Re: [PATCH v5 01/29] md/md-llbitmap: clear flush state after daemon flush
[email protected] Sun, 02 Aug 2026 20:28:38 +0000
| Newsgroups | org.kernel.vger.linux-raid |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 2 potential issue(= s) to consider: New issues: - [High] The patch unmasks a use-after-free of `llbitmap` during array tear= down by allowing the daemon worker to re-arm the timer after it has been de= leted. Pre-existing issues: - [High] This problem wasn't introduced by this patch, but threads waiting = for IO barriers will hang indefinitely if page suspension times out. -- --- Patch [1]: [PATCH v5 01/29] md/md-llbitmap: clear flush state after dae= mon flush --- commit 5b6bbbac2eb163d696a69aa1800138e01de10a7e Author: Yu Kuai <[email protected]> md/md-llbitmap: clear flush state after daemon flush This patch changes the llbitmap daemon to consume the LLPageFlush bit using test_and_clear_bit() instead of just testing it. This ensures that after an explicit flush, subsequent dirty bits on the same page will correctly wait for the barrier_idle window before being cleaned. > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c > @@ -1066,14 +1066,14 @@ static void md_llbitmap_daemon_fn(struct work_str= uct *work) > =20 > for (idx =3D 0; idx < llbitmap->nr_pages; idx++) { > struct llbitmap_page_ctl *pctl =3D llbitmap->pctl[idx]; > + bool flush =3D test_and_clear_bit(LLPageFlush, &pctl->flags); > =20 > if (idx > 0) { > start =3D end + 1; > end =3D min(end + PAGE_SIZE, llbitmap->chunks - 1); > } > =20 > - if (!test_bit(LLPageFlush, &pctl->flags) && > - time_before(jiffies, pctl->expire)) { > + if (!flush && time_before(jiffies, pctl->expire)) { ^^^^^^ [Severity: High] Does consuming the LLPageFlush bit here expose a use-after-free during array teardown? During normal array teardown, llbitmap_flush() sets LLPageFlush and queues daemon_work. Because this patch consumes LLPageFlush, a subsequent execution of the work can see LLPageFlush as clear. It will then evaluate time_before(jiffies, pctl->expire) as true, set restart =3D true, and blind= ly call mod_timer() at the end of md_llbitmap_daemon_fn(). If this work runs via flush_workqueue(md_llbitmap_io_wq) in llbitmap_destroy(), it arms the timer after timer_delete_sync() has already finished: drivers/md/md-llbitmap.c:llbitmap_destroy() { ... timer_delete_sync(&llbitmap->pending_timer); flush_workqueue(md_llbitmap_io_wq); ... } The llbitmap is then freed, and the timer can fire on freed memory. > restart =3D true; > continue; > } [Severity: High] This isn't a bug introduced by this patch, but threads waiting for IO barriers will hang indefinitely if page suspension times out. If llbitmap_suspend_timeout() times out (e.g., due to slow IO), it resurrec= ts the percpu_ref but skips calling wake_up(&pctl->wait): drivers/md/md-llbitmap.c:llbitmap_suspend_timeout() { ... percpu_ref_resurrect(&pctl->active); return -ETIMEDOUT; ... } The daemon then continues and skips llbitmap_resume() which normally does t= he wakeup. Threads waiting in llbitmap_raise_barrier() for the dying state to clear will never be woken up: drivers/md/md-llbitmap.c:llbitmap_raise_barrier() { ... wait_event(pctl->wait, !percpu_ref_is_dying(&pctl->active)); ... } Can this lead to a permanent hang of IO threads accessing the md array? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260802195038.1642= [email protected]?part=3D1