Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern put back clearing of KN_QUEUED and check for re-que...



details:   https://anonhg.NetBSD.org/src/rev/03febf06b7fb
branches:  trunk
changeset: 950353:03febf06b7fb
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Mon Jan 25 19:57:05 2021 +0000

description:
put back clearing of KN_QUEUED and check for re-queue - as rev. 1.53 notes,
it's necessary for correct function

fixes PR kern/55946, thanks to Paul Goyette for testing

part of PR kern/50094 fix

diffstat:

 sys/kern/kern_event.c |  24 +++++++++++++++++-------
 1 files changed, 17 insertions(+), 7 deletions(-)

diffs (82 lines):

diff -r 9a92a7c81279 -r 03febf06b7fb sys/kern/kern_event.c
--- a/sys/kern/kern_event.c     Mon Jan 25 19:39:34 2021 +0000
+++ b/sys/kern/kern_event.c     Mon Jan 25 19:57:05 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_event.c,v 1.114 2021/01/24 11:31:47 jdolecek Exp $        */
+/*     $NetBSD: kern_event.c,v 1.115 2021/01/25 19:57:05 jdolecek Exp $        */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.114 2021/01/24 11:31:47 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.115 2021/01/25 19:57:05 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1487,11 +1487,12 @@
                KASSERT((kn->kn_status & KN_BUSY) == 0);
 
                kq_check(kq);
+               kn->kn_status &= ~KN_QUEUED;
                kn->kn_status |= KN_BUSY;
                kq_check(kq);
                if (kn->kn_status & KN_DISABLED) {
+                       kn->kn_status &= ~KN_BUSY;
                        kq->kq_count--;
-                       kn->kn_status &= ~(KN_QUEUED|KN_BUSY);
                        /* don't want disabled events */
                        continue;
                }
@@ -1504,12 +1505,20 @@
                        rv = (*kn->kn_fop->f_event)(kn, 0);
                        KERNEL_UNLOCK_ONE(NULL);        /* XXXSMP */
                        mutex_spin_enter(&kq->kq_lock);
+                       /* Re-poll if note was re-enqueued. */
+                       if ((kn->kn_status & KN_QUEUED) != 0) {
+                               kn->kn_status &= ~KN_BUSY;
+                               /* Re-enqueue raised kq_count, lower it again */
+                               kq->kq_count--;
+                               influx = 1;
+                               continue;
+                       }
                        if (rv == 0) {
                                /*
                                 * non-ONESHOT event that hasn't
                                 * triggered again, so de-queue.
                                 */
-                               kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE|KN_BUSY);
+                               kn->kn_status &= ~(KN_ACTIVE|KN_BUSY);
                                kq->kq_count--;
                                influx = 1;
                                continue;
@@ -1533,7 +1542,7 @@
                influx = 1;
                if (kn->kn_flags & EV_ONESHOT) {
                        /* delete ONESHOT events after retrieval */
-                       kn->kn_status &= ~(KN_QUEUED|KN_BUSY);
+                       kn->kn_status &= ~KN_BUSY;
                        kq->kq_count--;
                        mutex_spin_exit(&kq->kq_lock);
                        knote_detach(kn, fdp, true);
@@ -1551,15 +1560,16 @@
                                kn->kn_data = 0;
                                kn->kn_fflags = 0;
                        }
-                       kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE|KN_BUSY);
+                       kn->kn_status &= ~(KN_ACTIVE|KN_BUSY);
                        kq->kq_count--;
                } else if (kn->kn_flags & EV_DISPATCH) {
                        kn->kn_status |= KN_DISABLED;
-                       kn->kn_status &= ~(KN_QUEUED|KN_ACTIVE|KN_BUSY);
+                       kn->kn_status &= ~(KN_ACTIVE|KN_BUSY);
                        kq->kq_count--;
                } else {
                        /* add event back on list */
                        kq_check(kq);
+                       kn->kn_status |= KN_QUEUED;
                        kn->kn_status &= ~KN_BUSY;
                        TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
                        kq_check(kq);



Home | Main Index | Thread Index | Old Index