1 /*- 2 * Copyright (c) 2017 Hans Petter Selasky 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <linux/workqueue.h> 31 #include <linux/wait.h> 32 #include <linux/compat.h> 33 #include <linux/spinlock.h> 34 35 #include <sys/kernel.h> 36 37 /* 38 * Define all work struct states 39 */ 40 enum { 41 WORK_ST_IDLE, /* idle - not started */ 42 WORK_ST_TIMER, /* timer is being started */ 43 WORK_ST_TASK, /* taskqueue is being queued */ 44 WORK_ST_EXEC, /* callback is being called */ 45 WORK_ST_CANCEL, /* cancel is being requested */ 46 WORK_ST_MAX, 47 }; 48 49 /* 50 * Define global workqueues 51 */ 52 static struct workqueue_struct *linux_system_short_wq; 53 static struct workqueue_struct *linux_system_long_wq; 54 55 struct workqueue_struct *system_wq; 56 struct workqueue_struct *system_long_wq; 57 struct workqueue_struct *system_unbound_wq; 58 struct workqueue_struct *system_power_efficient_wq; 59 60 static void linux_delayed_work_timer_fn(void *); 61 62 /* 63 * This function atomically updates the work state and returns the 64 * previous state at the time of update. 65 */ 66 static uint8_t 67 linux_update_state(atomic_t *v, const uint8_t *pstate) 68 { 69 int c, old; 70 71 c = v->counter; 72 73 while ((old = atomic_cmpxchg(v, c, pstate[c])) != c) 74 c = old; 75 76 return (c); 77 } 78 79 /* 80 * A LinuxKPI task is allowed to free itself inside the callback function 81 * and cannot safely be referred after the callback function has 82 * completed. This function gives the linux_work_fn() function a hint, 83 * that the task is not going away and can have its state checked 84 * again. Without this extra hint LinuxKPI tasks cannot be serialized 85 * accross multiple worker threads. 86 */ 87 static bool 88 linux_work_exec_unblock(struct work_struct *work) 89 { 90 struct workqueue_struct *wq; 91 struct work_exec *exec; 92 bool retval = 0; 93 94 wq = work->work_queue; 95 if (unlikely(wq == NULL)) 96 goto done; 97 98 WQ_EXEC_LOCK(wq); 99 TAILQ_FOREACH(exec, &wq->exec_head, entry) { 100 if (exec->target == work) { 101 exec->target = NULL; 102 retval = 1; 103 break; 104 } 105 } 106 WQ_EXEC_UNLOCK(wq); 107 done: 108 return (retval); 109 } 110 111 static void 112 linux_delayed_work_enqueue(struct delayed_work *dwork) 113 { 114 struct taskqueue *tq; 115 116 tq = dwork->work.work_queue->taskqueue; 117 taskqueue_enqueue(tq, &dwork->work.work_task); 118 } 119 120 /* 121 * This function queues the given work structure on the given 122 * workqueue. It returns non-zero if the work was successfully 123 * [re-]queued. Else the work is already pending for completion. 124 */ 125 bool 126 linux_queue_work_on(int cpu __unused, struct workqueue_struct *wq, 127 struct work_struct *work) 128 { 129 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 130 [WORK_ST_IDLE] = WORK_ST_TASK, /* start queuing task */ 131 [WORK_ST_TIMER] = WORK_ST_TIMER, /* NOP */ 132 [WORK_ST_TASK] = WORK_ST_TASK, /* NOP */ 133 [WORK_ST_EXEC] = WORK_ST_TASK, /* queue task another time */ 134 [WORK_ST_CANCEL] = WORK_ST_TASK, /* start queuing task again */ 135 }; 136 137 if (atomic_read(&wq->draining) != 0) 138 return (!work_pending(work)); 139 140 switch (linux_update_state(&work->state, states)) { 141 case WORK_ST_EXEC: 142 case WORK_ST_CANCEL: 143 if (linux_work_exec_unblock(work) != 0) 144 return (1); 145 /* FALLTHROUGH */ 146 case WORK_ST_IDLE: 147 work->work_queue = wq; 148 taskqueue_enqueue(wq->taskqueue, &work->work_task); 149 return (1); 150 default: 151 return (0); /* already on a queue */ 152 } 153 } 154 155 /* 156 * This function queues the given work structure on the given 157 * workqueue after a given delay in ticks. It returns non-zero if the 158 * work was successfully [re-]queued. Else the work is already pending 159 * for completion. 160 */ 161 bool 162 linux_queue_delayed_work_on(int cpu, struct workqueue_struct *wq, 163 struct delayed_work *dwork, unsigned delay) 164 { 165 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 166 [WORK_ST_IDLE] = WORK_ST_TIMER, /* start timeout */ 167 [WORK_ST_TIMER] = WORK_ST_TIMER, /* NOP */ 168 [WORK_ST_TASK] = WORK_ST_TASK, /* NOP */ 169 [WORK_ST_EXEC] = WORK_ST_TIMER, /* start timeout */ 170 [WORK_ST_CANCEL] = WORK_ST_TIMER, /* start timeout */ 171 }; 172 173 if (atomic_read(&wq->draining) != 0) 174 return (!work_pending(&dwork->work)); 175 176 switch (linux_update_state(&dwork->work.state, states)) { 177 case WORK_ST_EXEC: 178 case WORK_ST_CANCEL: 179 if (delay == 0 && linux_work_exec_unblock(&dwork->work) != 0) { 180 dwork->timer.expires = jiffies; 181 return (1); 182 } 183 /* FALLTHROUGH */ 184 case WORK_ST_IDLE: 185 dwork->work.work_queue = wq; 186 dwork->timer.expires = jiffies + delay; 187 188 if (delay == 0) { 189 linux_delayed_work_enqueue(dwork); 190 } else if (unlikely(cpu != WORK_CPU_UNBOUND)) { 191 mtx_lock(&dwork->timer.mtx); 192 callout_reset_on(&dwork->timer.callout, delay, 193 &linux_delayed_work_timer_fn, dwork, cpu); 194 mtx_unlock(&dwork->timer.mtx); 195 } else { 196 mtx_lock(&dwork->timer.mtx); 197 callout_reset(&dwork->timer.callout, delay, 198 &linux_delayed_work_timer_fn, dwork); 199 mtx_unlock(&dwork->timer.mtx); 200 } 201 return (1); 202 default: 203 return (0); /* already on a queue */ 204 } 205 } 206 207 void 208 linux_work_fn(void *context, int pending) 209 { 210 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 211 [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ 212 [WORK_ST_TIMER] = WORK_ST_EXEC, /* delayed work w/o timeout */ 213 [WORK_ST_TASK] = WORK_ST_EXEC, /* call callback */ 214 [WORK_ST_EXEC] = WORK_ST_IDLE, /* complete callback */ 215 [WORK_ST_CANCEL] = WORK_ST_IDLE, /* complete cancel */ 216 }; 217 struct work_struct *work; 218 struct workqueue_struct *wq; 219 struct work_exec exec; 220 221 linux_set_current(curthread); 222 223 /* setup local variables */ 224 work = context; 225 wq = work->work_queue; 226 227 /* store target pointer */ 228 exec.target = work; 229 230 /* insert executor into list */ 231 WQ_EXEC_LOCK(wq); 232 TAILQ_INSERT_TAIL(&wq->exec_head, &exec, entry); 233 while (1) { 234 switch (linux_update_state(&work->state, states)) { 235 case WORK_ST_TIMER: 236 case WORK_ST_TASK: 237 WQ_EXEC_UNLOCK(wq); 238 239 /* call work function */ 240 work->func(work); 241 242 WQ_EXEC_LOCK(wq); 243 /* check if unblocked */ 244 if (exec.target != work) { 245 /* reapply block */ 246 exec.target = work; 247 break; 248 } 249 /* FALLTHROUGH */ 250 default: 251 goto done; 252 } 253 } 254 done: 255 /* remove executor from list */ 256 TAILQ_REMOVE(&wq->exec_head, &exec, entry); 257 WQ_EXEC_UNLOCK(wq); 258 } 259 260 static void 261 linux_delayed_work_timer_fn(void *arg) 262 { 263 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 264 [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ 265 [WORK_ST_TIMER] = WORK_ST_TASK, /* start queueing task */ 266 [WORK_ST_TASK] = WORK_ST_TASK, /* NOP */ 267 [WORK_ST_EXEC] = WORK_ST_TASK, /* queue task another time */ 268 [WORK_ST_CANCEL] = WORK_ST_IDLE, /* complete cancel */ 269 }; 270 struct delayed_work *dwork = arg; 271 272 switch (linux_update_state(&dwork->work.state, states)) { 273 case WORK_ST_TIMER: 274 linux_delayed_work_enqueue(dwork); 275 break; 276 default: 277 break; 278 } 279 } 280 281 /* 282 * This function cancels the given work structure in a synchronous 283 * fashion. It returns non-zero if the work was successfully 284 * cancelled. Else the work was already cancelled. 285 */ 286 bool 287 linux_cancel_work_sync(struct work_struct *work) 288 { 289 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 290 [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ 291 [WORK_ST_TIMER] = WORK_ST_IDLE, /* idle */ 292 [WORK_ST_TASK] = WORK_ST_IDLE, /* idle */ 293 [WORK_ST_EXEC] = WORK_ST_IDLE, /* idle */ 294 [WORK_ST_CANCEL] = WORK_ST_IDLE, /* idle */ 295 }; 296 struct taskqueue *tq; 297 298 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 299 "linux_cancel_work_sync() might sleep"); 300 301 switch (linux_update_state(&work->state, states)) { 302 case WORK_ST_IDLE: 303 return (0); 304 default: 305 tq = work->work_queue->taskqueue; 306 if (taskqueue_cancel(tq, &work->work_task, NULL) != 0) 307 taskqueue_drain(tq, &work->work_task); 308 return (1); 309 } 310 } 311 312 /* 313 * This function atomically stops the timer and callback. The timer 314 * callback will not be called after this function returns. This 315 * functions returns true when the timeout was cancelled. Else the 316 * timeout was not started or has already been called. 317 */ 318 static inline bool 319 linux_cancel_timer(struct delayed_work *dwork, bool drain) 320 { 321 bool cancelled; 322 323 mtx_lock(&dwork->timer.mtx); 324 cancelled = (callout_stop(&dwork->timer.callout) == 1); 325 mtx_unlock(&dwork->timer.mtx); 326 327 /* check if we should drain */ 328 if (drain) 329 callout_drain(&dwork->timer.callout); 330 return (cancelled); 331 } 332 333 /* 334 * This function cancels the given delayed work structure in a 335 * non-blocking fashion. It returns non-zero if the work was 336 * successfully cancelled. Else the work may still be busy or already 337 * cancelled. 338 */ 339 bool 340 linux_cancel_delayed_work(struct delayed_work *dwork) 341 { 342 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 343 [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ 344 [WORK_ST_TIMER] = WORK_ST_CANCEL, /* cancel */ 345 [WORK_ST_TASK] = WORK_ST_CANCEL, /* cancel */ 346 [WORK_ST_EXEC] = WORK_ST_CANCEL, /* cancel */ 347 [WORK_ST_CANCEL] = WORK_ST_CANCEL, /* cancel */ 348 }; 349 struct taskqueue *tq; 350 351 switch (linux_update_state(&dwork->work.state, states)) { 352 case WORK_ST_TIMER: 353 if (linux_cancel_timer(dwork, 0)) 354 return (1); 355 /* FALLTHROUGH */ 356 case WORK_ST_TASK: 357 case WORK_ST_EXEC: 358 tq = dwork->work.work_queue->taskqueue; 359 if (taskqueue_cancel(tq, &dwork->work.work_task, NULL) == 0) 360 return (1); 361 /* FALLTHROUGH */ 362 default: 363 return (0); 364 } 365 } 366 367 /* 368 * This function cancels the given work structure in a synchronous 369 * fashion. It returns non-zero if the work was successfully 370 * cancelled. Else the work was already cancelled. 371 */ 372 bool 373 linux_cancel_delayed_work_sync(struct delayed_work *dwork) 374 { 375 static const uint8_t states[WORK_ST_MAX] __aligned(8) = { 376 [WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */ 377 [WORK_ST_TIMER] = WORK_ST_IDLE, /* idle */ 378 [WORK_ST_TASK] = WORK_ST_IDLE, /* idle */ 379 [WORK_ST_EXEC] = WORK_ST_IDLE, /* idle */ 380 [WORK_ST_CANCEL] = WORK_ST_IDLE, /* idle */ 381 }; 382 struct taskqueue *tq; 383 384 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 385 "linux_cancel_delayed_work_sync() might sleep"); 386 387 switch (linux_update_state(&dwork->work.state, states)) { 388 case WORK_ST_IDLE: 389 return (0); 390 case WORK_ST_TIMER: 391 if (linux_cancel_timer(dwork, 1)) { 392 /* 393 * Make sure taskqueue is also drained before 394 * returning: 395 */ 396 tq = dwork->work.work_queue->taskqueue; 397 taskqueue_drain(tq, &dwork->work.work_task); 398 return (1); 399 } 400 /* FALLTHROUGH */ 401 default: 402 tq = dwork->work.work_queue->taskqueue; 403 if (taskqueue_cancel(tq, &dwork->work.work_task, NULL) != 0) 404 taskqueue_drain(tq, &dwork->work.work_task); 405 return (1); 406 } 407 } 408 409 /* 410 * This function waits until the given work structure is completed. 411 * It returns non-zero if the work was successfully 412 * waited for. Else the work was not waited for. 413 */ 414 bool 415 linux_flush_work(struct work_struct *work) 416 { 417 struct taskqueue *tq; 418 419 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 420 "linux_flush_work() might sleep"); 421 422 switch (atomic_read(&work->state)) { 423 case WORK_ST_IDLE: 424 return (0); 425 default: 426 tq = work->work_queue->taskqueue; 427 taskqueue_drain(tq, &work->work_task); 428 return (1); 429 } 430 } 431 432 /* 433 * This function waits until the given delayed work structure is 434 * completed. It returns non-zero if the work was successfully waited 435 * for. Else the work was not waited for. 436 */ 437 bool 438 linux_flush_delayed_work(struct delayed_work *dwork) 439 { 440 struct taskqueue *tq; 441 442 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 443 "linux_flush_delayed_work() might sleep"); 444 445 switch (atomic_read(&dwork->work.state)) { 446 case WORK_ST_IDLE: 447 return (0); 448 case WORK_ST_TIMER: 449 if (linux_cancel_timer(dwork, 1)) 450 linux_delayed_work_enqueue(dwork); 451 /* FALLTHROUGH */ 452 default: 453 tq = dwork->work.work_queue->taskqueue; 454 taskqueue_drain(tq, &dwork->work.work_task); 455 return (1); 456 } 457 } 458 459 /* 460 * This function returns true if the given work is pending, and not 461 * yet executing: 462 */ 463 bool 464 linux_work_pending(struct work_struct *work) 465 { 466 switch (atomic_read(&work->state)) { 467 case WORK_ST_TIMER: 468 case WORK_ST_TASK: 469 return (1); 470 default: 471 return (0); 472 } 473 } 474 475 /* 476 * This function returns true if the given work is busy. 477 */ 478 bool 479 linux_work_busy(struct work_struct *work) 480 { 481 struct taskqueue *tq; 482 483 switch (atomic_read(&work->state)) { 484 case WORK_ST_IDLE: 485 return (0); 486 case WORK_ST_EXEC: 487 case WORK_ST_CANCEL: 488 tq = work->work_queue->taskqueue; 489 return (taskqueue_poll_is_busy(tq, &work->work_task)); 490 default: 491 return (1); 492 } 493 } 494 495 struct workqueue_struct * 496 linux_create_workqueue_common(const char *name, int cpus) 497 { 498 struct workqueue_struct *wq; 499 500 wq = kmalloc(sizeof(*wq), M_WAITOK | M_ZERO); 501 wq->taskqueue = taskqueue_create(name, M_WAITOK, 502 taskqueue_thread_enqueue, &wq->taskqueue); 503 atomic_set(&wq->draining, 0); 504 taskqueue_start_threads(&wq->taskqueue, cpus, PWAIT, "%s", name); 505 TAILQ_INIT(&wq->exec_head); 506 mtx_init(&wq->exec_mtx, "linux_wq_exec", NULL, MTX_DEF); 507 508 return (wq); 509 } 510 511 void 512 linux_destroy_workqueue(struct workqueue_struct *wq) 513 { 514 atomic_inc(&wq->draining); 515 drain_workqueue(wq); 516 taskqueue_free(wq->taskqueue); 517 mtx_destroy(&wq->exec_mtx); 518 kfree(wq); 519 } 520 521 void 522 linux_init_delayed_work(struct delayed_work *dwork, work_func_t func) 523 { 524 memset(dwork, 0, sizeof(*dwork)); 525 INIT_WORK(&dwork->work, func); 526 mtx_init(&dwork->timer.mtx, spin_lock_name("lkpi-dwork"), NULL, 527 MTX_DEF | MTX_NOWITNESS); 528 callout_init_mtx(&dwork->timer.callout, &dwork->timer.mtx, 0); 529 } 530 531 static void 532 linux_work_init(void *arg) 533 { 534 int max_wq_cpus = mp_ncpus + 1; 535 536 /* avoid deadlock when there are too few threads */ 537 if (max_wq_cpus < 4) 538 max_wq_cpus = 4; 539 540 linux_system_short_wq = alloc_workqueue("linuxkpi_short_wq", 0, max_wq_cpus); 541 linux_system_long_wq = alloc_workqueue("linuxkpi_long_wq", 0, max_wq_cpus); 542 543 /* populate the workqueue pointers */ 544 system_long_wq = linux_system_long_wq; 545 system_wq = linux_system_short_wq; 546 system_power_efficient_wq = linux_system_short_wq; 547 system_unbound_wq = linux_system_short_wq; 548 } 549 SYSINIT(linux_work_init, SI_SUB_INIT_IF, SI_ORDER_THIRD, linux_work_init, NULL); 550 551 static void 552 linux_work_uninit(void *arg) 553 { 554 destroy_workqueue(linux_system_short_wq); 555 destroy_workqueue(linux_system_long_wq); 556 557 /* clear workqueue pointers */ 558 system_long_wq = NULL; 559 system_wq = NULL; 560 system_power_efficient_wq = NULL; 561 system_unbound_wq = NULL; 562 } 563 SYSUNINIT(linux_work_uninit, SI_SUB_INIT_IF, SI_ORDER_THIRD, linux_work_uninit, NULL); 564