mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
LinuxKPI: Add cancel_work() function.
Cancel a work not waiting for it to finish. Sponsored by: Serenity Cyber Security, LLC Reviewed by: manu, kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D42811
This commit is contained in:
parent
64e30cba3f
commit
1b2f43a742
|
@ -188,6 +188,9 @@ do { \
|
|||
#define delayed_work_pending(dwork) \
|
||||
linux_work_pending(&(dwork)->work)
|
||||
|
||||
#define cancel_work(work) \
|
||||
linux_cancel_work(work)
|
||||
|
||||
#define cancel_delayed_work(dwork) \
|
||||
linux_cancel_delayed_work(dwork)
|
||||
|
||||
|
@ -243,6 +246,7 @@ extern void linux_destroy_workqueue(struct workqueue_struct *);
|
|||
extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *);
|
||||
extern bool linux_queue_delayed_work_on(int cpu, struct workqueue_struct *,
|
||||
struct delayed_work *, unsigned delay);
|
||||
extern bool linux_cancel_work(struct work_struct *);
|
||||
extern bool linux_cancel_delayed_work(struct delayed_work *);
|
||||
extern bool linux_cancel_work_sync(struct work_struct *);
|
||||
extern bool linux_cancel_delayed_work_sync(struct delayed_work *);
|
||||
|
|
|
@ -360,6 +360,38 @@ linux_delayed_work_timer_fn(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function cancels the given work structure in a
|
||||
* non-blocking fashion. It returns non-zero if the work was
|
||||
* successfully cancelled. Else the work may still be busy or already
|
||||
* cancelled.
|
||||
*/
|
||||
bool
|
||||
linux_cancel_work(struct work_struct *work)
|
||||
{
|
||||
static const uint8_t states[WORK_ST_MAX] __aligned(8) = {
|
||||
[WORK_ST_IDLE] = WORK_ST_IDLE, /* NOP */
|
||||
[WORK_ST_TIMER] = WORK_ST_TIMER, /* can't happen */
|
||||
[WORK_ST_TASK] = WORK_ST_IDLE, /* cancel */
|
||||
[WORK_ST_EXEC] = WORK_ST_EXEC, /* NOP */
|
||||
[WORK_ST_CANCEL] = WORK_ST_IDLE, /* can't happen */
|
||||
};
|
||||
struct taskqueue *tq;
|
||||
|
||||
MPASS(atomic_read(&work->state) != WORK_ST_TIMER);
|
||||
MPASS(atomic_read(&work->state) != WORK_ST_CANCEL);
|
||||
|
||||
switch (linux_update_state(&work->state, states)) {
|
||||
case WORK_ST_TASK:
|
||||
tq = work->work_queue->taskqueue;
|
||||
if (taskqueue_cancel(tq, &work->work_task, NULL) == 0)
|
||||
return (true);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function cancels the given work structure in a synchronous
|
||||
* fashion. It returns non-zero if the work was successfully
|
||||
|
|
Loading…
Reference in a new issue