Print this page
OS-6363 system went to dark side of moon for ~467 seconds OS-6404 ARC reclaim should throttle its calls to arc_kmem_reap_now() Reviewed by: Bryan Cantrill <bryan@joyent.com> Reviewed by: Dan McDonald <danmcd@joyent.com>


   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  28  * Copyright (c) 2014 by Delphix. All rights reserved.

  29  */
  30 
  31 #include <sys/zfs_context.h>
  32 
  33 int taskq_now;
  34 taskq_t *system_taskq;
  35 
  36 #define TASKQ_ACTIVE    0x00010000
  37 #define TASKQ_NAMELEN   31
  38 
  39 struct taskq {
  40         char            tq_name[TASKQ_NAMELEN + 1];
  41         kmutex_t        tq_lock;
  42         krwlock_t       tq_threadlock;
  43         kcondvar_t      tq_dispatch_cv;
  44         kcondvar_t      tq_wait_cv;
  45         thread_t        *tq_threadlist;
  46         int             tq_flags;
  47         int             tq_active;
  48         int             tq_nthreads;


 161         /*
 162          * Enqueue the task to the underlying queue.
 163          */
 164         mutex_enter(&tq->tq_lock);
 165 
 166         if (flags & TQ_FRONT) {
 167                 t->tqent_next = tq->tq_task.tqent_next;
 168                 t->tqent_prev = &tq->tq_task;
 169         } else {
 170                 t->tqent_next = &tq->tq_task;
 171                 t->tqent_prev = tq->tq_task.tqent_prev;
 172         }
 173         t->tqent_next->tqent_prev = t;
 174         t->tqent_prev->tqent_next = t;
 175         t->tqent_func = func;
 176         t->tqent_arg = arg;
 177         cv_signal(&tq->tq_dispatch_cv);
 178         mutex_exit(&tq->tq_lock);
 179 }
 180 












 181 void
 182 taskq_wait(taskq_t *tq)
 183 {
 184         mutex_enter(&tq->tq_lock);
 185         while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
 186                 cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
 187         mutex_exit(&tq->tq_lock);
 188 }
 189 
 190 static void *
 191 taskq_thread(void *arg)
 192 {
 193         taskq_t *tq = arg;
 194         taskq_ent_t *t;
 195         boolean_t prealloc;
 196 
 197         mutex_enter(&tq->tq_lock);
 198         while (tq->tq_flags & TASKQ_ACTIVE) {
 199                 if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
 200                         if (--tq->tq_active == 0)




   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  28  * Copyright (c) 2014 by Delphix. All rights reserved.
  29  * Copyright (c) 2017, Joyent, Inc.
  30  */
  31 
  32 #include <sys/zfs_context.h>
  33 
  34 int taskq_now;
  35 taskq_t *system_taskq;
  36 
  37 #define TASKQ_ACTIVE    0x00010000
  38 #define TASKQ_NAMELEN   31
  39 
  40 struct taskq {
  41         char            tq_name[TASKQ_NAMELEN + 1];
  42         kmutex_t        tq_lock;
  43         krwlock_t       tq_threadlock;
  44         kcondvar_t      tq_dispatch_cv;
  45         kcondvar_t      tq_wait_cv;
  46         thread_t        *tq_threadlist;
  47         int             tq_flags;
  48         int             tq_active;
  49         int             tq_nthreads;


 162         /*
 163          * Enqueue the task to the underlying queue.
 164          */
 165         mutex_enter(&tq->tq_lock);
 166 
 167         if (flags & TQ_FRONT) {
 168                 t->tqent_next = tq->tq_task.tqent_next;
 169                 t->tqent_prev = &tq->tq_task;
 170         } else {
 171                 t->tqent_next = &tq->tq_task;
 172                 t->tqent_prev = tq->tq_task.tqent_prev;
 173         }
 174         t->tqent_next->tqent_prev = t;
 175         t->tqent_prev->tqent_next = t;
 176         t->tqent_func = func;
 177         t->tqent_arg = arg;
 178         cv_signal(&tq->tq_dispatch_cv);
 179         mutex_exit(&tq->tq_lock);
 180 }
 181 
 182 boolean_t
 183 taskq_empty(taskq_t *tq)
 184 {
 185         boolean_t rv;
 186 
 187         mutex_enter(&tq->tq_lock);
 188         rv = (tq->tq_task.tqent_next == &tq->tq_task) && (tq->tq_active == 0);
 189         mutex_exit(&tq->tq_lock);
 190 
 191         return (rv);
 192 }
 193 
 194 void
 195 taskq_wait(taskq_t *tq)
 196 {
 197         mutex_enter(&tq->tq_lock);
 198         while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
 199                 cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
 200         mutex_exit(&tq->tq_lock);
 201 }
 202 
 203 static void *
 204 taskq_thread(void *arg)
 205 {
 206         taskq_t *tq = arg;
 207         taskq_ent_t *t;
 208         boolean_t prealloc;
 209 
 210         mutex_enter(&tq->tq_lock);
 211         while (tq->tq_flags & TASKQ_ACTIVE) {
 212                 if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
 213                         if (--tq->tq_active == 0)