Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull workqueue updates from Tejun Heo:

- Prepare for defaulting to unbound workqueue. A separate branch was
created to ease pulling in from other trees but none of the
conversions have landed yet

- Memory allocation profiling support added

- Misc changes

* tag 'wq-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
workqueue: Use atomic_try_cmpxchg_relaxed() in tryinc_node_nr_active()
workqueue: Remove unused work_on_cpu_safe
workqueue: Add new WQ_PERCPU flag
workqueue: Add system_percpu_wq and system_dfl_wq
workqueue: Basic memory allocation profiling support
workqueue: fix opencoded cpumask_next_and_wrap() in wq_select_unbound_cpu()

+44 -70
+6
Documentation/core-api/workqueue.rst
··· 183 183 BH work items cannot sleep. All other features such as delayed queueing, 184 184 flushing and canceling are supported. 185 185 186 + ``WQ_PERCPU`` 187 + Work items queued to a per-cpu wq are bound to a specific CPU. 188 + This flag is the right choice when cpu locality is important. 189 + 190 + This flag is the complement of ``WQ_UNBOUND``. 191 + 186 192 ``WQ_UNBOUND`` 187 193 Work items queued to an unbound wq are served by the special 188 194 worker-pools which host workers which are not bound to any
+14 -20
include/linux/workqueue.h
··· 6 6 #ifndef _LINUX_WORKQUEUE_H 7 7 #define _LINUX_WORKQUEUE_H 8 8 9 + #include <linux/alloc_tag.h> 9 10 #include <linux/timer.h> 10 11 #include <linux/linkage.h> 11 12 #include <linux/bitops.h> ··· 402 401 * http://thread.gmane.org/gmane.linux.kernel/1480396 403 402 */ 404 403 WQ_POWER_EFFICIENT = 1 << 7, 404 + WQ_PERCPU = 1 << 8, /* bound to a specific cpu */ 405 405 406 406 __WQ_DESTROYING = 1 << 15, /* internal: workqueue is destroying */ 407 407 __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ ··· 429 427 /* 430 428 * System-wide workqueues which are always present. 431 429 * 432 - * system_wq is the one used by schedule[_delayed]_work[_on](). 430 + * system_percpu_wq is the one used by schedule[_delayed]_work[_on](). 433 431 * Multi-CPU multi-threaded. There are users which expect relatively 434 432 * short queue flush time. Don't queue works which can run for too 435 433 * long. ··· 440 438 * system_long_wq is similar to system_wq but may host long running 441 439 * works. Queue flushing might take relatively long. 442 440 * 443 - * system_unbound_wq is unbound workqueue. Workers are not bound to 441 + * system_dfl_wq is unbound workqueue. Workers are not bound to 444 442 * any specific CPU, not concurrency managed, and all queued works are 445 443 * executed immediately as long as max_active limit is not reached and 446 444 * resources are available. ··· 457 455 * system_bh[_highpri]_wq are convenience interface to softirq. BH work items 458 456 * are executed in the queueing CPU's BH context in the queueing order. 459 457 */ 460 - extern struct workqueue_struct *system_wq; 458 + extern struct workqueue_struct *system_wq; /* use system_percpu_wq, this will be removed */ 459 + extern struct workqueue_struct *system_percpu_wq; 461 460 extern struct workqueue_struct *system_highpri_wq; 462 461 extern struct workqueue_struct *system_long_wq; 463 462 extern struct workqueue_struct *system_unbound_wq; 463 + extern struct workqueue_struct *system_dfl_wq; 464 464 extern struct workqueue_struct *system_freezable_wq; 465 465 extern struct workqueue_struct *system_power_efficient_wq; 466 466 extern struct workqueue_struct *system_freezable_power_efficient_wq; ··· 509 505 * Pointer to the allocated workqueue on success, %NULL on failure. 510 506 */ 511 507 __printf(1, 4) struct workqueue_struct * 512 - alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...); 508 + alloc_workqueue_noprof(const char *fmt, unsigned int flags, int max_active, ...); 509 + #define alloc_workqueue(...) alloc_hooks(alloc_workqueue_noprof(__VA_ARGS__)) 513 510 514 511 #ifdef CONFIG_LOCKDEP 515 512 /** ··· 549 544 * Pointer to the allocated workqueue on success, %NULL on failure. 550 545 */ 551 546 #define alloc_ordered_workqueue_lockdep_map(fmt, flags, lockdep_map, args...) \ 552 - alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), \ 553 - 1, lockdep_map, ##args) 547 + alloc_hooks(alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags),\ 548 + 1, lockdep_map, ##args)) 554 549 #endif 555 550 556 551 /** ··· 582 577 583 578 extern void destroy_workqueue(struct workqueue_struct *wq); 584 579 585 - struct workqueue_attrs *alloc_workqueue_attrs(void); 580 + struct workqueue_attrs *alloc_workqueue_attrs_noprof(void); 581 + #define alloc_workqueue_attrs(...) alloc_hooks(alloc_workqueue_attrs_noprof(__VA_ARGS__)) 582 + 586 583 void free_workqueue_attrs(struct workqueue_attrs *attrs); 587 584 int apply_workqueue_attrs(struct workqueue_struct *wq, 588 585 const struct workqueue_attrs *attrs); ··· 847 840 work_on_cpu_key(_cpu, _fn, _arg, &__key); \ 848 841 }) 849 842 850 - long work_on_cpu_safe_key(int cpu, long (*fn)(void *), 851 - void *arg, struct lock_class_key *key); 852 - 853 - /* 854 - * A new key is defined for each caller to make sure the work 855 - * associated with the function doesn't share its locking class. 856 - */ 857 - #define work_on_cpu_safe(_cpu, _fn, _arg) \ 858 - ({ \ 859 - static struct lock_class_key __key; \ 860 - \ 861 - work_on_cpu_safe_key(_cpu, _fn, _arg, &__key); \ 862 - }) 863 843 #endif /* CONFIG_SMP */ 864 844 865 845 #ifdef CONFIG_FREEZER
+24 -50
kernel/workqueue.c
··· 505 505 506 506 struct workqueue_struct *system_wq __ro_after_init; 507 507 EXPORT_SYMBOL(system_wq); 508 + struct workqueue_struct *system_percpu_wq __ro_after_init; 509 + EXPORT_SYMBOL(system_percpu_wq); 508 510 struct workqueue_struct *system_highpri_wq __ro_after_init; 509 511 EXPORT_SYMBOL_GPL(system_highpri_wq); 510 512 struct workqueue_struct *system_long_wq __ro_after_init; 511 513 EXPORT_SYMBOL_GPL(system_long_wq); 512 514 struct workqueue_struct *system_unbound_wq __ro_after_init; 513 515 EXPORT_SYMBOL_GPL(system_unbound_wq); 516 + struct workqueue_struct *system_dfl_wq __ro_after_init; 517 + EXPORT_SYMBOL_GPL(system_dfl_wq); 514 518 struct workqueue_struct *system_freezable_wq __ro_after_init; 515 519 EXPORT_SYMBOL_GPL(system_freezable_wq); 516 520 struct workqueue_struct *system_power_efficient_wq __ro_after_init; ··· 1690 1686 static bool tryinc_node_nr_active(struct wq_node_nr_active *nna) 1691 1687 { 1692 1688 int max = READ_ONCE(nna->max); 1689 + int old = atomic_read(&nna->nr); 1693 1690 1694 - while (true) { 1695 - int old, tmp; 1696 - 1697 - old = atomic_read(&nna->nr); 1691 + do { 1698 1692 if (old >= max) 1699 1693 return false; 1700 - tmp = atomic_cmpxchg_relaxed(&nna->nr, old, old + 1); 1701 - if (tmp == old) 1702 - return true; 1703 - } 1694 + } while (!atomic_try_cmpxchg_relaxed(&nna->nr, &old, old + 1)); 1695 + 1696 + return true; 1704 1697 } 1705 1698 1706 1699 /** ··· 2222 2221 } 2223 2222 2224 2223 new_cpu = __this_cpu_read(wq_rr_cpu_last); 2225 - new_cpu = cpumask_next_and(new_cpu, wq_unbound_cpumask, cpu_online_mask); 2226 - if (unlikely(new_cpu >= nr_cpu_ids)) { 2227 - new_cpu = cpumask_first_and(wq_unbound_cpumask, cpu_online_mask); 2228 - if (unlikely(new_cpu >= nr_cpu_ids)) 2229 - return cpu; 2230 - } 2224 + new_cpu = cpumask_next_and_wrap(new_cpu, wq_unbound_cpumask, cpu_online_mask); 2225 + if (unlikely(new_cpu >= nr_cpu_ids)) 2226 + return cpu; 2231 2227 __this_cpu_write(wq_rr_cpu_last, new_cpu); 2232 2228 2233 2229 return new_cpu; ··· 4627 4629 * 4628 4630 * Return: The allocated new workqueue_attr on success. %NULL on failure. 4629 4631 */ 4630 - struct workqueue_attrs *alloc_workqueue_attrs(void) 4632 + struct workqueue_attrs *alloc_workqueue_attrs_noprof(void) 4631 4633 { 4632 4634 struct workqueue_attrs *attrs; 4633 4635 ··· 5680 5682 else 5681 5683 wq_size = sizeof(*wq); 5682 5684 5683 - wq = kzalloc(wq_size, GFP_KERNEL); 5685 + wq = kzalloc_noprof(wq_size, GFP_KERNEL); 5684 5686 if (!wq) 5685 5687 return NULL; 5686 5688 5687 5689 if (flags & WQ_UNBOUND) { 5688 - wq->unbound_attrs = alloc_workqueue_attrs(); 5690 + wq->unbound_attrs = alloc_workqueue_attrs_noprof(); 5689 5691 if (!wq->unbound_attrs) 5690 5692 goto err_free_wq; 5691 5693 } ··· 5775 5777 } 5776 5778 5777 5779 __printf(1, 4) 5778 - struct workqueue_struct *alloc_workqueue(const char *fmt, 5779 - unsigned int flags, 5780 - int max_active, ...) 5780 + struct workqueue_struct *alloc_workqueue_noprof(const char *fmt, 5781 + unsigned int flags, 5782 + int max_active, ...) 5781 5783 { 5782 5784 struct workqueue_struct *wq; 5783 5785 va_list args; ··· 5792 5794 5793 5795 return wq; 5794 5796 } 5795 - EXPORT_SYMBOL_GPL(alloc_workqueue); 5797 + EXPORT_SYMBOL_GPL(alloc_workqueue_noprof); 5796 5798 5797 5799 #ifdef CONFIG_LOCKDEP 5798 5800 __printf(1, 5) ··· 6768 6770 return wfc.ret; 6769 6771 } 6770 6772 EXPORT_SYMBOL_GPL(work_on_cpu_key); 6771 - 6772 - /** 6773 - * work_on_cpu_safe_key - run a function in thread context on a particular cpu 6774 - * @cpu: the cpu to run on 6775 - * @fn: the function to run 6776 - * @arg: the function argument 6777 - * @key: The lock class key for lock debugging purposes 6778 - * 6779 - * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold 6780 - * any locks which would prevent @fn from completing. 6781 - * 6782 - * Return: The value @fn returns. 6783 - */ 6784 - long work_on_cpu_safe_key(int cpu, long (*fn)(void *), 6785 - void *arg, struct lock_class_key *key) 6786 - { 6787 - long ret = -ENODEV; 6788 - 6789 - cpus_read_lock(); 6790 - if (cpu_online(cpu)) 6791 - ret = work_on_cpu_key(cpu, fn, arg, key); 6792 - cpus_read_unlock(); 6793 - return ret; 6794 - } 6795 - EXPORT_SYMBOL_GPL(work_on_cpu_safe_key); 6796 6773 #endif /* CONFIG_SMP */ 6797 6774 6798 6775 #ifdef CONFIG_FREEZER ··· 7803 7830 } 7804 7831 7805 7832 system_wq = alloc_workqueue("events", 0, 0); 7833 + system_percpu_wq = alloc_workqueue("events", 0, 0); 7806 7834 system_highpri_wq = alloc_workqueue("events_highpri", WQ_HIGHPRI, 0); 7807 7835 system_long_wq = alloc_workqueue("events_long", 0, 0); 7808 - system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, 7809 - WQ_MAX_ACTIVE); 7836 + system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, WQ_MAX_ACTIVE); 7837 + system_dfl_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, WQ_MAX_ACTIVE); 7810 7838 system_freezable_wq = alloc_workqueue("events_freezable", 7811 7839 WQ_FREEZABLE, 0); 7812 7840 system_power_efficient_wq = alloc_workqueue("events_power_efficient", ··· 7818 7844 system_bh_wq = alloc_workqueue("events_bh", WQ_BH, 0); 7819 7845 system_bh_highpri_wq = alloc_workqueue("events_bh_highpri", 7820 7846 WQ_BH | WQ_HIGHPRI, 0); 7821 - BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq || 7822 - !system_unbound_wq || !system_freezable_wq || 7847 + BUG_ON(!system_wq || !system_percpu_wq|| !system_highpri_wq || !system_long_wq || 7848 + !system_unbound_wq || !system_freezable_wq || !system_dfl_wq || 7823 7849 !system_power_efficient_wq || 7824 7850 !system_freezable_power_efficient_wq || 7825 7851 !system_bh_wq || !system_bh_highpri_wq);