diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 39 |
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 | ||
251 | struct workqueue_struct *system_wq __read_mostly; | 251 | struct workqueue_struct *system_wq __read_mostly; |
@@ -253,11 +253,13 @@ struct workqueue_struct *system_long_wq __read_mostly; | |||
253 | struct workqueue_struct *system_nrt_wq __read_mostly; | 253 | struct workqueue_struct *system_nrt_wq __read_mostly; |
254 | struct workqueue_struct *system_unbound_wq __read_mostly; | 254 | struct workqueue_struct *system_unbound_wq __read_mostly; |
255 | struct workqueue_struct *system_freezable_wq __read_mostly; | 255 | struct workqueue_struct *system_freezable_wq __read_mostly; |
256 | struct workqueue_struct *system_nrt_freezable_wq __read_mostly; | ||
256 | EXPORT_SYMBOL_GPL(system_wq); | 257 | EXPORT_SYMBOL_GPL(system_wq); |
257 | EXPORT_SYMBOL_GPL(system_long_wq); | 258 | EXPORT_SYMBOL_GPL(system_long_wq); |
258 | EXPORT_SYMBOL_GPL(system_nrt_wq); | 259 | EXPORT_SYMBOL_GPL(system_nrt_wq); |
259 | EXPORT_SYMBOL_GPL(system_unbound_wq); | 260 | EXPORT_SYMBOL_GPL(system_unbound_wq); |
260 | EXPORT_SYMBOL_GPL(system_freezable_wq); | 261 | EXPORT_SYMBOL_GPL(system_freezable_wq); |
262 | EXPORT_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 | ||
2957 | struct workqueue_struct *__alloc_workqueue_key(const char *name, | 2959 | struct 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 | } |
3828 | early_initcall(init_workqueues); | 3845 | early_initcall(init_workqueues); |