Re: WARNING: at kernel/workqueue.c:1473 __queue_work+0x3b8/0x3d0

From: Robin Murphy
Date: Mon Mar 02 2020 - 13:00:18 EST


On 02/03/2020 5:25 pm, Daniel Jordan wrote:
On Sun, Mar 01, 2020 at 06:53:51PM +0100, Corentin Labbe wrote:
I tried to bisect this problem, but the result is:
...
# first bad commit: [81ff5d2cba4f86cd850b9ee4a530cd221ee45aa3] Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

The only interesting thing I see in this MR is: "Add fuzz testing to testmgr"

But this wont help.

Hm, that merge commit has only a couple lines of powerpc build change, so maybe
there's something nondeterministic going on.

Something smelled familiar about this discussion, and sure enough that merge contains c4741b230597 ("crypto: run initcalls for generic implementations earlier"), which has raised its head before[1].

Does this fix it? I can't verify but figure it's worth trying the simplest
explanation first, which is that the work isn't initialized by the time it's
queued.

The relative initcall levels would appear to explain the symptom - I guess the question is whether this represents a bug in a particular test/algorithm (as with the unaligned accesses) or a fundamental problem in the infrastructure now being able to poke the module loader too early.

Robin.

[1] https://lore.kernel.org/linux-arm-kernel/20190530170737.GB70051@xxxxxxxxx/

thanks,
daniel

---8<---

Subject: [PATCH] module: statically initialize init section freeing data

Signed-off-by: Daniel Jordan <daniel.m.jordan@xxxxxxxxxx>
---
kernel/module.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 33569a01d6e1..db0cda206167 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -88,8 +88,9 @@ EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);
/* Work queue for freeing init sections in success case */
-static struct work_struct init_free_wq;
-static struct llist_head init_free_list;
+static void do_free_init(struct work_struct *w);
+static DECLARE_WORK(init_free_wq, do_free_init);
+static LLIST_HEAD(init_free_list);
#ifdef CONFIG_MODULES_TREE_LOOKUP
@@ -3501,14 +3502,6 @@ static void do_free_init(struct work_struct *w)
}
}
-static int __init modules_wq_init(void)
-{
- INIT_WORK(&init_free_wq, do_free_init);
- init_llist_head(&init_free_list);
- return 0;
-}
-module_init(modules_wq_init);
-
/*
* This is where the real work happens.
*