Reenable backcall detection

This commit is contained in:
Thomas Veerman 2011-10-27 15:26:08 +00:00
parent 823e42c3e3
commit febb4403ff
6 changed files with 47 additions and 15 deletions

View file

@ -62,7 +62,7 @@ PUBLIC void fs_sendmore(struct vmnt *vmp)
return; return;
if (vmp->m_comm.c_cur_reqs >= vmp->m_comm.c_max_reqs)/*No room to send more*/ if (vmp->m_comm.c_cur_reqs >= vmp->m_comm.c_max_reqs)/*No room to send more*/
return; return;
if (vmp->m_flags & VMNT_BACKCALL) /* Hold off for now */ if (vmp->m_flags & VMNT_CALLBACK) /* Hold off for now */
return; return;
vmp->m_comm.c_req_queue = worker->w_next; /* Remove head */ vmp->m_comm.c_req_queue = worker->w_next; /* Remove head */
@ -88,7 +88,7 @@ PUBLIC int fs_sendrec(endpoint_t fs_e, message *reqmp)
fp->fp_sendrec = reqmp; /* Where to store request and reply */ fp->fp_sendrec = reqmp; /* Where to store request and reply */
/* Find out whether we can send right away or have to enqueue */ /* Find out whether we can send right away or have to enqueue */
if ( !(vmp->m_flags & VMNT_BACKCALL) && if ( !(vmp->m_flags & VMNT_CALLBACK) &&
vmp->m_comm.c_cur_reqs < vmp->m_comm.c_max_reqs) { vmp->m_comm.c_cur_reqs < vmp->m_comm.c_max_reqs) {
/* There's still room to send more and no proc is queued */ /* There's still room to send more and no proc is queued */
r = sendmsg(vmp, fp); r = sendmsg(vmp, fp);

View file

@ -96,7 +96,7 @@ int flags; /* device flags */
dp = &dmap[major]; dp = &dmap[major];
/* Check if we're supposed to unmap it. */ /* Check if we're supposed to unmap it. */
if(proc_nr_e == NONE) { if (proc_nr_e == NONE) {
dp->dmap_opcl = no_dev; dp->dmap_opcl = no_dev;
dp->dmap_io = no_dev_io; dp->dmap_io = no_dev_io;
dp->dmap_driver = NONE; dp->dmap_driver = NONE;
@ -106,8 +106,13 @@ int flags; /* device flags */
/* Check process number of new driver if it was alive before mapping */ /* Check process number of new driver if it was alive before mapping */
if (! (flags & DRV_FORCED)) { if (! (flags & DRV_FORCED)) {
struct fproc *rfp;
if (isokendpt(proc_nr_e, &slot) != OK) if (isokendpt(proc_nr_e, &slot) != OK)
return(EINVAL); return(EINVAL);
rfp = &fproc[slot];
rfp->fp_flags |= FP_SYS_PROC; /* Process is a driver */
} }
if (label != NULL) { if (label != NULL) {

View file

@ -58,11 +58,12 @@ EXTERN struct fproc {
#define FP_SUSP_REOPEN 01 /* Process is suspended until the reopens are #define FP_SUSP_REOPEN 01 /* Process is suspended until the reopens are
* completed (after the restart of a driver). * completed (after the restart of a driver).
*/ */
#define FP_REVIVED 02 /* Indicates process is being revived */ #define FP_REVIVED 0002 /* Indicates process is being revived */
#define FP_SESLDR 04 /* Set if process is session leader */ #define FP_SESLDR 0004 /* Set if process is session leader */
#define FP_PENDING 010 /* Set if process has pending work */ #define FP_PENDING 0010 /* Set if process has pending work */
#define FP_EXITING 020 /* Set if process is exiting */ #define FP_EXITING 0020 /* Set if process is exiting */
#define FP_PM_PENDING 040 /* Set if process has pending PM request */ #define FP_PM_PENDING 0040 /* Set if process has pending PM request */
#define FP_SYS_PROC 0100 /* Set if process is a driver or FS */
/* Field values. */ /* Field values. */
#define NOT_REVIVING 0xC0FFEEE /* process is not being revived */ #define NOT_REVIVING 0xC0FFEEE /* process is not being revived */

View file

@ -77,7 +77,7 @@ PUBLIC int main(void)
/* SEF local startup. */ /* SEF local startup. */
sef_local_startup(); sef_local_startup();
printf("Started AVFS\n"); printf("Started AVFS: %d worker thread(s)\n", NR_WTHREADS);
verbose = 0; verbose = 0;
/* This is the main loop that gets work, processes it, and sends replies. */ /* This is the main loop that gets work, processes it, and sends replies. */
@ -140,12 +140,16 @@ PRIVATE void handle_work(void *(*func)(void *arg))
{ {
/* Handle asynchronous device replies and new system calls. If the originating /* Handle asynchronous device replies and new system calls. If the originating
* endpoint is an FS endpoint, take extra care not to get in deadlock. */ * endpoint is an FS endpoint, take extra care not to get in deadlock. */
struct vmnt *vmp; struct vmnt *vmp = NULL;
if ((vmp = find_vmnt(who_e)) != NULL) { if ((vmp = find_vmnt(who_e)) != NULL) {
/* A back call or dev result from an FS endpoint */ /* A call back or dev result from an FS endpoint */
/* When an FS point has to make a callback in order to mount, force /* Set call back flag. We assume that an FS does only one call back
* at a time */
vmp->m_flags |= VMNT_CALLBACK;
/* When an FS point has to make a call back in order to mount, force
* its device to a "none device" so block reads/writes will be handled * its device to a "none device" so block reads/writes will be handled
* by ROOT_FS_E. * by ROOT_FS_E.
*/ */
@ -157,6 +161,7 @@ PRIVATE void handle_work(void *(*func)(void *arg))
if (deadlock_resolving) { if (deadlock_resolving) {
/* Already trying to resolve a deadlock, can't /* Already trying to resolve a deadlock, can't
* handle more, sorry */ * handle more, sorry */
vmp->m_flags &= ~VMNT_CALLBACK;
reply(who_e, EAGAIN); reply(who_e, EAGAIN);
return; return;
} }
@ -208,6 +213,13 @@ PRIVATE void *do_async_dev_result(void *arg)
deadlock_resolving = 0; deadlock_resolving = 0;
} }
if (fp != NULL && (fp->fp_flags & FP_SYS_PROC)) {
struct vmnt *vmp;
if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL)
vmp->m_flags &= ~VMNT_CALLBACK;
}
thread_cleanup(NULL); thread_cleanup(NULL);
return(NULL); return(NULL);
} }
@ -425,6 +437,14 @@ PRIVATE void *do_work(void *arg)
/* Copy the results back to the user and send reply. */ /* Copy the results back to the user and send reply. */
if (error != SUSPEND) { if (error != SUSPEND) {
if ((fp->fp_flags & FP_SYS_PROC)) {
struct vmnt *vmp;
if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL)
vmp->m_flags &= ~VMNT_CALLBACK;
}
if (deadlock_resolving) { if (deadlock_resolving) {
if (fp->fp_wtid == dl_worker.w_tid) if (fp->fp_wtid == dl_worker.w_tid)
deadlock_resolving = 0; deadlock_resolving = 0;

View file

@ -167,8 +167,8 @@ int rdonly,
char mount_label[LABEL_MAX] ) char mount_label[LABEL_MAX] )
{ {
int rdir, mdir; /* TRUE iff {root|mount} file is dir */ int rdir, mdir; /* TRUE iff {root|mount} file is dir */
int i, r = OK, found, isroot, mount_root, con_reqs; int i, r = OK, found, isroot, mount_root, con_reqs, slot;
struct fproc *tfp; struct fproc *tfp, *rfp;
struct dmap *dp; struct dmap *dp;
struct vnode *root_node, *vp = NULL; struct vnode *root_node, *vp = NULL;
struct vmnt *new_vmp, *parent_vmp; struct vmnt *new_vmp, *parent_vmp;
@ -249,6 +249,12 @@ char mount_label[LABEL_MAX] )
lock_vnode(root_node, VNODE_OPCL); lock_vnode(root_node, VNODE_OPCL);
/* Record process as a system process */
if (isokendpt(fs_e, &slot) != OK)
return(EINVAL);
rfp = &fproc[slot];
rfp->fp_flags |= FP_SYS_PROC; /* Process is an FS */
/* Store some essential vmnt data first */ /* Store some essential vmnt data first */
new_vmp->m_fs_e = fs_e; new_vmp->m_fs_e = fs_e;
new_vmp->m_dev = dev; new_vmp->m_dev = dev;

View file

@ -14,7 +14,7 @@ EXTERN struct vmnt {
/* vmnt flags */ /* vmnt flags */
#define VMNT_READONLY 01 /* Device mounted readonly */ #define VMNT_READONLY 01 /* Device mounted readonly */
#define VMNT_BACKCALL 02 /* FS did back call */ #define VMNT_CALLBACK 02 /* FS did back call */
#define VMNT_MOUNTING 04 /* Device is being mounted */ #define VMNT_MOUNTING 04 /* Device is being mounted */
#define VMNT_FORCEROOTBSF 010 /* Force usage of none-device */ #define VMNT_FORCEROOTBSF 010 /* Force usage of none-device */