Re: [PATCH] checkpatch: Check WQ_PERCPU or WQ_UNBOUND presence in alloc_workqueue() users

From: Marco Crivellari

Date: Thu Jun 04 2026 - 05:37:30 EST


Hi,

On Thu, Jun 4, 2026 at 7:08 AM Joe Perches <joe@xxxxxxxxxxx> wrote:
> [...]
> OK but a couple comments:
>
> Add devm_alloc_workqueue as well?

No I don't think it would be useful / needed. There is only 1 user of
that macro, devm_alloc_ordered_workqueue(), which already specifies
the WQ_UNBOUND flag and it is part of the workqueue code.

Also, we're adding this in checkpatch, because it reflects what is
going to be present in the workqueue code:

https://lore.kernel.org/all/20260529130640.220328-3-marco.crivellari@xxxxxxxx/

> Avoid using $line here as $stat isn't populated on multi-line uses
> of alloc_workqueue. Just test $stat

Aha, noted. I will remove that test.

> Using the patch below gives a few matches treewide with a few
> false positives as the flags are stored in a variable in
> drivers/nvme/host/... and fs/btrfs/...

Yeah, those false positives were expected. I thought about adding a
message about that, indeed.

> -----------------
> block/blk-zoned.c
> -----------------
> ERROR: alloc_workqueue() must specify either WQ_PERCPU or WQ_UNBOUND
> #1926: FILE: block/blk-zoned.c:1926:
> + disk->zone_wplugs_wq =
> + alloc_workqueue("%s_zwplugs", WQ_MEM_RECLAIM | WQ_HIGHPRI,
> + pool_size, disk->disk_name);

Interestingly, my Coccinelle script didn't match this.

> scripts/checkpatch.pl | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index 0492d6afc9a1..aed83ce4b552 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -7804,6 +7804,31 @@ sub process {
> ERROR("UNINITIALIZED_PTR_WITH_FREE",
> "pointer '$1' with __free attribute should be initialized\n" . $herecurr);
> }
> +
> +# check alloc_workqueue() and devm_alloc_workqueue parameters for
> +# WQ_PERCPU and WQ_UNBOUND uses
> + if (defined($stat) &&
> + $stat =~ /^[ \+]\s*(?:$Lval\s*=\s*)?((?:devm_)?alloc_workqueue)\s*($balanced_parens)/) {
> + my $func = $1;
> + my $args = $2;
> + my $has_percpu = $args =~ /\bWQ_PERCPU\b/;
> + my $has_unbound = $args =~ /\bWQ_UNBOUND\b/;
> + my $error_msg;
> +
> + if ($has_percpu && $has_unbound) {
> + $error_msg = "$func() should not contain both WQ_PERCPU and WQ_UNBOUND\n";
> + } elsif (!$has_percpu && !$has_unbound) {
> + $error_msg = "$func() must specify either WQ_PERCPU or WQ_UNBOUND\n";
> + }
> +
> + if (defined($error_msg)) {
> + my $stmt_cnt = statement_rawlines($stat);
> + my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
> + ERROR("ALLOC_WORKQUEUE_FLAGS",
> + $error_msg . $herectx);
> + }
> +
> + }
> }
>
> # If we have no input at all, then there is nothing to report on

I will integrate my code with this!

Thanks!

--

Marco Crivellari

SUSE Labs