workqueue: Fixes for v7.1-rc2

- Fix devm_alloc_workqueue() passing a va_list as a positional arg to the
   variadic alloc_workqueue() macro, which garbled wq->name and skipped
   lockdep init on the devm path. Fold both noprof entry points onto a
   va_list helper. Also, annotate __printf(1, 0).
 -----BEGIN PGP SIGNATURE-----
 
 iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCafpheA4cdGpAa2VybmVs
 Lm9yZwAKCRCxYfJx3gVYGeBeAQDKq3XmN45CaOB76k9wSmRYqVgTSoWWTL83O8km
 nC2UhQEAiJBfqhP586coXyK6saaZX9QwFdPzTcB72LhZSAj13gQ=
 =Zixt
 -----END PGP SIGNATURE-----

Merge tag 'wq-for-7.1-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue fixes from Tejun Heo:

 - Fix devm_alloc_workqueue() passing a va_list as a positional arg to
   the variadic alloc_workqueue() macro, which garbled wq->name and
   skipped lockdep init on the devm path. Fold both noprof entry points
   onto a va_list helper.

   Also, annotate it using __printf(1, 0)

* tag 'wq-for-7.1-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: Annotate alloc_workqueue_va() with __printf(1, 0)
  workqueue: fix devm_alloc_workqueue() va_list misuse
This commit is contained in:
Linus Torvalds 2026-05-05 16:09:31 -07:00
commit 74fe02ce12
2 changed files with 24 additions and 11 deletions

View File

@ -534,8 +534,10 @@ alloc_workqueue_noprof(const char *fmt, unsigned int flags, int max_active, ...)
* Pointer to the allocated workqueue on success, %NULL on failure.
*/
__printf(2, 5) struct workqueue_struct *
devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags,
int max_active, ...);
devm_alloc_workqueue_noprof(struct device *dev, const char *fmt,
unsigned int flags, int max_active, ...);
#define devm_alloc_workqueue(...) \
alloc_hooks(devm_alloc_workqueue_noprof(__VA_ARGS__))
#ifdef CONFIG_LOCKDEP
/**

View File

@ -5906,6 +5906,21 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
return NULL;
}
__printf(1, 0)
static struct workqueue_struct *alloc_workqueue_va(const char *fmt,
unsigned int flags,
int max_active,
va_list args)
{
struct workqueue_struct *wq;
wq = __alloc_workqueue(fmt, flags, max_active, args);
if (wq)
wq_init_lockdep(wq);
return wq;
}
__printf(1, 4)
struct workqueue_struct *alloc_workqueue_noprof(const char *fmt,
unsigned int flags,
@ -5915,12 +5930,8 @@ struct workqueue_struct *alloc_workqueue_noprof(const char *fmt,
va_list args;
va_start(args, max_active);
wq = __alloc_workqueue(fmt, flags, max_active, args);
wq = alloc_workqueue_va(fmt, flags, max_active, args);
va_end(args);
if (!wq)
return NULL;
wq_init_lockdep(wq);
return wq;
}
@ -5932,15 +5943,15 @@ static void devm_workqueue_release(void *res)
}
__printf(2, 5) struct workqueue_struct *
devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags,
int max_active, ...)
devm_alloc_workqueue_noprof(struct device *dev, const char *fmt,
unsigned int flags, int max_active, ...)
{
struct workqueue_struct *wq;
va_list args;
int ret;
va_start(args, max_active);
wq = alloc_workqueue(fmt, flags, max_active, args);
wq = alloc_workqueue_va(fmt, flags, max_active, args);
va_end(args);
if (!wq)
return NULL;
@ -5951,7 +5962,7 @@ devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags,
return wq;
}
EXPORT_SYMBOL_GPL(devm_alloc_workqueue);
EXPORT_SYMBOL_GPL(devm_alloc_workqueue_noprof);
#ifdef CONFIG_LOCKDEP
__printf(1, 5)