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