Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_work.c
Show All 25 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <linux/workqueue.h> | #include <linux/workqueue.h> | ||||
#include <linux/wait.h> | #include <linux/wait.h> | ||||
#include <linux/compat.h> | #include <linux/compat.h> | ||||
#include <linux/spinlock.h> | #include <linux/spinlock.h> | ||||
#include <linux/rcupdate.h> | |||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
/* | /* | ||||
* Define all work struct states | * Define all work struct states | ||||
*/ | */ | ||||
enum { | enum { | ||||
WORK_ST_IDLE, /* idle - not started */ | WORK_ST_IDLE, /* idle - not started */ | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | case WORK_ST_CANCEL: | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case WORK_ST_IDLE: | case WORK_ST_IDLE: | ||||
work->work_queue = wq; | work->work_queue = wq; | ||||
taskqueue_enqueue(wq->taskqueue, &work->work_task); | taskqueue_enqueue(wq->taskqueue, &work->work_task); | ||||
return (true); | return (true); | ||||
default: | default: | ||||
return (false); /* already on a queue */ | return (false); /* already on a queue */ | ||||
} | } | ||||
} | |||||
/* | |||||
* Callback func for linux_queue_rcu_work | |||||
*/ | |||||
static void | |||||
rcu_work_func(struct rcu_head *rcu) | |||||
{ | |||||
struct rcu_work *rwork; | |||||
rwork = container_of(rcu, struct rcu_work, rcu); | |||||
linux_queue_work_on(WORK_CPU_UNBOUND, rwork->wq, &rwork->work); | |||||
hselasky: I think you should pass WORK_CPU_UNBOUND instead of 0 there, even though the argument is not… | |||||
} | |||||
/* | |||||
* This function queue a work after a grace period | |||||
* If the work was already pending it returns false, | |||||
* if not it calls call_rcu and returns true. | |||||
*/ | |||||
bool | |||||
linux_queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork) | |||||
{ | |||||
if (!linux_work_pending(&rwork->work)) { | |||||
rwork->wq = wq; | |||||
linux_call_rcu(RCU_TYPE_REGULAR, &rwork->rcu, rcu_work_func); | |||||
return (true); | |||||
} | |||||
return (false); | |||||
} | |||||
/* | |||||
* This function waits for the last execution of a work and then | |||||
* flush the work. | |||||
* It returns true if the work was pending and we waited, it returns | |||||
* false otherwise. | |||||
*/ | |||||
bool | |||||
linux_flush_rcu_work(struct rcu_work *rwork) | |||||
{ | |||||
Done Inline ActionsInsert empty line at top of function when no local variables - BSD style. hselasky: Insert empty line at top of function when no local variables - BSD style. | |||||
if (linux_work_pending(&rwork->work)) { | |||||
linux_rcu_barrier(RCU_TYPE_REGULAR); | |||||
linux_flush_work(&rwork->work); | |||||
return (true); | |||||
} | |||||
Done Inline ActionsRemove this empty line. hselasky: Remove this empty line. | |||||
return (linux_flush_work(&rwork->work)); | |||||
} | } | ||||
/* | /* | ||||
* This function queues the given work structure on the given | * This function queues the given work structure on the given | ||||
* workqueue after a given delay in ticks. It returns non-zero if the | * workqueue after a given delay in ticks. It returns non-zero if the | ||||
* work was successfully [re-]queued. Else the work is already pending | * work was successfully [re-]queued. Else the work is already pending | ||||
* for completion. | * for completion. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 474 Lines • Show Last 20 Lines |
I think you should pass WORK_CPU_UNBOUND instead of 0 there, even though the argument is not used.