Source-Changes-HG archive

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

[src/trunk]: src/external/cddl/osnet/sys/kern There is no 1:1 relation betwee...



details:   https://anonhg.NetBSD.org/src/rev/d95ab967a904
branches:  trunk
changeset: 451894:d95ab967a904
user:      hannken <hannken%NetBSD.org@localhost>
date:      Tue Jun 11 09:05:33 2019 +0000

description:
There is no 1:1 relation between cv_signal() and cv_timedwait() as
the latter implicitly calls cv_signal() on error.

This leads to "tq_waiting > 0" with "tq_running == 0" and the
taskq stalls.

Change task_executor() to increment and decrement "tq_waiting"
and always check and run the queue after cv_timedwait().

Use mstohz(), fix timeout and sort includes.

Addresses PR port-xen/54273: "zpool create pool xbd2" panics DOMU kernel

diffstat:

 external/cddl/osnet/sys/kern/taskq.c |  26 ++++++++++++++++----------
 1 files changed, 16 insertions(+), 10 deletions(-)

diffs (73 lines):

diff -r e88a4adcc782 -r d95ab967a904 external/cddl/osnet/sys/kern/taskq.c
--- a/external/cddl/osnet/sys/kern/taskq.c      Tue Jun 11 09:04:37 2019 +0000
+++ b/external/cddl/osnet/sys/kern/taskq.c      Tue Jun 11 09:05:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: taskq.c,v 1.9 2019/05/07 08:49:59 hannken Exp $        */
+/*     $NetBSD: taskq.c,v 1.10 2019/06/11 09:05:33 hannken Exp $       */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -30,9 +30,11 @@
  */
 
 #include <sys/types.h>
-#include <sys/mutex.h>
+#include <sys/param.h>
 #include <sys/kcondvar.h>
+#include <sys/kernel.h>
 #include <sys/kmem.h>
+#include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/threadpool.h>
 
@@ -65,7 +67,7 @@
 
 /*
  * Threadpool job to service tasks from task queue.
- * Runs until the task queue gets destroyed or the queue is empty for 5 secs.
+ * Runs until the task queue gets destroyed or the queue is empty for 10 secs.
  */
 static void
 task_executor(struct threadpool_job *job)
@@ -73,22 +75,27 @@
        struct taskq_executor *state = (struct taskq_executor *)job;
        taskq_t *tq = state->te_self;
        taskq_ent_t *tqe; 
+       int error;
 
        lwp_setspecific(taskq_lwp_key, tq);
 
        mutex_enter(&tq->tq_lock);
        while (!tq->tq_destroyed) {
-               tqe = SIMPLEQ_FIRST(&tq->tq_list);
-               if (tqe == NULL) {
+               if (SIMPLEQ_EMPTY(&tq->tq_list)) {
                        if (ISSET(tq->tq_flags, TASKQ_DYNAMIC))
                                break;
                        tq->tq_waiting++;
-                       if (cv_timedwait(&tq->tq_cv, &tq->tq_lock, 5000) != 0) {
-                               tq->tq_waiting--;
-                               break;
+                       error = cv_timedwait(&tq->tq_cv, &tq->tq_lock,
+                           mstohz(10000));
+                       tq->tq_waiting--;
+                       if (SIMPLEQ_EMPTY(&tq->tq_list)) {
+                               if (error)
+                                       break;
+                               continue;
                        }
-                       continue;
                }
+               tqe = SIMPLEQ_FIRST(&tq->tq_list);
+               KASSERT(tqe != NULL);
                SIMPLEQ_REMOVE_HEAD(&tq->tq_list, tqent_list);
                tqe->tqent_queued = 0;
                mutex_exit(&tq->tq_lock);
@@ -144,7 +151,6 @@
        tq->tq_active++;
        if (tq->tq_waiting) {
                cv_signal(&tq->tq_cv);
-               tq->tq_waiting--;
                mutex_exit(&tq->tq_lock);
                return;
        }



Home | Main Index | Thread Index | Old Index