aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-01-18 17:05:56 -0500
committerTejun Heo <tj@kernel.org>2013-01-18 17:05:56 -0500
commit84b233adcca3cacd5cfa8013a5feda7a3db4a9af (patch)
tree3d1f4a7f5f1d27dc08bb661691fd1470acf497a5
parent2eaebdb33e1911c0cf3d44fd3596c42c6f502fab (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.h1
-rw-r--r--kernel/async.c14
-rw-r--r--kernel/workqueue_internal.h11
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);
52extern void async_synchronize_cookie(async_cookie_t cookie); 52extern void async_synchronize_cookie(async_cookie_t cookie);
53extern void async_synchronize_cookie_domain(async_cookie_t cookie, 53extern void async_synchronize_cookie_domain(async_cookie_t cookie,
54 struct async_domain *domain); 54 struct async_domain *domain);
55extern 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
60static async_cookie_t next_cookie = 1; 62static 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}
339EXPORT_SYMBOL_GPL(async_synchronize_cookie); 341EXPORT_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 */
348bool 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
12struct global_cwq; 13struct global_cwq;
13struct worker_pool; 14struct 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 */
51static 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.