Calling va_start / va_end multiple times is undefined and causes problems with certain compiler / platforms. Change alloc_ordered_workqueue_lockdep_map to a macro and updated __alloc_workqueue to take a va_list argument.
Showing the changes to kernel/workqueue.c (1 of 2 files). Show all
Unified · Split
| @@ -5619,12 +5619,10 @@ static void wq_adjust_max_active(struct workqueue_struct *wq) · 5618 unmodified lines | |||
| 5619 | } while (activated); | 5619 | } while (activated); |
| 5620 | } | 5620 | } |
| 5621 | 5621 | ||
| 5622 | __printf(1, 4) | ||
| 5623 | static struct workqueue_struct *__alloc_workqueue(const char *fmt, | 5622 | static struct workqueue_struct *__alloc_workqueue(const char *fmt, |
| 5624 | unsigned int flags, | 5623 | unsigned int flags, |
| 5625 | int max_active, ...) | 5624 | int max_active, va_list args) |
| 5626 | { | 5625 | { |
| 5627 | va_list args; | ||
| 5628 | struct workqueue_struct *wq; | 5626 | struct workqueue_struct *wq; |
| 5629 | size_t wq_size; | 5627 | size_t wq_size; |
| 5630 | int name_len; | 5628 | int name_len; |
| @@ -5656,9 +5654,7 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, · 25 unmodified lines | |||
| 5656 | goto err_free_wq; | 5654 | goto err_free_wq; |
| 5657 | } | 5655 | } |
| 5658 | 5656 | ||
| 5659 | va_start(args, max_active); | ||
| 5660 | name_len = vsnprintf(wq->name, sizeof(wq->name), fmt, args); | 5657 | name_len = vsnprintf(wq->name, sizeof(wq->name), fmt, args); |
| 5661 | va_end(args); | ||
| 5662 | 5658 | ||
| 5663 | if (name_len >= WQ_NAME_LEN) | 5659 | if (name_len >= WQ_NAME_LEN) |
| 5664 | pr_warn_once("workqueue: name exceeds WQ_NAME_LEN. Truncating to: %s\n", | 5660 | pr_warn_once("workqueue: name exceeds WQ_NAME_LEN. Truncating to: %s\n", |