Re: [syzbot] [usb?] [pm?] WARNING in enable_work

0 views
Skip to first unread message

syzbot

unread,
12:39 PM (7 hours ago) 12:39 PM
to linux-...@vger.kernel.org, penguin...@i-love.sakura.ne.jp, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+7053fb...@syzkaller.appspotmail.com
Tested-by: syzbot+7053fb...@syzkaller.appspotmail.com

Tested on:

commit: c1f49dea Merge tag 'mm-hotfixes-stable-2026-04-19-00-1..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1776f4ce580000
kernel config: https://syzkaller.appspot.com/x/.config?x=fe26ced796b9ad9b
dashboard link: https://syzkaller.appspot.com/bug?extid=7053fbd8757fecbbe492
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=176a34ce580000

Note: testing is done by a robot and is best-effort only.

Tetsuo Handa

unread,
5:34 PM (2 hours ago) 5:34 PM
to syzbot, linux-...@vger.kernel.org, syzkall...@googlegroups.com
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ab6cb70ca1a5..f5c3cc85a1e7 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -267,7 +267,10 @@ static inline unsigned int work_static(struct work_struct *work)
return *work_data_bits(work) & WORK_STRUCT_STATIC;
}
#else
-static inline void __init_work(struct work_struct *work, int onstack) { }
+static inline void __init_work(struct work_struct *work, int onstack) {
+ atomic_set(&work->enable_count, 0);
+ atomic_set(&work->disable_count, 0);
+}
static inline void destroy_work_on_stack(struct work_struct *work) { }
static inline void destroy_delayed_work_on_stack(struct delayed_work *work) { }
static inline unsigned int work_static(struct work_struct *work) { return 0; }
diff --git a/include/linux/workqueue_types.h b/include/linux/workqueue_types.h
index 4c38824f3ab4..a9f5d74fe814 100644
--- a/include/linux/workqueue_types.h
+++ b/include/linux/workqueue_types.h
@@ -20,6 +20,8 @@ struct work_struct {
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
+ atomic_t enable_count;
+ atomic_t disable_count;
};

#endif /* _LINUX_WORKQUEUE_TYPES_H */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 5f747f241a5f..48e8d572fa33 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -689,6 +689,8 @@ static inline void debug_work_deactivate(struct work_struct *work)

void __init_work(struct work_struct *work, int onstack)
{
+ atomic_set(&work->enable_count, 0);
+ atomic_set(&work->disable_count, 0);
if (onstack)
debug_object_init_on_stack(work, &work_debug_descr);
else
@@ -4418,22 +4420,28 @@ bool flush_rcu_work(struct rcu_work *rwork)
}
EXPORT_SYMBOL(flush_rcu_work);

-static void work_offqd_disable(struct work_offq_data *offqd)
+static void work_offqd_disable(struct work_struct *work, struct work_offq_data *offqd)
{
const unsigned long max = (1lu << WORK_OFFQ_DISABLE_BITS) - 1;

+ atomic_inc(&work->disable_count);
if (likely(offqd->disable < max))
offqd->disable++;
else
- WARN_ONCE(true, "workqueue: work disable count overflowed\n");
+ WARN_ONCE(true, "workqueue: work disable count overflowed: %d %d %d\n",
+ offqd->disable, atomic_read(&work->disable_count),
+ atomic_read(&work->enable_count));
}

-static void work_offqd_enable(struct work_offq_data *offqd)
+static void work_offqd_enable(struct work_struct *work, struct work_offq_data *offqd)
{
+ atomic_inc(&work->enable_count);
if (likely(offqd->disable > 0))
offqd->disable--;
else
- WARN_ONCE(true, "workqueue: work disable count underflowed\n");
+ WARN_ONCE(true, "workqueue: work disable count underflowed: %d %d %d\n",
+ offqd->disable, atomic_read(&work->disable_count),
+ atomic_read(&work->enable_count));
}

static bool __cancel_work(struct work_struct *work, u32 cflags)
@@ -4447,7 +4455,7 @@ static bool __cancel_work(struct work_struct *work, u32 cflags)
work_offqd_unpack(&offqd, *work_data_bits(work));

if (cflags & WORK_CANCEL_DISABLE)
- work_offqd_disable(&offqd);
+ work_offqd_disable(work, &offqd);

set_work_pool_and_clear_pending(work, offqd.pool_id,
work_offqd_pack_flags(&offqd));
@@ -4604,7 +4612,7 @@ bool enable_work(struct work_struct *work)
work_grab_pending(work, 0, &irq_flags);

work_offqd_unpack(&offqd, *work_data_bits(work));
- work_offqd_enable(&offqd);
+ work_offqd_enable(work, &offqd);
set_work_pool_and_clear_pending(work, offqd.pool_id,
work_offqd_pack_flags(&offqd));
local_irq_restore(irq_flags);


syzbot

unread,
6:17 PM (1 hour ago) 6:17 PM
to linux-...@vger.kernel.org, penguin...@i-love.sakura.ne.jp, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+7053fb...@syzkaller.appspotmail.com
Tested-by: syzbot+7053fb...@syzkaller.appspotmail.com

Tested on:

commit: c1f49dea Merge tag 'mm-hotfixes-stable-2026-04-19-00-1..
git tree: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
console output: https://syzkaller.appspot.com/x/log.txt?x=14049f16580000
kernel config: https://syzkaller.appspot.com/x/.config?x=fe26ced796b9ad9b
dashboard link: https://syzkaller.appspot.com/bug?extid=7053fbd8757fecbbe492
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=1189f4ce580000
Reply all
Reply to author
Forward
0 new messages