1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2000 Doug Rabson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/bus.h> 32 #include <sys/cpuset.h> 33 #include <sys/interrupt.h> 34 #include <sys/kernel.h> 35 #include <sys/kthread.h> 36 #include <sys/libkern.h> 37 #include <sys/limits.h> 38 #include <sys/lock.h> 39 #include <sys/malloc.h> 40 #include <sys/mutex.h> 41 #include <sys/proc.h> 42 #include <sys/epoch.h> 43 #include <sys/sched.h> 44 #include <sys/smp.h> 45 #include <sys/stdarg.h> 46 #include <sys/sysctl.h> 47 #include <sys/taskqueue.h> 48 #include <sys/unistd.h> 49 50 static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); 51 static void *taskqueue_giant_ih; 52 static void *taskqueue_ih; 53 static void taskqueue_fast_enqueue(void *); 54 static void taskqueue_swi_enqueue(void *); 55 static void taskqueue_swi_giant_enqueue(void *); 56 57 struct taskqueue_busy { 58 struct task *tb_running; 59 u_int tb_seq; 60 bool tb_canceling; 61 bool tb_wanted; 62 LIST_ENTRY(taskqueue_busy) tb_link; 63 }; 64 65 struct taskqueue { 66 STAILQ_HEAD(, task) tq_queue; 67 LIST_HEAD(, taskqueue_busy) tq_active; 68 struct task *tq_hint; 69 u_int tq_seq; 70 int tq_callouts; 71 struct mtx_padalign tq_mutex; 72 taskqueue_enqueue_fn tq_enqueue; 73 void *tq_context; 74 char *tq_name; 75 struct thread **tq_threads; 76 int tq_tcount; 77 int tq_spin; 78 int tq_flags; 79 taskqueue_callback_fn tq_callbacks[TASKQUEUE_NUM_CALLBACKS]; 80 void *tq_cb_contexts[TASKQUEUE_NUM_CALLBACKS]; 81 }; 82 83 static SYSCTL_NODE(_kern, OID_AUTO, taskqueue, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 84 "taskqueue information"); 85 86 /* 87 * Limit on the number of tasks that may be run in a single epoch section. 88 * It's profitable to batch tasks together, but there must be a bound in order 89 * to maintain system liveness. 90 */ 91 unsigned int net_epoch_task_limit = 8; 92 SYSCTL_UINT(_kern_taskqueue, OID_AUTO, net_epoch_task_limit, CTLFLAG_RWTUN, 93 &net_epoch_task_limit, 0, 94 "Maximum number of tasks to run in an epoch section"); 95 96 #define TQ_FLAGS_ACTIVE (1 << 0) 97 #define TQ_FLAGS_BLOCKED (1 << 1) 98 #define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2) 99 100 #define DT_CALLOUT_ARMED (1 << 0) 101 #define DT_DRAIN_IN_PROGRESS (1 << 1) 102 103 #define TQ_LOCK(tq) \ 104 do { \ 105 if ((tq)->tq_spin) \ 106 mtx_lock_spin(&(tq)->tq_mutex); \ 107 else \ 108 mtx_lock(&(tq)->tq_mutex); \ 109 } while (0) 110 #define TQ_ASSERT_LOCKED(tq) mtx_assert(&(tq)->tq_mutex, MA_OWNED) 111 112 #define TQ_UNLOCK(tq) \ 113 do { \ 114 if ((tq)->tq_spin) \ 115 mtx_unlock_spin(&(tq)->tq_mutex); \ 116 else \ 117 mtx_unlock(&(tq)->tq_mutex); \ 118 } while (0) 119 #define TQ_ASSERT_UNLOCKED(tq) mtx_assert(&(tq)->tq_mutex, MA_NOTOWNED) 120 121 void 122 _timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task, 123 int priority, task_fn_t func, void *context) 124 { 125 126 TASK_INIT(&timeout_task->t, priority, func, context); 127 callout_init_mtx(&timeout_task->c, &queue->tq_mutex, 128 CALLOUT_RETURNUNLOCKED); 129 timeout_task->q = queue; 130 timeout_task->f = 0; 131 } 132 133 static __inline int 134 TQ_SLEEP(struct taskqueue *tq, void *p, const char *wm) 135 { 136 if (tq->tq_spin) 137 return (msleep_spin(p, (struct mtx *)&tq->tq_mutex, wm, 0)); 138 return (msleep(p, &tq->tq_mutex, 0, wm, 0)); 139 } 140 141 static __inline int 142 TQ_SLEEP_BUSY(struct taskqueue *tq, struct taskqueue_busy *tb, const char *wm) 143 { 144 145 TQ_ASSERT_LOCKED(tq); 146 tb->tb_wanted = true; 147 return (TQ_SLEEP(tq, tb, wm)); 148 } 149 150 static struct taskqueue_busy * 151 task_get_busy(struct taskqueue *queue, struct task *task) 152 { 153 struct taskqueue_busy *tb; 154 155 TQ_ASSERT_LOCKED(queue); 156 LIST_FOREACH(tb, &queue->tq_active, tb_link) { 157 if (tb->tb_running == task) 158 return (tb); 159 } 160 return (NULL); 161 } 162 163 static struct taskqueue * 164 _taskqueue_create(const char *name, int mflags, 165 taskqueue_enqueue_fn enqueue, void *context, 166 int mtxflags, const char *mtxname __unused) 167 { 168 struct taskqueue *queue; 169 char *tq_name; 170 171 tq_name = malloc(TASKQUEUE_NAMELEN, M_TASKQUEUE, mflags | M_ZERO); 172 if (tq_name == NULL) 173 return (NULL); 174 175 queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags | M_ZERO); 176 if (queue == NULL) { 177 free(tq_name, M_TASKQUEUE); 178 return (NULL); 179 } 180 181 snprintf(tq_name, TASKQUEUE_NAMELEN, "%s", (name) ? name : "taskqueue"); 182 183 STAILQ_INIT(&queue->tq_queue); 184 LIST_INIT(&queue->tq_active); 185 queue->tq_enqueue = enqueue; 186 queue->tq_context = context; 187 queue->tq_name = tq_name; 188 queue->tq_spin = (mtxflags & MTX_SPIN) != 0; 189 queue->tq_flags |= TQ_FLAGS_ACTIVE; 190 if (enqueue == taskqueue_fast_enqueue || 191 enqueue == taskqueue_swi_enqueue || 192 enqueue == taskqueue_swi_giant_enqueue || 193 enqueue == taskqueue_thread_enqueue) 194 queue->tq_flags |= TQ_FLAGS_UNLOCKED_ENQUEUE; 195 mtx_init(&queue->tq_mutex, tq_name, NULL, mtxflags); 196 197 return (queue); 198 } 199 200 struct taskqueue * 201 taskqueue_create(const char *name, int mflags, 202 taskqueue_enqueue_fn enqueue, void *context) 203 { 204 205 return _taskqueue_create(name, mflags, enqueue, context, 206 MTX_DEF, name); 207 } 208 209 void 210 taskqueue_set_callback(struct taskqueue *queue, 211 enum taskqueue_callback_type cb_type, taskqueue_callback_fn callback, 212 void *context) 213 { 214 215 KASSERT(((cb_type >= TASKQUEUE_CALLBACK_TYPE_MIN) && 216 (cb_type <= TASKQUEUE_CALLBACK_TYPE_MAX)), 217 ("Callback type %d not valid, must be %d-%d", cb_type, 218 TASKQUEUE_CALLBACK_TYPE_MIN, TASKQUEUE_CALLBACK_TYPE_MAX)); 219 KASSERT((queue->tq_callbacks[cb_type] == NULL), 220 ("Re-initialization of taskqueue callback?")); 221 222 queue->tq_callbacks[cb_type] = callback; 223 queue->tq_cb_contexts[cb_type] = context; 224 } 225 226 /* 227 * Signal a taskqueue thread to terminate. 228 */ 229 static void 230 taskqueue_terminate(struct thread **pp, struct taskqueue *tq) 231 { 232 233 while (tq->tq_tcount > 0 || tq->tq_callouts > 0) { 234 wakeup(tq); 235 TQ_SLEEP(tq, pp, "tq_destroy"); 236 } 237 } 238 239 void 240 taskqueue_free(struct taskqueue *queue) 241 { 242 243 TQ_LOCK(queue); 244 queue->tq_flags &= ~TQ_FLAGS_ACTIVE; 245 taskqueue_terminate(queue->tq_threads, queue); 246 KASSERT(LIST_EMPTY(&queue->tq_active), ("Tasks still running?")); 247 KASSERT(queue->tq_callouts == 0, ("Armed timeout tasks")); 248 mtx_destroy(&queue->tq_mutex); 249 free(queue->tq_threads, M_TASKQUEUE); 250 free(queue->tq_name, M_TASKQUEUE); 251 free(queue, M_TASKQUEUE); 252 } 253 254 static int 255 taskqueue_enqueue_locked(struct taskqueue *queue, struct task *task, int flags) 256 { 257 struct task *ins; 258 struct task *prev; 259 struct taskqueue_busy *tb; 260 261 KASSERT(task->ta_func != NULL, ("enqueueing task with NULL func")); 262 /* 263 * Ignore canceling task if requested. 264 */ 265 if (__predict_false((flags & TASKQUEUE_FAIL_IF_CANCELING) != 0)) { 266 tb = task_get_busy(queue, task); 267 if (tb != NULL && tb->tb_canceling) { 268 TQ_UNLOCK(queue); 269 return (ECANCELED); 270 } 271 } 272 273 /* 274 * Count multiple enqueues. 275 */ 276 if (task->ta_pending) { 277 if (__predict_false((flags & TASKQUEUE_FAIL_IF_PENDING) != 0)) { 278 TQ_UNLOCK(queue); 279 return (EEXIST); 280 } 281 if (task->ta_pending < USHRT_MAX) 282 task->ta_pending++; 283 TQ_UNLOCK(queue); 284 return (0); 285 } 286 287 /* 288 * Optimise cases when all tasks use small set of priorities. 289 * In case of only one priority we always insert at the end. 290 * In case of two tq_hint typically gives the insertion point. 291 * In case of more then two tq_hint should halve the search. 292 */ 293 prev = STAILQ_LAST(&queue->tq_queue, task, ta_link); 294 if (!prev || prev->ta_priority >= task->ta_priority) { 295 STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link); 296 } else { 297 prev = queue->tq_hint; 298 if (prev && prev->ta_priority >= task->ta_priority) { 299 ins = STAILQ_NEXT(prev, ta_link); 300 } else { 301 prev = NULL; 302 ins = STAILQ_FIRST(&queue->tq_queue); 303 } 304 for (; ins; prev = ins, ins = STAILQ_NEXT(ins, ta_link)) 305 if (ins->ta_priority < task->ta_priority) 306 break; 307 308 if (prev) { 309 STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); 310 queue->tq_hint = task; 311 } else 312 STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); 313 } 314 315 task->ta_pending = 1; 316 if ((queue->tq_flags & TQ_FLAGS_UNLOCKED_ENQUEUE) != 0) 317 TQ_UNLOCK(queue); 318 if ((queue->tq_flags & TQ_FLAGS_BLOCKED) == 0) 319 queue->tq_enqueue(queue->tq_context); 320 if ((queue->tq_flags & TQ_FLAGS_UNLOCKED_ENQUEUE) == 0) 321 TQ_UNLOCK(queue); 322 323 /* Return with lock released. */ 324 return (0); 325 } 326 327 int 328 taskqueue_enqueue_flags(struct taskqueue *queue, struct task *task, int flags) 329 { 330 int res; 331 332 TQ_LOCK(queue); 333 res = taskqueue_enqueue_locked(queue, task, flags); 334 /* The lock is released inside. */ 335 336 return (res); 337 } 338 339 int 340 taskqueue_enqueue(struct taskqueue *queue, struct task *task) 341 { 342 return (taskqueue_enqueue_flags(queue, task, 0)); 343 } 344 345 static void 346 taskqueue_timeout_func(void *arg) 347 { 348 struct taskqueue *queue; 349 struct timeout_task *timeout_task; 350 351 timeout_task = arg; 352 queue = timeout_task->q; 353 KASSERT((timeout_task->f & DT_CALLOUT_ARMED) != 0, ("Stray timeout")); 354 timeout_task->f &= ~DT_CALLOUT_ARMED; 355 queue->tq_callouts--; 356 taskqueue_enqueue_locked(timeout_task->q, &timeout_task->t, 0); 357 /* The lock is released inside. */ 358 } 359 360 int 361 taskqueue_enqueue_timeout_sbt(struct taskqueue *queue, 362 struct timeout_task *timeout_task, sbintime_t sbt, sbintime_t pr, int flags) 363 { 364 int res; 365 366 TQ_LOCK(queue); 367 KASSERT(timeout_task->q == NULL || timeout_task->q == queue, 368 ("Migrated queue")); 369 timeout_task->q = queue; 370 res = timeout_task->t.ta_pending; 371 if (timeout_task->f & DT_DRAIN_IN_PROGRESS) { 372 /* Do nothing */ 373 TQ_UNLOCK(queue); 374 res = -1; 375 } else if (sbt == 0) { 376 taskqueue_enqueue_locked(queue, &timeout_task->t, 0); 377 /* The lock is released inside. */ 378 } else { 379 if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) { 380 res++; 381 } else { 382 queue->tq_callouts++; 383 timeout_task->f |= DT_CALLOUT_ARMED; 384 if (sbt < 0) 385 sbt = -sbt; /* Ignore overflow. */ 386 } 387 if (sbt > 0) { 388 if (queue->tq_spin) 389 flags |= C_DIRECT_EXEC; 390 if (queue->tq_spin && queue->tq_tcount == 1 && 391 queue->tq_threads[0] == curthread) { 392 callout_reset_sbt_curcpu(&timeout_task->c, sbt, pr, 393 taskqueue_timeout_func, timeout_task, flags); 394 } else { 395 callout_reset_sbt(&timeout_task->c, sbt, pr, 396 taskqueue_timeout_func, timeout_task, flags); 397 } 398 } 399 TQ_UNLOCK(queue); 400 } 401 return (res); 402 } 403 404 int 405 taskqueue_enqueue_timeout(struct taskqueue *queue, 406 struct timeout_task *ttask, int ticks) 407 { 408 409 return (taskqueue_enqueue_timeout_sbt(queue, ttask, ticks * tick_sbt, 410 0, C_HARDCLOCK)); 411 } 412 413 static void 414 taskqueue_task_nop_fn(void *context, int pending) 415 { 416 } 417 418 /* 419 * Block until all currently queued tasks in this taskqueue 420 * have begun execution. Tasks queued during execution of 421 * this function are ignored. 422 */ 423 static int 424 taskqueue_drain_tq_queue(struct taskqueue *queue) 425 { 426 struct task t_barrier; 427 428 if (STAILQ_EMPTY(&queue->tq_queue)) 429 return (0); 430 431 /* 432 * Enqueue our barrier after all current tasks, but with 433 * the highest priority so that newly queued tasks cannot 434 * pass it. Because of the high priority, we can not use 435 * taskqueue_enqueue_locked directly (which drops the lock 436 * anyway) so just insert it at tail while we have the 437 * queue lock. 438 */ 439 TASK_INIT(&t_barrier, UCHAR_MAX, taskqueue_task_nop_fn, &t_barrier); 440 STAILQ_INSERT_TAIL(&queue->tq_queue, &t_barrier, ta_link); 441 queue->tq_hint = &t_barrier; 442 t_barrier.ta_pending = 1; 443 444 /* 445 * Once the barrier has executed, all previously queued tasks 446 * have completed or are currently executing. 447 */ 448 while (t_barrier.ta_pending != 0) 449 TQ_SLEEP(queue, &t_barrier, "tq_qdrain"); 450 return (1); 451 } 452 453 /* 454 * Block until all currently executing tasks for this taskqueue 455 * complete. Tasks that begin execution during the execution 456 * of this function are ignored. 457 */ 458 static int 459 taskqueue_drain_tq_active(struct taskqueue *queue) 460 { 461 struct taskqueue_busy *tb; 462 u_int seq; 463 464 if (LIST_EMPTY(&queue->tq_active)) 465 return (0); 466 467 /* Block taskq_terminate().*/ 468 queue->tq_callouts++; 469 470 /* Wait for any active task with sequence from the past. */ 471 seq = queue->tq_seq; 472 restart: 473 LIST_FOREACH(tb, &queue->tq_active, tb_link) { 474 if ((int)(tb->tb_seq - seq) <= 0) { 475 TQ_SLEEP_BUSY(queue, tb, "tq_adrain"); 476 goto restart; 477 } 478 } 479 480 /* Release taskqueue_terminate(). */ 481 queue->tq_callouts--; 482 if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0) 483 wakeup_one(queue->tq_threads); 484 return (1); 485 } 486 487 void 488 taskqueue_block(struct taskqueue *queue) 489 { 490 491 TQ_LOCK(queue); 492 queue->tq_flags |= TQ_FLAGS_BLOCKED; 493 TQ_UNLOCK(queue); 494 } 495 496 void 497 taskqueue_unblock(struct taskqueue *queue) 498 { 499 500 TQ_LOCK(queue); 501 queue->tq_flags &= ~TQ_FLAGS_BLOCKED; 502 if (!STAILQ_EMPTY(&queue->tq_queue)) 503 queue->tq_enqueue(queue->tq_context); 504 TQ_UNLOCK(queue); 505 } 506 507 static void 508 taskqueue_run_locked(struct taskqueue *queue) 509 { 510 struct epoch_tracker et; 511 struct taskqueue_busy tb; 512 struct task *task; 513 unsigned int epochtasks; 514 int pending; 515 516 KASSERT(queue != NULL, ("tq is NULL")); 517 TQ_ASSERT_LOCKED(queue); 518 tb.tb_running = NULL; 519 tb.tb_wanted = false; 520 LIST_INSERT_HEAD(&queue->tq_active, &tb, tb_link); 521 522 epochtasks = 0; 523 while ((task = STAILQ_FIRST(&queue->tq_queue)) != NULL) { 524 STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); 525 if (queue->tq_hint == task) 526 queue->tq_hint = NULL; 527 pending = task->ta_pending; 528 task->ta_pending = 0; 529 tb.tb_running = task; 530 tb.tb_seq = ++queue->tq_seq; 531 tb.tb_canceling = false; 532 TQ_UNLOCK(queue); 533 534 KASSERT(task->ta_func != NULL, ("task->ta_func is NULL")); 535 if (TASK_IS_NET(task)) { 536 if (epochtasks++ == 0) 537 NET_EPOCH_ENTER(et); 538 } else if (epochtasks > 0) { 539 NET_EPOCH_EXIT(et); 540 epochtasks = 0; 541 } 542 task->ta_func(task->ta_context, pending); 543 if (epochtasks > net_epoch_task_limit) { 544 NET_EPOCH_EXIT(et); 545 epochtasks = 0; 546 } 547 548 wakeup(task); 549 550 TQ_LOCK(queue); 551 if (__predict_false(tb.tb_wanted)) { 552 tb.tb_wanted = false; 553 wakeup(&tb); 554 } 555 } 556 if (epochtasks > 0) 557 NET_EPOCH_EXIT(et); 558 LIST_REMOVE(&tb, tb_link); 559 } 560 561 void 562 taskqueue_run(struct taskqueue *queue) 563 { 564 565 TQ_LOCK(queue); 566 taskqueue_run_locked(queue); 567 TQ_UNLOCK(queue); 568 } 569 570 /* 571 * Only use this function in single threaded contexts. It returns 572 * non-zero if the given task is either pending or running. Else the 573 * task is idle and can be queued again or freed. 574 */ 575 int 576 taskqueue_poll_is_busy(struct taskqueue *queue, struct task *task) 577 { 578 int retval; 579 580 TQ_LOCK(queue); 581 retval = task->ta_pending > 0 || task_get_busy(queue, task) != NULL; 582 TQ_UNLOCK(queue); 583 584 return (retval); 585 } 586 587 static int 588 taskqueue_cancel_locked(struct taskqueue *queue, struct task *task, 589 u_int *pendp) 590 { 591 struct taskqueue_busy *tb; 592 int retval = 0; 593 594 if (task->ta_pending > 0) { 595 STAILQ_REMOVE(&queue->tq_queue, task, task, ta_link); 596 if (queue->tq_hint == task) 597 queue->tq_hint = NULL; 598 } 599 if (pendp != NULL) 600 *pendp = task->ta_pending; 601 task->ta_pending = 0; 602 tb = task_get_busy(queue, task); 603 if (tb != NULL) { 604 tb->tb_canceling = true; 605 retval = EBUSY; 606 } 607 608 return (retval); 609 } 610 611 int 612 taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp) 613 { 614 int error; 615 616 TQ_LOCK(queue); 617 error = taskqueue_cancel_locked(queue, task, pendp); 618 TQ_UNLOCK(queue); 619 620 return (error); 621 } 622 623 int 624 taskqueue_cancel_timeout(struct taskqueue *queue, 625 struct timeout_task *timeout_task, u_int *pendp) 626 { 627 u_int pending, pending1; 628 int error; 629 630 TQ_LOCK(queue); 631 pending = !!(callout_stop(&timeout_task->c) > 0); 632 error = taskqueue_cancel_locked(queue, &timeout_task->t, &pending1); 633 if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) { 634 timeout_task->f &= ~DT_CALLOUT_ARMED; 635 queue->tq_callouts--; 636 } 637 TQ_UNLOCK(queue); 638 639 if (pendp != NULL) 640 *pendp = pending + pending1; 641 return (error); 642 } 643 644 void 645 taskqueue_drain(struct taskqueue *queue, struct task *task) 646 { 647 struct taskqueue_busy *tb; 648 649 if (!queue->tq_spin) 650 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); 651 652 TQ_LOCK(queue); 653 for (;;) { 654 if (task->ta_pending != 0) 655 TQ_SLEEP(queue, task, "tq_drain"); 656 else if ((tb = task_get_busy(queue, task)) != NULL) 657 TQ_SLEEP_BUSY(queue, tb, "tq_drain"); 658 else 659 break; 660 } 661 TQ_UNLOCK(queue); 662 } 663 664 void 665 taskqueue_drain_all(struct taskqueue *queue) 666 { 667 668 if (!queue->tq_spin) 669 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); 670 671 TQ_LOCK(queue); 672 (void)taskqueue_drain_tq_queue(queue); 673 (void)taskqueue_drain_tq_active(queue); 674 TQ_UNLOCK(queue); 675 } 676 677 void 678 taskqueue_drain_timeout(struct taskqueue *queue, 679 struct timeout_task *timeout_task) 680 { 681 682 /* 683 * Set flag to prevent timer from re-starting during drain: 684 */ 685 TQ_LOCK(queue); 686 KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0, 687 ("Drain already in progress")); 688 timeout_task->f |= DT_DRAIN_IN_PROGRESS; 689 TQ_UNLOCK(queue); 690 691 callout_drain(&timeout_task->c); 692 taskqueue_drain(queue, &timeout_task->t); 693 694 /* 695 * Clear flag to allow timer to re-start: 696 */ 697 TQ_LOCK(queue); 698 timeout_task->f &= ~DT_DRAIN_IN_PROGRESS; 699 TQ_UNLOCK(queue); 700 } 701 702 void 703 taskqueue_quiesce(struct taskqueue *queue) 704 { 705 int ret; 706 707 TQ_LOCK(queue); 708 do { 709 ret = taskqueue_drain_tq_queue(queue); 710 if (ret == 0) 711 ret = taskqueue_drain_tq_active(queue); 712 } while (ret != 0); 713 TQ_UNLOCK(queue); 714 } 715 716 static void 717 taskqueue_swi_enqueue(void *context) 718 { 719 swi_sched(taskqueue_ih, 0); 720 } 721 722 static void 723 taskqueue_swi_run(void *dummy) 724 { 725 taskqueue_run(taskqueue_swi); 726 } 727 728 static void 729 taskqueue_swi_giant_enqueue(void *context) 730 { 731 swi_sched(taskqueue_giant_ih, 0); 732 } 733 734 static void 735 taskqueue_swi_giant_run(void *dummy) 736 { 737 taskqueue_run(taskqueue_swi_giant); 738 } 739 740 static int 741 _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri, 742 cpuset_t *mask, struct proc *p, const char *name, va_list ap) 743 { 744 char ktname[MAXCOMLEN + 1]; 745 struct thread *td; 746 struct taskqueue *tq; 747 int i, error; 748 749 if (count <= 0) 750 return (EINVAL); 751 752 vsnprintf(ktname, sizeof(ktname), name, ap); 753 tq = *tqp; 754 755 tq->tq_threads = malloc(sizeof(struct thread *) * count, M_TASKQUEUE, 756 M_NOWAIT | M_ZERO); 757 if (tq->tq_threads == NULL) { 758 printf("%s: no memory for %s threads\n", __func__, ktname); 759 return (ENOMEM); 760 } 761 762 for (i = 0; i < count; i++) { 763 if (count == 1) 764 error = kthread_add(taskqueue_thread_loop, tqp, p, 765 &tq->tq_threads[i], RFSTOPPED, 0, "%s", ktname); 766 else 767 error = kthread_add(taskqueue_thread_loop, tqp, p, 768 &tq->tq_threads[i], RFSTOPPED, 0, 769 "%s_%d", ktname, i); 770 if (error) { 771 /* should be ok to continue, taskqueue_free will dtrt */ 772 printf("%s: kthread_add(%s): error %d", __func__, 773 ktname, error); 774 tq->tq_threads[i] = NULL; /* paranoid */ 775 } else 776 tq->tq_tcount++; 777 } 778 if (tq->tq_tcount == 0) { 779 free(tq->tq_threads, M_TASKQUEUE); 780 tq->tq_threads = NULL; 781 return (ENOMEM); 782 } 783 for (i = 0; i < count; i++) { 784 if (tq->tq_threads[i] == NULL) 785 continue; 786 td = tq->tq_threads[i]; 787 if (mask) { 788 error = cpuset_setthread(td->td_tid, mask); 789 /* 790 * Failing to pin is rarely an actual fatal error; 791 * it'll just affect performance. 792 */ 793 if (error) 794 printf("%s: curthread=%llu: can't pin; " 795 "error=%d\n", 796 __func__, 797 (unsigned long long) td->td_tid, 798 error); 799 } 800 thread_lock(td); 801 sched_prio(td, pri); 802 sched_add(td, SRQ_BORING); 803 } 804 805 return (0); 806 } 807 808 int 809 taskqueue_start_threads(struct taskqueue **tqp, int count, int pri, 810 const char *name, ...) 811 { 812 va_list ap; 813 int error; 814 815 va_start(ap, name); 816 error = _taskqueue_start_threads(tqp, count, pri, NULL, NULL, name, ap); 817 va_end(ap); 818 return (error); 819 } 820 821 int 822 taskqueue_start_threads_in_proc(struct taskqueue **tqp, int count, int pri, 823 struct proc *proc, const char *name, ...) 824 { 825 va_list ap; 826 int error; 827 828 va_start(ap, name); 829 error = _taskqueue_start_threads(tqp, count, pri, NULL, proc, name, ap); 830 va_end(ap); 831 return (error); 832 } 833 834 int 835 taskqueue_start_threads_cpuset(struct taskqueue **tqp, int count, int pri, 836 cpuset_t *mask, const char *name, ...) 837 { 838 va_list ap; 839 int error; 840 841 va_start(ap, name); 842 error = _taskqueue_start_threads(tqp, count, pri, mask, NULL, name, ap); 843 va_end(ap); 844 return (error); 845 } 846 847 static inline void 848 taskqueue_run_callback(struct taskqueue *tq, 849 enum taskqueue_callback_type cb_type) 850 { 851 taskqueue_callback_fn tq_callback; 852 853 TQ_ASSERT_UNLOCKED(tq); 854 tq_callback = tq->tq_callbacks[cb_type]; 855 if (tq_callback != NULL) 856 tq_callback(tq->tq_cb_contexts[cb_type]); 857 } 858 859 void 860 taskqueue_thread_loop(void *arg) 861 { 862 struct taskqueue **tqp, *tq; 863 864 tqp = arg; 865 tq = *tqp; 866 taskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_INIT); 867 TQ_LOCK(tq); 868 while ((tq->tq_flags & TQ_FLAGS_ACTIVE) != 0) { 869 /* XXX ? */ 870 taskqueue_run_locked(tq); 871 /* 872 * Because taskqueue_run() can drop tq_mutex, we need to 873 * check if the TQ_FLAGS_ACTIVE flag wasn't removed in the 874 * meantime, which means we missed a wakeup. 875 */ 876 if ((tq->tq_flags & TQ_FLAGS_ACTIVE) == 0) 877 break; 878 TQ_SLEEP(tq, tq, "-"); 879 } 880 taskqueue_run_locked(tq); 881 /* 882 * This thread is on its way out, so just drop the lock temporarily 883 * in order to call the shutdown callback. This allows the callback 884 * to look at the taskqueue, even just before it dies. 885 */ 886 TQ_UNLOCK(tq); 887 taskqueue_run_callback(tq, TASKQUEUE_CALLBACK_TYPE_SHUTDOWN); 888 TQ_LOCK(tq); 889 890 /* rendezvous with thread that asked us to terminate */ 891 tq->tq_tcount--; 892 wakeup_one(tq->tq_threads); 893 TQ_UNLOCK(tq); 894 kthread_exit(); 895 } 896 897 void 898 taskqueue_thread_enqueue(void *context) 899 { 900 struct taskqueue **tqp, *tq; 901 902 tqp = context; 903 tq = *tqp; 904 wakeup_any(tq); 905 } 906 907 TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, NULL, 908 swi_add(NULL, "task queue", taskqueue_swi_run, NULL, SWI_TQ, 909 INTR_MPSAFE, &taskqueue_ih)); 910 911 TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, NULL, 912 swi_add(NULL, "Giant taskq", taskqueue_swi_giant_run, 913 NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); 914 915 TASKQUEUE_DEFINE_THREAD(thread); 916 917 struct taskqueue * 918 taskqueue_create_fast(const char *name, int mflags, 919 taskqueue_enqueue_fn enqueue, void *context) 920 { 921 return _taskqueue_create(name, mflags, enqueue, context, 922 MTX_SPIN, "fast_taskqueue"); 923 } 924 925 static void *taskqueue_fast_ih; 926 927 static void 928 taskqueue_fast_enqueue(void *context) 929 { 930 swi_sched(taskqueue_fast_ih, 0); 931 } 932 933 static void 934 taskqueue_fast_run(void *dummy) 935 { 936 taskqueue_run(taskqueue_fast); 937 } 938 939 TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, NULL, 940 swi_add(NULL, "fast taskq", taskqueue_fast_run, NULL, 941 SWI_TQ_FAST, INTR_MPSAFE, &taskqueue_fast_ih)); 942 943 int 944 taskqueue_member(struct taskqueue *queue, struct thread *td) 945 { 946 int i, j, ret = 0; 947 948 for (i = 0, j = 0; ; i++) { 949 if (queue->tq_threads[i] == NULL) 950 continue; 951 if (queue->tq_threads[i] == td) { 952 ret = 1; 953 break; 954 } 955 if (++j >= queue->tq_tcount) 956 break; 957 } 958 return (ret); 959 } 960