Skip to content

Commit

Permalink
added iftest out experimental code for flock() recovery
Browse files Browse the repository at this point in the history
occurs when display has gone away

controlled by EXPERIMENTAL_FLOCK_RECOVERY
  • Loading branch information
rockowitz committed Jan 4, 2025
1 parent f71ea47 commit 23ac168
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
78 changes: 77 additions & 1 deletion src/base/flock.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

#include "public/ddcutil_types.h"

#include "util/data_structures.h"
#include "util/debug_util.h"
#include "util/edid.h"
#include "util/file_util.h"
#include "util/linux_util.h"
#include "util/report_util.h"
Expand All @@ -24,6 +26,12 @@
#include "base/rtti.h"
#include "base/status_code_mgt.h"

#ifdef EXPERIMENTAL_FLOCK_RECOVERY
#include "i2c/i2c_edid.h" // violates layering
#include "i2c/i2c_execute.h"
#endif

#include "base/flock.h"

static DDCA_Trace_Group TRACE_GROUP = DDCA_TRC_BASE;

Expand Down Expand Up @@ -107,11 +115,62 @@ void explore_flock(int fd, const char * filename) {
}
}

#ifdef EXPERIMENTAL_FLOCK_RECOVERY
static bool simple_ioctl_read_edid_by_fd(
int fd,
int read_size,
bool write_before_read,
int depth)
{
bool debug = true;
DBGMSF(debug, "Starting. fd=%d, filename=%s, read_size=%d, write_before_read=%s",
fd, filename_for_fd_t(fd), read_size, sbool(write_before_read));
assert(read_size == 128 || read_size == 256);
rpt_nl();
rpt_vstring(depth, "Attempting simple %d byte EDID read, fd=%d, %s initial write",
read_size, fd,
(write_before_read) ? "WITH" : "WITHOUT"
);

Byte * edid_buf = calloc(1, 256);

int rc = 0;
bool ok = false;

if (write_before_read) {
edid_buf[0] = 0x00;
rc = i2c_ioctl_writer(fd, 0x50, 1, edid_buf);
if (rc < 0) {
rpt_vstring(depth, "write of 1 byte failed, errno = %s", linux_errno_desc(errno));
rpt_label(depth, "Continuing");
}
}

DBGMSF(debug, "Calling i2c_ioctl_reader(), read_bytewise=false, read_size=%d, edid_buf=%p",
read_size, edid_buf);
rc = i2c_ioctl_reader(fd, 0x50, false, read_size, edid_buf);
if (rc < 0) {
rpt_vstring(depth,"read failed. errno = %s", linux_errno_desc(errno));
}
else {
rpt_hex_dump(edid_buf, read_size, depth+1);
ok = true;
}

free(edid_buf);
DBGMSF(debug, "Returning: %s", sbool(ok));
return ok;
}
#endif


Status_Errno flock_lock_by_fd(int fd, const char * filename, bool wait) {
assert(filename);
bool debug = false;
debug = debug || debug_flock;
debug = debug || debug_flock;
#ifdef EXPERIMENTAL_FLOCK_RECOVERY
debug = debug || streq(filename,"/devi2c-25");
#endif
DBGTRC_STARTING(debug, DDCA_TRC_BASE, "fd=%d, filename=%s, wait=%s", fd, filename, SBOOL(wait));

// int inode = get_inode_by_fn(filename);
Expand Down Expand Up @@ -144,6 +203,7 @@ Status_Errno flock_lock_by_fd(int fd, const char * filename, bool wait) {
} // flockrc == 0

// handle failure
// n.b. lock will fail w EAGAIN if at least NEC display turned off
assert(flockrc == -1);
int errsv = errno;
DBGTRC_NOPREFIX(true, DDCA_TRC_NONE, "filename=%s, flock_call_ctr=%d, flock() returned: %s",
Expand All @@ -162,6 +222,22 @@ Status_Errno flock_lock_by_fd(int fd, const char * filename, bool wait) {
break;
}

#ifdef EXPERIMENTAL_FLOCK_RECOVERY
if (errsv == EWOULDBLOCK) {
Buffer * edidbuf = buffer_new(256, "");
Status_Errno_DDC rc = i2c_get_raw_edid_by_fd(fd, edidbuf);
bool found_edid = (rc == 0);
buffer_free(edidbuf, "");
DBGTRC_NOPREFIX(true, DDCA_TRC_NONE, "able to read edid directly: %s", sbool(found_edid));
// TODO: read attributes
// RPT_ATTR_TEXT(1, NULL, "/sys/class/drm", dh->dref->

simple_ioctl_read_edid_by_fd(fd,
256, // read size
true, //write before read
2); // depth
}
#endif
DBGTRC_NOPREFIX(debug || debug_flock, DDCA_TRC_NONE,
"Resource locked. filename=%s, flock_call_ctr=%d, Sleeping", filename, flock_call_ctr);

Expand Down
13 changes: 12 additions & 1 deletion src/i2c/i2c_bus_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

#include "util/coredefs_base.h"
#include "util/debug_util.h"
#include "util/data_structures.h"
#include "util/drm_common.h"
#include <base/drm_connector_state.h>
#include "util/edid.h"
#include "util/error_info.h"
#include "util/failsim.h"
Expand All @@ -52,6 +52,7 @@
#include "base/core.h"
#include "base/ddc_errno.h"
#include "base/display_lock.h"
#include "base/drm_connector_state.h"
#include "base/flock.h"
#include "base/i2c_bus_base.h"
#include "base/linux_errno.h"
Expand Down Expand Up @@ -305,6 +306,16 @@ Error_Info * i2c_open_bus(
if (flockrc != 0) {
DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Cross instance locking failed for %s", filename);
cur_error = ERRINFO_NEW(flockrc, "flock_lock_by_fd(%s) returned %s", filename, psc_desc(flockrc));
#ifdef EXPERIMENTAL_FLOCK_RECOVREY
Buffer * edidbuf = buffer_new(256, "");
Status_Errno_DDC rc = i2c_get_raw_edid_by_fd(*fd_loc, edidbuf);
bool found_edid = (rc == 0);
buffer_free(edidbuf, "");
DBGTRC_NOPREFIX(true, DDCA_TRC_NONE, "able to read edid directly for /dev/i2c-%d: %s",
busno, sbool(found_edid));
// TODO: read attributes
// RPT_ATTR_TEXT(1, NULL, "/sys/class/drm", dh->dref->
#endif
}
else {
DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Cross instance locking succeeded for %s", filename);
Expand Down

0 comments on commit 23ac168

Please sign in to comment.