Commit 0de4cb4
workqueue: fix devm_alloc_workqueue() va_list misuse
devm_alloc_workqueue() built a va_list and passed it as a single
positional argument to the variadic alloc_workqueue() macro:
va_start(args, max_active);
wq = alloc_workqueue(fmt, flags, max_active, args);
va_end(args);
C does not allow forwarding a va_list through a ... parameter.
alloc_workqueue() expands to alloc_workqueue_noprof(), which runs
its own va_start() over its ... params, so the inner
vsnprintf(wq->name, sizeof(wq->name), fmt, args) in
__alloc_workqueue() received the outer va_list object as the first
variadic slot rather than the caller's actual format arguments.
Add a new static helper alloc_workqueue_va() that wraps
__alloc_workqueue() and runs wq_init_lockdep() on success, and
fold both alloc_workqueue_noprof() and devm_alloc_workqueue_noprof()
onto it as suggested by Tejun.
The wq_init_lockdep() step is required on the devm path
too, otherwise __flush_workqueue()'s on-stack
COMPLETION_INITIALIZER_ONSTACK_MAP would NULL-deref wq->lockdep_map.
No caller changes are required. devm_alloc_ordered_workqueue() is
a macro forwarding to devm_alloc_workqueue() and inherits the fix.
Two in-tree callers actively trigger the broken path on every probe:
drivers/power/supply/mt6370-charger.c:889
drivers/power/supply/max77705_charger.c:649
both of which use devm_alloc_ordered_workqueue(dev, "%s", 0,
dev_name(dev)).
A standalone reproducer module is available at[1].
Link: https://github.com/leitao/debug/blob/main/workqueue/valist/wq_va_test.c [1]
Fixes: 1dfc9d6 ("workqueue: devres: Add device-managed allocate workqueue")
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Tejun Heo <tj@kernel.org>1 parent dca922e commit 0de4cb4
2 files changed
Lines changed: 23 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
534 | 534 | | |
535 | 535 | | |
536 | 536 | | |
537 | | - | |
538 | | - | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
539 | 541 | | |
540 | 542 | | |
541 | 543 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5906 | 5906 | | |
5907 | 5907 | | |
5908 | 5908 | | |
| 5909 | + | |
| 5910 | + | |
| 5911 | + | |
| 5912 | + | |
| 5913 | + | |
| 5914 | + | |
| 5915 | + | |
| 5916 | + | |
| 5917 | + | |
| 5918 | + | |
| 5919 | + | |
| 5920 | + | |
| 5921 | + | |
| 5922 | + | |
5909 | 5923 | | |
5910 | 5924 | | |
5911 | 5925 | | |
| |||
5915 | 5929 | | |
5916 | 5930 | | |
5917 | 5931 | | |
5918 | | - | |
| 5932 | + | |
5919 | 5933 | | |
5920 | | - | |
5921 | | - | |
5922 | | - | |
5923 | | - | |
5924 | 5934 | | |
5925 | 5935 | | |
5926 | 5936 | | |
| |||
5932 | 5942 | | |
5933 | 5943 | | |
5934 | 5944 | | |
5935 | | - | |
5936 | | - | |
| 5945 | + | |
| 5946 | + | |
5937 | 5947 | | |
5938 | 5948 | | |
5939 | 5949 | | |
5940 | 5950 | | |
5941 | 5951 | | |
5942 | 5952 | | |
5943 | | - | |
| 5953 | + | |
5944 | 5954 | | |
5945 | 5955 | | |
5946 | 5956 | | |
| |||
5951 | 5961 | | |
5952 | 5962 | | |
5953 | 5963 | | |
5954 | | - | |
| 5964 | + | |
5955 | 5965 | | |
5956 | 5966 | | |
5957 | 5967 | | |
| |||
0 commit comments