diff options
author | Tejun Heo <tj@kernel.org> | 2013-01-18 17:05:56 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-01-18 17:05:56 -0500 |
commit | 84b233adcca3cacd5cfa8013a5feda7a3db4a9af (patch) | |
tree | 3d1f4a7f5f1d27dc08bb661691fd1470acf497a5 | |
parent | 2eaebdb33e1911c0cf3d44fd3596c42c6f502fab (diff) |
workqueue: implement current_is_async()
This function queries whether %current is an async worker executing an
async item. This will be used to implement warning on synchronous
request_module() from async workers.
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | include/linux/async.h | 1 | ||||
-rw-r--r-- | kernel/async.c | 14 | ||||
-rw-r--r-- | kernel/workqueue_internal.h | 11 |
3 files changed, 26 insertions, 0 deletions
diff --git a/include/linux/async.h b/include/linux/async.h index 7a24fe9b44b4..345169cfa304 100644 --- a/include/linux/async.h +++ b/include/linux/async.h | |||
@@ -52,4 +52,5 @@ extern void async_synchronize_full_domain(struct async_domain *domain); | |||
52 | extern void async_synchronize_cookie(async_cookie_t cookie); | 52 | extern void async_synchronize_cookie(async_cookie_t cookie); |
53 | extern void async_synchronize_cookie_domain(async_cookie_t cookie, | 53 | extern void async_synchronize_cookie_domain(async_cookie_t cookie, |
54 | struct async_domain *domain); | 54 | struct async_domain *domain); |
55 | extern bool current_is_async(void); | ||
55 | #endif | 56 | #endif |
diff --git a/kernel/async.c b/kernel/async.c index 9d3118384858..d9bf2a9b5cee 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
@@ -57,6 +57,8 @@ asynchronous and synchronous parts of the kernel. | |||
57 | #include <linux/slab.h> | 57 | #include <linux/slab.h> |
58 | #include <linux/workqueue.h> | 58 | #include <linux/workqueue.h> |
59 | 59 | ||
60 | #include "workqueue_internal.h" | ||
61 | |||
60 | static async_cookie_t next_cookie = 1; | 62 | static async_cookie_t next_cookie = 1; |
61 | 63 | ||
62 | #define MAX_WORK 32768 | 64 | #define MAX_WORK 32768 |
@@ -337,3 +339,15 @@ void async_synchronize_cookie(async_cookie_t cookie) | |||
337 | async_synchronize_cookie_domain(cookie, &async_running); | 339 | async_synchronize_cookie_domain(cookie, &async_running); |
338 | } | 340 | } |
339 | EXPORT_SYMBOL_GPL(async_synchronize_cookie); | 341 | EXPORT_SYMBOL_GPL(async_synchronize_cookie); |
342 | |||
343 | /** | ||
344 | * current_is_async - is %current an async worker task? | ||
345 | * | ||
346 | * Returns %true if %current is an async worker task. | ||
347 | */ | ||
348 | bool current_is_async(void) | ||
349 | { | ||
350 | struct worker *worker = current_wq_worker(); | ||
351 | |||
352 | return worker && worker->current_func == async_run_entry_fn; | ||
353 | } | ||
diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h index 02549fa04587..cc35e7e62091 100644 --- a/kernel/workqueue_internal.h +++ b/kernel/workqueue_internal.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #define _KERNEL_WORKQUEUE_INTERNAL_H | 8 | #define _KERNEL_WORKQUEUE_INTERNAL_H |
9 | 9 | ||
10 | #include <linux/workqueue.h> | 10 | #include <linux/workqueue.h> |
11 | #include <linux/kthread.h> | ||
11 | 12 | ||
12 | struct global_cwq; | 13 | struct global_cwq; |
13 | struct worker_pool; | 14 | struct worker_pool; |
@@ -44,6 +45,16 @@ struct worker { | |||
44 | struct workqueue_struct *rescue_wq; /* I: the workqueue to rescue */ | 45 | struct workqueue_struct *rescue_wq; /* I: the workqueue to rescue */ |
45 | }; | 46 | }; |
46 | 47 | ||
48 | /** | ||
49 | * current_wq_worker - return struct worker if %current is a workqueue worker | ||
50 | */ | ||
51 | static inline struct worker *current_wq_worker(void) | ||
52 | { | ||
53 | if (current->flags & PF_WQ_WORKER) | ||
54 | return kthread_data(current); | ||
55 | return NULL; | ||
56 | } | ||
57 | |||
47 | /* | 58 | /* |
48 | * Scheduler hooks for concurrency managed workqueue. Only to be used from | 59 | * Scheduler hooks for concurrency managed workqueue. Only to be used from |
49 | * sched.c and workqueue.c. | 60 | * sched.c and workqueue.c. |