aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 42fa9ad0a810..f2c5638bb5ab 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -242,10 +242,10 @@ struct workqueue_struct {
242 242
243 int nr_drainers; /* W: drain in progress */ 243 int nr_drainers; /* W: drain in progress */
244 int saved_max_active; /* W: saved cwq max_active */ 244 int saved_max_active; /* W: saved cwq max_active */
245 const char *name; /* I: workqueue name */
246#ifdef CONFIG_LOCKDEP 245#ifdef CONFIG_LOCKDEP
247 struct lockdep_map lockdep_map; 246 struct lockdep_map lockdep_map;
248#endif 247#endif
248 char name[]; /* I: workqueue name */
249}; 249};
250 250
251struct workqueue_struct *system_wq __read_mostly; 251struct workqueue_struct *system_wq __read_mostly;
@@ -253,11 +253,13 @@ struct workqueue_struct *system_long_wq __read_mostly;
253struct workqueue_struct *system_nrt_wq __read_mostly; 253struct workqueue_struct *system_nrt_wq __read_mostly;
254struct workqueue_struct *system_unbound_wq __read_mostly; 254struct workqueue_struct *system_unbound_wq __read_mostly;
255struct workqueue_struct *system_freezable_wq __read_mostly; 255struct workqueue_struct *system_freezable_wq __read_mostly;
256struct workqueue_struct *system_nrt_freezable_wq __read_mostly;
256EXPORT_SYMBOL_GPL(system_wq); 257EXPORT_SYMBOL_GPL(system_wq);
257EXPORT_SYMBOL_GPL(system_long_wq); 258EXPORT_SYMBOL_GPL(system_long_wq);
258EXPORT_SYMBOL_GPL(system_nrt_wq); 259EXPORT_SYMBOL_GPL(system_nrt_wq);
259EXPORT_SYMBOL_GPL(system_unbound_wq); 260EXPORT_SYMBOL_GPL(system_unbound_wq);
260EXPORT_SYMBOL_GPL(system_freezable_wq); 261EXPORT_SYMBOL_GPL(system_freezable_wq);
262EXPORT_SYMBOL_GPL(system_nrt_freezable_wq);
261 263
262#define CREATE_TRACE_POINTS 264#define CREATE_TRACE_POINTS
263#include <trace/events/workqueue.h> 265#include <trace/events/workqueue.h>
@@ -2954,14 +2956,29 @@ static int wq_clamp_max_active(int max_active, unsigned int flags,
2954 return clamp_val(max_active, 1, lim); 2956 return clamp_val(max_active, 1, lim);
2955} 2957}
2956 2958
2957struct workqueue_struct *__alloc_workqueue_key(const char *name, 2959struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
2958 unsigned int flags, 2960 unsigned int flags,
2959 int max_active, 2961 int max_active,
2960 struct lock_class_key *key, 2962 struct lock_class_key *key,
2961 const char *lock_name) 2963 const char *lock_name, ...)
2962{ 2964{
2965 va_list args, args1;
2963 struct workqueue_struct *wq; 2966 struct workqueue_struct *wq;
2964 unsigned int cpu; 2967 unsigned int cpu;
2968 size_t namelen;
2969
2970 /* determine namelen, allocate wq and format name */
2971 va_start(args, lock_name);
2972 va_copy(args1, args);
2973 namelen = vsnprintf(NULL, 0, fmt, args) + 1;
2974
2975 wq = kzalloc(sizeof(*wq) + namelen, GFP_KERNEL);
2976 if (!wq)
2977 goto err;
2978
2979 vsnprintf(wq->name, namelen, fmt, args1);
2980 va_end(args);
2981 va_end(args1);
2965 2982
2966 /* 2983 /*
2967 * Workqueues which may be used during memory reclaim should 2984 * Workqueues which may be used during memory reclaim should
@@ -2978,12 +2995,9 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name,
2978 flags |= WQ_HIGHPRI; 2995 flags |= WQ_HIGHPRI;
2979 2996
2980 max_active = max_active ?: WQ_DFL_ACTIVE; 2997 max_active = max_active ?: WQ_DFL_ACTIVE;
2981 max_active = wq_clamp_max_active(max_active, flags, name); 2998 max_active = wq_clamp_max_active(max_active, flags, wq->name);
2982
2983 wq = kzalloc(sizeof(*wq), GFP_KERNEL);
2984 if (!wq)
2985 goto err;
2986 2999
3000 /* init wq */
2987 wq->flags = flags; 3001 wq->flags = flags;
2988 wq->saved_max_active = max_active; 3002 wq->saved_max_active = max_active;
2989 mutex_init(&wq->flush_mutex); 3003 mutex_init(&wq->flush_mutex);
@@ -2991,7 +3005,6 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name,
2991 INIT_LIST_HEAD(&wq->flusher_queue); 3005 INIT_LIST_HEAD(&wq->flusher_queue);
2992 INIT_LIST_HEAD(&wq->flusher_overflow); 3006 INIT_LIST_HEAD(&wq->flusher_overflow);
2993 3007
2994 wq->name = name;
2995 lockdep_init_map(&wq->lockdep_map, lock_name, key, 0); 3008 lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
2996 INIT_LIST_HEAD(&wq->list); 3009 INIT_LIST_HEAD(&wq->list);
2997 3010
@@ -3020,7 +3033,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name,
3020 if (!rescuer) 3033 if (!rescuer)
3021 goto err; 3034 goto err;
3022 3035
3023 rescuer->task = kthread_create(rescuer_thread, wq, "%s", name); 3036 rescuer->task = kthread_create(rescuer_thread, wq, "%s",
3037 wq->name);
3024 if (IS_ERR(rescuer->task)) 3038 if (IS_ERR(rescuer->task))
3025 goto err; 3039 goto err;
3026 3040
@@ -3821,8 +3835,11 @@ static int __init init_workqueues(void)
3821 WQ_UNBOUND_MAX_ACTIVE); 3835 WQ_UNBOUND_MAX_ACTIVE);
3822 system_freezable_wq = alloc_workqueue("events_freezable", 3836 system_freezable_wq = alloc_workqueue("events_freezable",
3823 WQ_FREEZABLE, 0); 3837 WQ_FREEZABLE, 0);
3838 system_nrt_freezable_wq = alloc_workqueue("events_nrt_freezable",
3839 WQ_NON_REENTRANT | WQ_FREEZABLE, 0);
3824 BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || 3840 BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
3825 !system_unbound_wq || !system_freezable_wq); 3841 !system_unbound_wq || !system_freezable_wq ||
3842 !system_nrt_freezable_wq);
3826 return 0; 3843 return 0;
3827} 3844}
3828early_initcall(init_workqueues); 3845early_initcall(init_workqueues);