Re: [PATCH] workqueue: add cmdline parameter `unbound_workqueue_cpus` to further constrain wq_unbound_cpumask at boot time

From: Randy Dunlap
Date: Wed Jun 21 2023 - 23:48:33 EST




On 6/21/23 20:34, tiozhang wrote:
> Motivation of doing this is to better improve boot times for devices when
> we want to prevent our workqueue works from running on some specific CPUs,
> e,g, some CPUs are busy with interrupts.
>
> Signed-off-by: tiozhang <tiozhang@xxxxxxxxxxxxxx>
> ---
> kernel/workqueue.c | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>

Documentation for this new command line parameter should be added to
Documentation/admin-guide/kernel-parameters.rst (in alphabetical order).

Thanks.

> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index 7cd5f5e7e0a1..47e7b29df5fe 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -329,6 +329,9 @@ static bool workqueue_freezing; /* PL: have wqs started freezing? */
> /* PL: allowable cpus for unbound wqs and work items */
> static cpumask_var_t wq_unbound_cpumask;
>
> +/* for further constrain wq_unbound_cpumask by cmdline parameter*/
> +static cpumask_var_t wq_cmdline_cpumask;
> +
> /* CPU where unbound work was last round robin scheduled from this CPU */
> static DEFINE_PER_CPU(int, wq_rr_cpu_last);
>
> @@ -6006,6 +6009,10 @@ void __init workqueue_init_early(void)
> cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_WQ));
> cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_DOMAIN));
>
> + if (!cpumask_empty(wq_cmdline_cpumask))
> + cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, wq_cmdline_cpumask);
> + free_bootmem_cpumask_var(wq_cmdline_cpumask);
> +
> pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
>
> /* initialize CPU pools */
> @@ -6129,3 +6136,21 @@ void __init workqueue_init(void)
> */
> void __warn_flushing_systemwide_wq(void) { }
> EXPORT_SYMBOL(__warn_flushing_systemwide_wq);
> +
> +
> +static int __init unbound_workqueue_cpus_setup(char *str)
> +{
> + cpumask_var_t cpumask;
> +
> + alloc_bootmem_cpumask_var(&wq_cmdline_cpumask);
> + alloc_bootmem_cpumask_var(&cpumask);
> + if (cpulist_parse(str, cpumask) < 0)
> + pr_warn("unbound_workqueue_cpus: incorrect CPU range\n");
> + else
> + cpumask_copy(wq_cmdline_cpumask, cpumask);
> +
> + free_bootmem_cpumask_var(cpumask);
> +
> + return 0;
> +}
> +__setup("unbound_workqueue_cpus=", unbound_workqueue_cpus_setup);

--
~Randy