alloc_workqueue() currently expects the passed in @name pointer to remain accessible. This is inconvenient and a bit silly given that the whole wq is being dynamically allocated. This patch updates alloc_workqueue() and friends to take printf format string instead of opaque string and matching varargs at the end. The name is allocated together with the wq and formatted. alloc_ordered_workqueue() is converted to a macro to unify varargs handling with alloc_workqueue(), and, while at it, add comment to alloc_workqueue(). None of the current in-kernel users pass in string with '%' as constant name and this change shouldn't cause any problem. [akpm@linux-foundation.org: use __printf] Signed-off-by: Tejun Heo <tj@kernel.org> Suggested-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing the changes to kernel/workqueue.c (1 of 2 files). Show all
Unified · Split
| @@ -242,10 +242,10 @@ struct workqueue_struct { · 241 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | int nr_drainers; /* W: drain in progress */ |
| 244 | 244 | int saved_max_active; /* W: saved cwq max_active */ |
| 245 | − const char *name; /* I: workqueue name */ | |
| 246 | 245 | #ifdef CONFIG_LOCKDEP |
| 247 | 246 | struct lockdep_map lockdep_map; |
| 248 | 247 | #endif |
| 248 | + char name[]; /* I: workqueue name */ | |
| 249 | 249 | }; |
| 250 | 250 | |
| 251 | 251 | struct workqueue_struct *system_wq __read_mostly; |
| @@ -2954,14 +2954,29 @@ static int wq_clamp_max_active(int max_active, unsigned int flags, · 2702 unmodified lines | ||
| 2954 | 2954 | return clamp_val(max_active, 1, lim); |
| 2955 | 2955 | } |
| 2956 | 2956 | |
| 2957 | −struct workqueue_struct *__alloc_workqueue_key(const char *name, | |
| 2957 | +struct workqueue_struct *__alloc_workqueue_key(const char *fmt, | |
| 2958 | 2958 | unsigned int flags, |
| 2959 | 2959 | int max_active, |
| 2960 | 2960 | struct lock_class_key *key, |
| 2961 | − const char *lock_name) | |
| 2961 | + const char *lock_name, ...) | |
| 2962 | 2962 | { |
| 2963 | + va_list args, args1; | |
| 2963 | 2964 | struct workqueue_struct *wq; |
| 2964 | 2965 | unsigned int cpu; |
| 2966 | + size_t namelen; | |
| 2967 | + | |
| 2968 | + /* determine namelen, allocate wq and format name */ | |
| 2969 | + va_start(args, lock_name); | |
| 2970 | + va_copy(args1, args); | |
| 2971 | + namelen = vsnprintf(NULL, 0, fmt, args) + 1; | |
| 2972 | + | |
| 2973 | + wq = kzalloc(sizeof(*wq) + namelen, GFP_KERNEL); | |
| 2974 | + if (!wq) | |
| 2975 | + goto err; | |
| 2976 | + | |
| 2977 | + vsnprintf(wq->name, namelen, fmt, args1); | |
| 2978 | + va_end(args); | |
| 2979 | + va_end(args1); | |
| 2965 | 2980 | |
| 2966 | 2981 | /* |
| 2967 | 2982 | * Workqueues which may be used during memory reclaim should |
| @@ -2978,12 +2993,9 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, · 10 unmodified lines | ||
| 2978 | 2993 | flags |= WQ_HIGHPRI; |
| 2979 | 2994 | |
| 2980 | 2995 | max_active = max_active ?: WQ_DFL_ACTIVE; |
| 2981 | − max_active = wq_clamp_max_active(max_active, flags, name); | |
| 2982 | − | |
| 2983 | − wq = kzalloc(sizeof(*wq), GFP_KERNEL); | |
| 2984 | − if (!wq) | |
| 2985 | − goto err; | |
| 2996 | + max_active = wq_clamp_max_active(max_active, flags, wq->name); | |
| 2986 | 2997 | |
| 2998 | + /* init wq */ | |
| 2987 | 2999 | wq->flags = flags; |
| 2988 | 3000 | wq->saved_max_active = max_active; |
| 2989 | 3001 | mutex_init(&wq->flush_mutex); |
| @@ -2991,7 +3003,6 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, · 1 unmodified line | ||
| 2991 | 3003 | INIT_LIST_HEAD(&wq->flusher_queue); |
| 2992 | 3004 | INIT_LIST_HEAD(&wq->flusher_overflow); |
| 2993 | 3005 | |
| 2994 | − wq->name = name; | |
| 2995 | 3006 | lockdep_init_map(&wq->lockdep_map, lock_name, key, 0); |
| 2996 | 3007 | INIT_LIST_HEAD(&wq->list); |
| 2997 | 3008 | |
| @@ -3020,7 +3031,8 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, · 22 unmodified lines | ||
| 3020 | 3031 | if (!rescuer) |
| 3021 | 3032 | goto err; |
| 3022 | 3033 | |
| 3023 | − rescuer->task = kthread_create(rescuer_thread, wq, "%s", name); | |
| 3034 | + rescuer->task = kthread_create(rescuer_thread, wq, "%s", | |
| 3035 | + wq->name); | |
| 3024 | 3036 | if (IS_ERR(rescuer->task)) |
| 3025 | 3037 | goto err; |
| 3026 | 3038 | |