Author: kmacy
Date: Fri Jul 10 19:43:07 2009
New Revision: 195586
URL: http://svn.freebsd.org/changeset/base/195586

Log:
  propagate MFC of 195148 to -STABLE:
   - Turn the third (islocked) argument of the knote call into flags parameter.
     Introduce the new flag KNF_NOKQLOCK to allow event callers to be called
     without KQ_LOCK mtx held.
   - Modify VFS knote calls to always use KNF_NOKQLOCK flag.  This is required
     for ZFS as its getattr implementation may sleep.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/kern/kern_event.c
  stable/7/sys/netgraph/ng_ksocket.c
  stable/7/sys/sys/event.h
  stable/7/sys/sys/mount.h
  stable/7/sys/sys/vnode.h

Modified: stable/7/sys/kern/kern_event.c
==============================================================================
--- stable/7/sys/kern/kern_event.c      Fri Jul 10 19:31:05 2009        
(r195585)
+++ stable/7/sys/kern/kern_event.c      Fri Jul 10 19:43:07 2009        
(r195586)
@@ -1608,17 +1608,18 @@ kqueue_wakeup(struct kqueue *kq)
  * first.
  */
 void
-knote(struct knlist *list, long hint, int islocked)
+knote(struct knlist *list, long hint, int lockflags)
 {
        struct kqueue *kq;
        struct knote *kn;
+       int error;
 
        if (list == NULL)
                return;
 
-       KNL_ASSERT_LOCK(list, islocked);
+       KNL_ASSERT_LOCK(list, lockflags & KNF_LISTLOCKED);
 
-       if (!islocked) 
+       if ((lockflags & KNF_LISTLOCKED) == 0)
                list->kl_lock(list->kl_lockarg); 
 
        /*
@@ -1633,17 +1634,28 @@ knote(struct knlist *list, long hint, in
                kq = kn->kn_kq;
                if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) {
                        KQ_LOCK(kq);
-                       if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) {
+                       if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
+                               KQ_UNLOCK(kq);
+                       } else if ((lockflags & KNF_NOKQLOCK) != 0) {
+                               kn->kn_status |= KN_INFLUX;
+                               KQ_UNLOCK(kq);
+                               error = kn->kn_fop->f_event(kn, hint);
+                               KQ_LOCK(kq);
+                               kn->kn_status &= ~KN_INFLUX;
+                               if (error)
+                                       KNOTE_ACTIVATE(kn, 1);
+                               KQ_UNLOCK_FLUX(kq);
+                       } else {
                                kn->kn_status |= KN_HASKQLOCK;
                                if (kn->kn_fop->f_event(kn, hint))
                                        KNOTE_ACTIVATE(kn, 1);
                                kn->kn_status &= ~KN_HASKQLOCK;
+                               KQ_UNLOCK(kq);
                        }
-                       KQ_UNLOCK(kq);
                }
                kq = NULL;
        }
-       if (!islocked)
+       if ((lockflags & KNF_LISTLOCKED) == 0)
                list->kl_unlock(list->kl_lockarg); 
 }
 

Modified: stable/7/sys/netgraph/ng_ksocket.c
==============================================================================
--- stable/7/sys/netgraph/ng_ksocket.c  Fri Jul 10 19:31:05 2009        
(r195585)
+++ stable/7/sys/netgraph/ng_ksocket.c  Fri Jul 10 19:43:07 2009        
(r195586)
@@ -1214,7 +1214,7 @@ ng_ksocket_finish_accept(priv_p priv)
        SOCK_UNLOCK(so);
        ACCEPT_UNLOCK();
 
-       /* XXX KNOTE(&head->so_rcv.sb_sel.si_note, 0); */
+       /* XXX KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0); */
 
        soaccept(so, &sa);
 

Modified: stable/7/sys/sys/event.h
==============================================================================
--- stable/7/sys/sys/event.h    Fri Jul 10 19:31:05 2009        (r195585)
+++ stable/7/sys/sys/event.h    Fri Jul 10 19:43:07 2009        (r195586)
@@ -135,8 +135,14 @@ struct knlist {
 MALLOC_DECLARE(M_KQUEUE);
 #endif
 
-#define KNOTE(list, hist, lock)                knote(list, hist, lock)
-#define KNOTE_LOCKED(list, hint)       knote(list, hint, 1)
+/*
+ * Flags for knote call
+ */
+#define        KNF_LISTLOCKED  0x0001                  /* knlist is locked */
+#define        KNF_NOKQLOCK    0x0002                  /* do not keep KQ_LOCK 
*/
+
+#define KNOTE(list, hist, flags)       knote(list, hist, flags)
+#define KNOTE_LOCKED(list, hint)       knote(list, hint, KNF_LISTLOCKED)
 #define KNOTE_UNLOCKED(list, hint)     knote(list, hint, 0)
 
 #define        KNLIST_EMPTY(list)              SLIST_EMPTY(&(list)->kl_list)
@@ -204,7 +210,7 @@ struct thread;
 struct proc;
 struct knlist;
 
-extern void    knote(struct knlist *list, long hint, int islocked);
+extern void    knote(struct knlist *list, long hint, int lockflags);
 extern void    knote_fork(struct knlist *list, int pid);
 extern void    knlist_add(struct knlist *knl, struct knote *kn, int islocked);
 extern void    knlist_remove(struct knlist *knl, struct knote *kn, int 
islocked);

Modified: stable/7/sys/sys/mount.h
==============================================================================
--- stable/7/sys/sys/mount.h    Fri Jul 10 19:31:05 2009        (r195585)
+++ stable/7/sys/sys/mount.h    Fri Jul 10 19:43:07 2009        (r195586)
@@ -633,7 +633,7 @@ extern int mpsafe_vfs;
 #define VFS_KNOTE_LOCKED(vp, hint) do                                  \
 {                                                                      \
        if (((vp)->v_vflag & VV_NOKNOTE) == 0)                          \
-               VN_KNOTE((vp), (hint), 1);                              \
+               VN_KNOTE((vp), (hint), KNF_LISTLOCKED);                 \
 } while (0)
 
 #define VFS_KNOTE_UNLOCKED(vp, hint) do                                        
\

Modified: stable/7/sys/sys/vnode.h
==============================================================================
--- stable/7/sys/sys/vnode.h    Fri Jul 10 19:31:05 2009        (r195585)
+++ stable/7/sys/sys/vnode.h    Fri Jul 10 19:43:07 2009        (r195586)
@@ -222,9 +222,10 @@ struct xvnode {
 #define VN_KNOTE(vp, b, a)                                     \
        do {                                                    \
                if (!VN_KNLIST_EMPTY(vp))                       \
-                       KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b), (a)); \
+                       KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b), \
+                           (a) | KNF_NOKQLOCK);                \
        } while (0)
-#define        VN_KNOTE_LOCKED(vp, b)          VN_KNOTE(vp, b, 1)
+#define        VN_KNOTE_LOCKED(vp, b)          VN_KNOTE(vp, b, KNF_LISTLOCKED)
 #define        VN_KNOTE_UNLOCKED(vp, b)        VN_KNOTE(vp, b, 0)
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to