]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: fix dead lock
authorThomas Veerman <thomas@minix3.org>
Mon, 2 Apr 2012 15:20:05 +0000 (15:20 +0000)
committerThomas Veerman <thomas@minix3.org>
Fri, 13 Apr 2012 13:19:10 +0000 (13:19 +0000)
When running out of worker threads to handle device replies a dead
lock resolver thread is used. However, it was only used for FS
endpoints; it is now used for "system processes" (drivers and FS
endpoints). Also, drivers were marked as system process when they
were not "forced" to map (i.e., mapping was done before endpoint was
alive).

servers/vfs/dmap.c
servers/vfs/main.c
servers/vfs/proto.h

index 54235e29dcb449e6c18c3fe6c6cc420a7af6f707..ed83553e20f19b244df7e33d31621871784eff8a 100644 (file)
@@ -87,9 +87,10 @@ int flags;                   /* device flags */
  * NONE, we're supposed to unmap it.
  */
 
-  int slot;
+  int slot, s;
   size_t len;
   struct dmap *dp;
+  struct fproc *rfp;
 
   /* Get pointer to device entry in the dmap table. */
   if (major < 0 || major >= NR_DEVICES) return(ENODEV);
@@ -105,12 +106,12 @@ int flags;                        /* device flags */
   }
 
   /* Check process number of new driver if it was alive before mapping */
-  if (! (flags & DRV_FORCED)) {
-       struct fproc *rfp;
-
-       if (isokendpt(proc_nr_e, &slot) != OK)
+  s = isokendpt(proc_nr_e, &slot);
+  if (s != OK) {
+       /* This is not a problem only when we force this driver mapping */
+       if (! (flags & DRV_FORCED))
                return(EINVAL);
-
+  } else {
        rfp = &fproc[slot];
        rfp->fp_flags |= FP_SYS_PROC;   /* Process is a driver */
   }
index 97883d3f1c9132f97f627d5c21dfba1d861d97d3..86369189035624ec90de2e8caa901c26be6da1f4 100644 (file)
@@ -147,31 +147,36 @@ static void handle_work(void *(*func)(void *arg))
 
   proc_e = m_in.m_source;
 
-  if ((vmp = find_vmnt(proc_e)) != NULL) {
-       /* A call back or dev result from an FS endpoint */
-
-       /* 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
-        * by ROOT_FS_E.
-        */
-       if (vmp->m_flags & VMNT_MOUNTING)
-               vmp->m_flags |= VMNT_FORCEROOTBSF;
-
+  if (fp->fp_flags & FP_SYS_PROC) {
        if (worker_available() == 0) {
-               /* No worker threads available to handle call */
-               if (deadlock_resolving) {
-                       /* Already trying to resolve a deadlock, can't
-                        * handle more, sorry */
-                       vmp->m_flags &= ~VMNT_CALLBACK;
-                       reply(proc_e, EAGAIN);
+               if (!deadlock_resolving) {
+                       if ((vmp = find_vmnt(proc_e)) != NULL) {
+                               /* A call back or dev result from an FS
+                                * endpoint. Set call back flag. Can do only
+                                * one call back at a time.
+                                */
+                               if (vmp->m_flags & VMNT_CALLBACK) {
+                                       reply(proc_e, EAGAIN);
+                                       return;
+                               }
+                               vmp->m_flags |= VMNT_CALLBACK;
+
+                               /* When an FS endpoint has to make a call back
+                                * in order to mount, force its device to a
+                                * "none device" so block reads/writes will be
+                                * handled by ROOT_FS_E.
+                                */
+                               if (vmp->m_flags & VMNT_MOUNTING)
+                                       vmp->m_flags |= VMNT_FORCEROOTBSF;
+                       }
+                       deadlock_resolving = 1;
+                       dl_worker_start(func);
                        return;
                }
-               deadlock_resolving = 1;
-               dl_worker_start(func);
+               /* Already trying to resolve a deadlock, can't
+                * handle more, sorry */
+
+               reply(proc_e, EAGAIN);
                return;
        }
   }
index 3689c6c29fd2adb7cb4659ba7cc6a0080968d8fb..6cde7927c368b35fe33fea29466f0c74e2d450b9 100644 (file)
@@ -62,7 +62,6 @@ struct dmap *get_dmap(endpoint_t proc_e);
 int do_mapdriver(void);
 int map_service(struct rprocpub *rpub);
 void dmap_unmap_by_endpt(int proc_nr);
-struct dmap *get_dmap(endpoint_t proc_e);
 int map_driver(const char *label, int major, endpoint_t proc_nr, int
        dev_style, int flags);
 int map_service(struct rprocpub *rpub);