VFS: add debug dump for select

By now it has become clear that the VFS select code has an unusually
high concentration of bugs, and there is no indication that any form
of convergence to a bug-free state is in sight.  Thus, for now, it
may be helpful to be able to dump the contents of the select tables
in order to track down any bugs in the future.  Hopefully that will
allow the next bugs to be resolved slightly after than before.

The debug dump can be triggered with "svrctl vfs get print_select".

Change-Id: Ia826746dce0f065d7f3b46aa9047945067b8263d
This commit is contained in:
David van Moolenbroek 2016-08-04 16:12:54 +00:00
parent 2ff64318e2
commit 63faa8fe9a
3 changed files with 57 additions and 0 deletions

View File

@ -862,6 +862,11 @@ int do_svrctl(void)
sysgetenv.val = 0;
sysgetenv.vallen = 0;
r = OK;
} else if (!strcmp(search_key, "print_select")) {
select_dump();
sysgetenv.val = 0;
sysgetenv.vallen = 0;
r = OK;
} else if (!strcmp(search_key, "active_threads")) {
int active = NR_WTHREADS - worker_available();
snprintf(small_buf, sizeof(small_buf) - 1,

View File

@ -352,6 +352,7 @@ void select_forget(void);
void select_reply1(endpoint_t driver_e, devminor_t minor, int status);
void select_reply2(endpoint_t driver_e, devminor_t minor, int status);
void select_unsuspend_by_endpt(endpoint_t proc);
void select_dump(void);
/* worker.c */
void worker_init(void);

View File

@ -1113,3 +1113,54 @@ static void select_lock_filp(struct filp *f, int ops)
lock_filp(f, locktype);
}
/*
* Dump the state of the entire select table, for debugging purposes.
*/
void
select_dump(void)
{
struct selectentry *se;
struct filp *f;
struct dmap *dp;
dev_t dev;
int s, fd;
for (s = 0; s < MAXSELECTS; s++) {
se = &selecttab[s];
if (se->requestor == NULL)
continue;
printf("select %d: endpt %d nfds %d nreadyfds %d error %d "
"block %d starting %d expiry %u is_deferred %d\n",
s, se->req_endpt, se->nfds, se->nreadyfds, se->error,
se->block, se->starting, se->expiry, is_deferred(se));
for (fd = 0; !se->starting && fd < se->nfds; fd++) {
/* Save on output: do not print NULL filps at all. */
if ((f = se->filps[fd]) == NULL)
continue;
printf("- [%d] filp %p flags %x type ", fd, f,
f->filp_select_flags);
if (is_regular_file(f))
printf("regular\n");
else if (is_pipe(f))
printf("pipe\n");
else if (is_char_device(f)) {
dev = cdev_map(f->filp_vno->v_sdev,
se->requestor);
printf("char (dev <%d,%d>, dmap ",
major(dev), minor(dev));
if (dev != NO_DEV) {
dp = &dmap[major(dev)];
printf("busy %d filp %p)\n",
dp->dmap_sel_busy,
dp->dmap_sel_filp);
} else
printf("unknown)\n");
} else
printf("unknown\n");
}
}
}