summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorstas <stas@FreeBSD.org>2009-06-28 21:49:43 +0000
committerstas <stas@FreeBSD.org>2009-06-28 21:49:43 +0000
commitc61e1d6988484a6875f72fcc81e34d5a1c2dccfa (patch)
tree022e59bcdde11f99bd112a6b3f3fb767e6be937c /sys/kern/kern_event.c
parent66973f6d466a972e501c27cd4da24634b5f87f3e (diff)
downloadFreeBSD-src-c61e1d6988484a6875f72fcc81e34d5a1c2dccfa.zip
FreeBSD-src-c61e1d6988484a6875f72fcc81e34d5a1c2dccfa.tar.gz
- 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. Approved by: re (rwatson) Reviewed by: kib MFC after: 2 weeks
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 1715741..6603d11 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1606,17 +1606,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);
/*
@@ -1631,17 +1632,28 @@ knote(struct knlist *list, long hint, int islocked)
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);
}
OpenPOWER on IntegriCloud