Home | History | Annotate | Line # | Download | only in linux
linux_work.c revision 1.12
      1 /*	$NetBSD: linux_work.c,v 1.12 2018/08/27 14:57:21 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2018 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Taylor R. Campbell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: linux_work.c,v 1.12 2018/08/27 14:57:21 riastradh Exp $");
     34 
     35 #include <sys/types.h>
     36 #include <sys/atomic.h>
     37 #include <sys/callout.h>
     38 #include <sys/condvar.h>
     39 #include <sys/errno.h>
     40 #include <sys/kmem.h>
     41 #include <sys/kthread.h>
     42 #include <sys/lwp.h>
     43 #include <sys/mutex.h>
     44 #include <sys/queue.h>
     45 
     46 #include <linux/workqueue.h>
     47 
     48 struct workqueue_struct {
     49 	kmutex_t			wq_lock;
     50 	kcondvar_t			wq_cv;
     51 	TAILQ_HEAD(, delayed_work)	wq_delayed;
     52 	TAILQ_HEAD(, work_struct)	wq_queue;
     53 	struct work_struct		*wq_current_work;
     54 	int				wq_flags;
     55 	struct lwp			*wq_lwp;
     56 	uint64_t			wq_gen;
     57 	bool				wq_requeued:1;
     58 	bool				wq_dying:1;
     59 };
     60 
     61 static void __dead	linux_workqueue_thread(void *);
     62 static void		linux_workqueue_timeout(void *);
     63 static void		queue_delayed_work_anew(struct workqueue_struct *,
     64 			    struct delayed_work *, unsigned long);
     65 
     66 static specificdata_key_t workqueue_key __read_mostly;
     67 
     68 struct workqueue_struct	*system_wq __read_mostly;
     69 struct workqueue_struct	*system_long_wq __read_mostly;
     70 struct workqueue_struct	*system_power_efficient_wq __read_mostly;
     71 
     72 int
     73 linux_workqueue_init(void)
     74 {
     75 	int error;
     76 
     77 	error = lwp_specific_key_create(&workqueue_key, NULL);
     78 	if (error)
     79 		goto fail0;
     80 
     81 	system_wq = alloc_ordered_workqueue("lnxsyswq", 0);
     82 	if (system_wq == NULL) {
     83 		error = ENOMEM;
     84 		goto fail1;
     85 	}
     86 
     87 	system_long_wq = alloc_ordered_workqueue("lnxlngwq", 0);
     88 	if (system_long_wq == NULL) {
     89 		error = ENOMEM;
     90 		goto fail2;
     91 	}
     92 
     93 	system_power_efficient_wq = alloc_ordered_workqueue("lnxpwrwq", 0);
     94 	if (system_long_wq == NULL) {
     95 		error = ENOMEM;
     96 		goto fail3;
     97 	}
     98 
     99 	return 0;
    100 
    101 fail4: __unused
    102 	destroy_workqueue(system_power_efficient_wq);
    103 fail3:	destroy_workqueue(system_long_wq);
    104 fail2:	destroy_workqueue(system_wq);
    105 fail1:	lwp_specific_key_delete(workqueue_key);
    106 fail0:	KASSERT(error);
    107 	return error;
    108 }
    109 
    110 void
    111 linux_workqueue_fini(void)
    112 {
    113 
    114 	destroy_workqueue(system_power_efficient_wq);
    115 	destroy_workqueue(system_long_wq);
    116 	destroy_workqueue(system_wq);
    117 	lwp_specific_key_delete(workqueue_key);
    118 }
    119 
    120 /*
    122  * Workqueues
    123  */
    124 
    125 struct workqueue_struct *
    126 alloc_ordered_workqueue(const char *name, int flags)
    127 {
    128 	struct workqueue_struct *wq;
    129 	int error;
    130 
    131 	KASSERT(flags == 0);
    132 
    133 	wq = kmem_alloc(sizeof(*wq), KM_SLEEP);
    134 
    135 	mutex_init(&wq->wq_lock, MUTEX_DEFAULT, IPL_NONE);
    136 	cv_init(&wq->wq_cv, name);
    137 	TAILQ_INIT(&wq->wq_delayed);
    138 	TAILQ_INIT(&wq->wq_queue);
    139 	wq->wq_current_work = NULL;
    140 
    141 	error = kthread_create(PRI_NONE,
    142 	    KTHREAD_MPSAFE|KTHREAD_TS|KTHREAD_MUSTJOIN, NULL,
    143 	    &linux_workqueue_thread, wq, &wq->wq_lwp, "%s", name);
    144 	if (error)
    145 		goto fail0;
    146 
    147 	return wq;
    148 
    149 fail0:	KASSERT(TAILQ_EMPTY(&wq->wq_queue));
    150 	KASSERT(TAILQ_EMPTY(&wq->wq_delayed));
    151 	cv_destroy(&wq->wq_cv);
    152 	mutex_destroy(&wq->wq_lock);
    153 	kmem_free(wq, sizeof(*wq));
    154 	return NULL;
    155 }
    156 
    157 void
    158 destroy_workqueue(struct workqueue_struct *wq)
    159 {
    160 
    161 	/*
    162 	 * Cancel all delayed work.  We do this first because any
    163 	 * delayed work that that has already timed out, which we can't
    164 	 * cancel, may have queued new work.
    165 	 */
    166 	for (;;) {
    167 		struct delayed_work *dw = NULL;
    168 
    169 		mutex_enter(&wq->wq_lock);
    170 		if (!TAILQ_EMPTY(&wq->wq_delayed)) {
    171 			dw = TAILQ_FIRST(&wq->wq_delayed);
    172 			if (!callout_halt(&dw->dw_callout, &wq->wq_lock))
    173 				TAILQ_REMOVE(&wq->wq_delayed, dw, dw_entry);
    174 		}
    175 		mutex_exit(&wq->wq_lock);
    176 
    177 		if (dw == NULL)
    178 			break;
    179 		cancel_delayed_work_sync(dw);
    180 	}
    181 
    182 	/* Tell the thread to exit.  */
    183 	mutex_enter(&wq->wq_lock);
    184 	wq->wq_dying = true;
    185 	cv_broadcast(&wq->wq_cv);
    186 	mutex_exit(&wq->wq_lock);
    187 
    188 	/* Wait for it to exit.  */
    189 	(void)kthread_join(wq->wq_lwp);
    190 
    191 	KASSERT(wq->wq_current_work == NULL);
    192 	KASSERT(TAILQ_EMPTY(&wq->wq_queue));
    193 	KASSERT(TAILQ_EMPTY(&wq->wq_delayed));
    194 	cv_destroy(&wq->wq_cv);
    195 	mutex_destroy(&wq->wq_lock);
    196 
    197 	kmem_free(wq, sizeof(*wq));
    198 }
    199 
    200 /*
    202  * Work thread and callout
    203  */
    204 
    205 static void __dead
    206 linux_workqueue_thread(void *cookie)
    207 {
    208 	struct workqueue_struct *const wq = cookie;
    209 	TAILQ_HEAD(, work_struct) tmp;
    210 
    211 	lwp_setspecific(workqueue_key, wq);
    212 
    213 	mutex_enter(&wq->wq_lock);
    214 	for (;;) {
    215 		/* Wait until there's activity.  If we're dying, stop.  */
    216 		while (TAILQ_EMPTY(&wq->wq_queue) && !wq->wq_dying)
    217 			cv_wait(&wq->wq_cv, &wq->wq_lock);
    218 		if (wq->wq_dying)
    219 			break;
    220 
    221 		/* Grab a batch of work off the queue.  */
    222 		KASSERT(!TAILQ_EMPTY(&wq->wq_queue));
    223 		TAILQ_INIT(&tmp);
    224 		TAILQ_CONCAT(&tmp, &wq->wq_queue, work_entry);
    225 
    226 		/* Process each work item in the batch.  */
    227 		while (!TAILQ_EMPTY(&tmp)) {
    228 			struct work_struct *const work = TAILQ_FIRST(&tmp);
    229 
    230 			TAILQ_REMOVE(&tmp, work, work_entry);
    231 			KASSERT(wq->wq_current_work == NULL);
    232 			wq->wq_current_work = work;
    233 
    234 			mutex_exit(&wq->wq_lock);
    235 			(*work->func)(work);
    236 			mutex_enter(&wq->wq_lock);
    237 
    238 			KASSERT(wq->wq_current_work == work);
    239 			KASSERT(work->work_queue == wq);
    240 			if (wq->wq_requeued)
    241 				wq->wq_requeued = false;
    242 			else
    243 				work->work_queue = NULL;
    244 			wq->wq_current_work = NULL;
    245 			cv_broadcast(&wq->wq_cv);
    246 		}
    247 
    248 		/* Notify flush that we've completed a batch of work.  */
    249 		wq->wq_gen++;
    250 		cv_broadcast(&wq->wq_cv);
    251 	}
    252 	mutex_exit(&wq->wq_lock);
    253 
    254 	kthread_exit(0);
    255 }
    256 
    257 static void
    258 linux_workqueue_timeout(void *cookie)
    259 {
    260 	struct delayed_work *const dw = cookie;
    261 	struct workqueue_struct *const wq = dw->work.work_queue;
    262 
    263 	KASSERT(wq != NULL);
    264 	mutex_enter(&wq->wq_lock);
    265 	switch (dw->dw_state) {
    266 	case DELAYED_WORK_IDLE:
    267 		panic("delayed work callout uninitialized: %p", dw);
    268 	case DELAYED_WORK_SCHEDULED:
    269 		dw->dw_state = DELAYED_WORK_IDLE;
    270 		callout_destroy(&dw->dw_callout);
    271 		TAILQ_REMOVE(&wq->wq_delayed, dw, dw_entry);
    272 		TAILQ_INSERT_TAIL(&wq->wq_queue, &dw->work, work_entry);
    273 		cv_broadcast(&wq->wq_cv);
    274 		break;
    275 	case DELAYED_WORK_RESCHEDULED:
    276 		dw->dw_state = DELAYED_WORK_SCHEDULED;
    277 		break;
    278 	case DELAYED_WORK_CANCELLED:
    279 		dw->dw_state = DELAYED_WORK_IDLE;
    280 		callout_destroy(&dw->dw_callout);
    281 		TAILQ_REMOVE(&wq->wq_delayed, dw, dw_entry);
    282 		break;
    283 	default:
    284 		panic("delayed work callout in bad state: %p", dw);
    285 	}
    286 	mutex_exit(&wq->wq_lock);
    287 }
    288 
    289 struct work_struct *
    290 current_work(void)
    291 {
    292 	struct workqueue_struct *wq = lwp_getspecific(workqueue_key);
    293 
    294 	/* If we're not a workqueue thread, then there's no work.  */
    295 	if (wq == NULL)
    296 		return NULL;
    297 
    298 	/*
    299 	 * Otherwise, this should be possible only while work is in
    300 	 * progress.  Return the current work item.
    301 	 */
    302 	KASSERT(wq->wq_current_work != NULL);
    303 	return wq->wq_current_work;
    304 }
    305 
    306 /*
    308  * Work
    309  */
    310 
    311 void
    312 INIT_WORK(struct work_struct *work, void (*fn)(struct work_struct *))
    313 {
    314 
    315 	work->work_queue = NULL;
    316 	work->func = fn;
    317 }
    318 
    319 bool
    320 schedule_work(struct work_struct *work)
    321 {
    322 
    323 	return queue_work(system_wq, work);
    324 }
    325 
    326 bool
    327 queue_work(struct workqueue_struct *wq, struct work_struct *work)
    328 {
    329 	struct workqueue_struct *wq0;
    330 	bool newly_queued;
    331 
    332 	KASSERT(wq != NULL);
    333 
    334 	mutex_enter(&wq->wq_lock);
    335 	if (__predict_true((wq0 = atomic_cas_ptr(&work->work_queue, NULL, wq))
    336 		== NULL)) {
    337 		TAILQ_INSERT_TAIL(&wq->wq_queue, work, work_entry);
    338 		newly_queued = true;
    339 	} else {
    340 		KASSERT(wq0 == wq);
    341 		newly_queued = false;
    342 	}
    343 	mutex_exit(&wq->wq_lock);
    344 
    345 	return newly_queued;
    346 }
    347 
    348 bool
    349 cancel_work(struct work_struct *work)
    350 {
    351 	struct workqueue_struct *wq;
    352 	bool cancelled_p = false;
    353 
    354 	wq = work->work_queue;
    355 	mutex_enter(&wq->wq_lock);
    356 	if (__predict_false(work->work_queue != wq)) {
    357 		cancelled_p = false;
    358 	} else if (wq->wq_current_work == work) {
    359 		cancelled_p = false;
    360 	} else {
    361 		TAILQ_REMOVE(&wq->wq_queue, work, work_entry);
    362 		cancelled_p = true;
    363 	}
    364 	mutex_exit(&wq->wq_lock);
    365 
    366 	return cancelled_p;
    367 }
    368 
    369 bool
    370 cancel_work_sync(struct work_struct *work)
    371 {
    372 	struct workqueue_struct *wq;
    373 	bool cancelled_p = false;
    374 
    375 	wq = work->work_queue;
    376 	mutex_enter(&wq->wq_lock);
    377 	if (__predict_false(work->work_queue != wq)) {
    378 		cancelled_p = false;
    379 	} else if (wq->wq_current_work == work) {
    380 		do {
    381 			cv_wait(&wq->wq_cv, &wq->wq_lock);
    382 		} while (wq->wq_current_work == work);
    383 		cancelled_p = false;
    384 	} else {
    385 		TAILQ_REMOVE(&wq->wq_queue, work, work_entry);
    386 		cancelled_p = true;
    387 	}
    388 	mutex_exit(&wq->wq_lock);
    389 
    390 	return cancelled_p;
    391 }
    392 
    393 /*
    395  * Delayed work
    396  */
    397 
    398 void
    399 INIT_DELAYED_WORK(struct delayed_work *dw, void (*fn)(struct work_struct *))
    400 {
    401 
    402 	INIT_WORK(&dw->work, fn);
    403 	dw->dw_state = DELAYED_WORK_IDLE;
    404 
    405 	/*
    406 	 * Defer callout_init until we are going to schedule the
    407 	 * callout, which can then callout_destroy it, because
    408 	 * otherwise since there's no DESTROY_DELAYED_WORK or anything
    409 	 * we have no opportunity to call callout_destroy.
    410 	 */
    411 }
    412 
    413 bool
    414 schedule_delayed_work(struct delayed_work *dw, unsigned long ticks)
    415 {
    416 
    417 	return queue_delayed_work(system_wq, dw, ticks);
    418 }
    419 
    420 static void
    421 queue_delayed_work_anew(struct workqueue_struct *wq, struct delayed_work *dw,
    422     unsigned long ticks)
    423 {
    424 
    425 	KASSERT(mutex_owned(&wq->wq_lock));
    426 	KASSERT(dw->work.work_queue == wq);
    427 	KASSERT((dw->dw_state == DELAYED_WORK_IDLE) ||
    428 	    (dw->dw_state == DELAYED_WORK_SCHEDULED));
    429 
    430 	if (ticks == 0) {
    431 		if (dw->dw_state == DELAYED_WORK_SCHEDULED) {
    432 			callout_destroy(&dw->dw_callout);
    433 			TAILQ_REMOVE(&wq->wq_delayed, dw, dw_entry);
    434 		} else {
    435 			KASSERT(dw->dw_state == DELAYED_WORK_IDLE);
    436 		}
    437 		TAILQ_INSERT_TAIL(&wq->wq_queue, &dw->work, work_entry);
    438 		dw->dw_state = DELAYED_WORK_IDLE;
    439 	} else {
    440 		if (dw->dw_state == DELAYED_WORK_IDLE) {
    441 			callout_init(&dw->dw_callout, CALLOUT_MPSAFE);
    442 			callout_reset(&dw->dw_callout, MIN(INT_MAX, ticks),
    443 			    &linux_workqueue_timeout, dw);
    444 			TAILQ_INSERT_HEAD(&wq->wq_delayed, dw, dw_entry);
    445 		} else {
    446 			KASSERT(dw->dw_state == DELAYED_WORK_SCHEDULED);
    447 		}
    448 		dw->dw_state = DELAYED_WORK_SCHEDULED;
    449 	}
    450 }
    451 
    452 bool
    453 queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dw,
    454     unsigned long ticks)
    455 {
    456 	struct workqueue_struct *wq0;
    457 	bool newly_queued;
    458 
    459 	mutex_enter(&wq->wq_lock);
    460 	if (__predict_true((wq0 = atomic_cas_ptr(&dw->work.work_queue, NULL,
    461 			wq)) == NULL)) {
    462 		KASSERT(dw->dw_state == DELAYED_WORK_IDLE);
    463 		queue_delayed_work_anew(wq, dw, ticks);
    464 		newly_queued = true;
    465 	} else {
    466 		KASSERT(wq0 == wq);
    467 		newly_queued = false;
    468 	}
    469 	mutex_exit(&wq->wq_lock);
    470 
    471 	return newly_queued;
    472 }
    473 
    474 bool
    475 mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dw,
    476     unsigned long ticks)
    477 {
    478 	struct workqueue_struct *wq0;
    479 	bool timer_modified;
    480 
    481 	mutex_enter(&wq->wq_lock);
    482 	if ((wq0 = atomic_cas_ptr(&dw->work.work_queue, NULL, wq)) == NULL) {
    483 		KASSERT(dw->dw_state == DELAYED_WORK_IDLE);
    484 		queue_delayed_work_anew(wq, dw, ticks);
    485 		timer_modified = false;
    486 	} else {
    487 		KASSERT(wq0 == wq);
    488 		switch (dw->dw_state) {
    489 		case DELAYED_WORK_IDLE:
    490 			if (wq->wq_current_work != &dw->work) {
    491 				/* Work is queued, but hasn't started yet.  */
    492 				TAILQ_REMOVE(&wq->wq_queue, &dw->work,
    493 				    work_entry);
    494 				queue_delayed_work_anew(wq, dw, ticks);
    495 				timer_modified = true;
    496 			} else {
    497 				/*
    498 				 * Too late.  Queue it anew.  If that
    499 				 * would skip the callout because it's
    500 				 * immediate, notify the workqueue.
    501 				 */
    502 				wq->wq_requeued = ticks == 0;
    503 				queue_delayed_work_anew(wq, dw, ticks);
    504 				timer_modified = false;
    505 			}
    506 			break;
    507 		case DELAYED_WORK_SCHEDULED:
    508 			if (callout_stop(&dw->dw_callout)) {
    509 				/*
    510 				 * Too late to stop, but we got in
    511 				 * before the callout acquired the
    512 				 * lock.  Reschedule it and tell it
    513 				 * we've done so.
    514 				 */
    515 				dw->dw_state = DELAYED_WORK_RESCHEDULED;
    516 				callout_schedule(&dw->dw_callout,
    517 				    MIN(INT_MAX, ticks));
    518 			} else {
    519 				/* Stopped it.  Queue it anew.  */
    520 				queue_delayed_work_anew(wq, dw, ticks);
    521 			}
    522 			timer_modified = true;
    523 			break;
    524 		case DELAYED_WORK_RESCHEDULED:
    525 		case DELAYED_WORK_CANCELLED:
    526 			/*
    527 			 * Someone modified the timer _again_, or
    528 			 * cancelled it, after the callout started but
    529 			 * before the poor thing even had a chance to
    530 			 * acquire the lock.  Just reschedule it once
    531 			 * more.
    532 			 */
    533 			callout_schedule(&dw->dw_callout, MIN(INT_MAX, ticks));
    534 			dw->dw_state = DELAYED_WORK_RESCHEDULED;
    535 			timer_modified = true;
    536 			break;
    537 		default:
    538 			panic("invalid delayed work state: %d",
    539 			    dw->dw_state);
    540 		}
    541 	}
    542 	mutex_exit(&wq->wq_lock);
    543 
    544 	return timer_modified;
    545 }
    546 
    547 bool
    548 cancel_delayed_work(struct delayed_work *dw)
    549 {
    550 	struct workqueue_struct *wq;
    551 	bool cancelled_p;
    552 
    553 	wq = dw->work.work_queue;
    554 	mutex_enter(&wq->wq_lock);
    555 	if (__predict_false(dw->work.work_queue != wq)) {
    556 		cancelled_p = false;
    557 	} else {
    558 		switch (dw->dw_state) {
    559 		case DELAYED_WORK_IDLE:
    560 			if (wq->wq_current_work == &dw->work) {
    561 				/* Too late, it's already running.  */
    562 				cancelled_p = false;
    563 			} else {
    564 				/* Got in before it started.  Remove it.  */
    565 				TAILQ_REMOVE(&wq->wq_queue, &dw->work,
    566 				    work_entry);
    567 				cancelled_p = true;
    568 			}
    569 			break;
    570 		case DELAYED_WORK_SCHEDULED:
    571 		case DELAYED_WORK_RESCHEDULED:
    572 		case DELAYED_WORK_CANCELLED:
    573 			if (callout_stop(&dw->dw_callout)) {
    574 				/*
    575 				 * Too late to stop, but we got in
    576 				 * before the callout acquired the
    577 				 * lock.  Tell it to give up.
    578 				 */
    579 				dw->dw_state = DELAYED_WORK_CANCELLED;
    580 			} else {
    581 				/* Stopped it.  Kill it.  */
    582 				callout_destroy(&dw->dw_callout);
    583 				TAILQ_REMOVE(&wq->wq_delayed, dw, dw_entry);
    584 				dw->dw_state = DELAYED_WORK_IDLE;
    585 			}
    586 			cancelled_p = true;
    587 		default:
    588 			panic("invalid delayed work state: %d",
    589 			    dw->dw_state);
    590 		}
    591 	}
    592 	mutex_exit(&wq->wq_lock);
    593 
    594 	return cancelled_p;
    595 }
    596 
    597 bool
    598 cancel_delayed_work_sync(struct delayed_work *dw)
    599 {
    600 	struct workqueue_struct *wq;
    601 	bool cancelled_p;
    602 
    603 	wq = dw->work.work_queue;
    604 	mutex_enter(&wq->wq_lock);
    605 	if (__predict_false(dw->work.work_queue != wq)) {
    606 		cancelled_p = false;
    607 	} else {
    608 retry:		switch (dw->dw_state) {
    609 		case DELAYED_WORK_IDLE:
    610 			if (wq->wq_current_work == &dw->work) {
    611 				/* Too late, it's already running.  Wait.  */
    612 				do {
    613 					cv_wait(&wq->wq_cv, &wq->wq_lock);
    614 				} while (wq->wq_current_work == &dw->work);
    615 				cancelled_p = false;
    616 			} else {
    617 				/* Got in before it started.  Remove it.  */
    618 				TAILQ_REMOVE(&wq->wq_queue, &dw->work,
    619 				    work_entry);
    620 				cancelled_p = true;
    621 			}
    622 			break;
    623 		case DELAYED_WORK_SCHEDULED:
    624 		case DELAYED_WORK_RESCHEDULED:
    625 		case DELAYED_WORK_CANCELLED:
    626 			/*
    627 			 * If it has started, tell it to stop, and wait
    628 			 * for it to complete.  We drop the lock, so by
    629 			 * the time the callout has completed, we must
    630 			 * review the state again.
    631 			 */
    632 			dw->dw_state = DELAYED_WORK_CANCELLED;
    633 			callout_halt(&dw->dw_callout, &wq->wq_lock);
    634 			goto retry;
    635 		default:
    636 			panic("invalid delayed work state: %d",
    637 			    dw->dw_state);
    638 		}
    639 	}
    640 	mutex_exit(&wq->wq_lock);
    641 
    642 	return cancelled_p;
    643 }
    644 
    645 /*
    647  * Flush
    648  */
    649 
    650 void
    651 flush_scheduled_work(void)
    652 {
    653 
    654 	flush_workqueue(system_wq);
    655 }
    656 
    657 void
    658 flush_workqueue(struct workqueue_struct *wq)
    659 {
    660 	uint64_t gen;
    661 
    662 	mutex_enter(&wq->wq_lock);
    663 	gen = wq->wq_gen;
    664 	do {
    665 		cv_wait(&wq->wq_cv, &wq->wq_lock);
    666 	} while (gen == wq->wq_gen);
    667 	mutex_exit(&wq->wq_lock);
    668 }
    669 
    670 bool
    671 flush_work(struct work_struct *work)
    672 {
    673 	struct workqueue_struct *const wq = work->work_queue;
    674 
    675 	if (wq == NULL)
    676 		return false;
    677 
    678 	flush_workqueue(wq);
    679 	return true;
    680 }
    681 
    682 bool
    683 flush_delayed_work(struct delayed_work *dw)
    684 {
    685 	struct workqueue_struct *const wq = dw->work.work_queue;
    686 	bool do_flush = false;
    687 
    688 	if (wq == NULL)
    689 		return false;
    690 
    691 	mutex_enter(&wq->wq_lock);
    692 	if (__predict_false(dw->work.work_queue != wq)) {
    693 		do_flush = true;
    694 	} else {
    695 retry:		switch (dw->dw_state) {
    696 		case DELAYED_WORK_IDLE:
    697 			if (wq->wq_current_work != &dw->work) {
    698 				TAILQ_REMOVE(&wq->wq_queue, &dw->work,
    699 				    work_entry);
    700 			} else {
    701 				do_flush = true;
    702 			}
    703 			break;
    704 		case DELAYED_WORK_SCHEDULED:
    705 		case DELAYED_WORK_RESCHEDULED:
    706 		case DELAYED_WORK_CANCELLED:
    707 			dw->dw_state = DELAYED_WORK_CANCELLED;
    708 			callout_halt(&dw->dw_callout, &wq->wq_lock);
    709 			goto retry;
    710 		default:
    711 			panic("invalid delayed work state: %d",
    712 			    dw->dw_state);
    713 		}
    714 	}
    715 	mutex_exit(&wq->wq_lock);
    716 
    717 	if (do_flush)
    718 		flush_workqueue(wq);
    719 
    720 	return true;
    721 }
    722