Re: [PATCH v2] md: scope memalloc_noio to allocation critical sections

"yu kuai" <[email protected]> Sun, 19 Jul 2026 18:03:52 +0800
Newsgroups org.kernel.vger.linux-raid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
在 2026/7/18 16:42, Chen Cheng 写道:

> From: Chen Cheng<[email protected]>
>
> Save token as mddev-scoped in mddev->noio_flags cause PF_MEMALLOC_NOIO
> leak into task A, while task B restores a token that it never saved.
>
> scenario:
>
> task A                          mddev                       task B
> ======                          =======                     ============
> write suspend_lo
> mddev_suspend()
>                                  suspended == 0
>                                  drain active_io
>                                  suspended = 1
> A: noio_A = memalloc_noio_save()
> A returns with PF_MEMALLOC_NOIO set
>
>                                                              write suspend_hi
>                                                              mddev_suspend()
>                                  suspended == 1
>                                  suspended = 2
>                                                              B returns
>                                                              (no save)
>
> mddev_resume()
>                                  suspended = 1
>                                  not last resume
> A returns
> A still has PF_MEMALLOC_NOIO   <-- leaked
>
>                                                              mddev_resume()
>                                  suspended = 0
>                                                              memalloc_noio_restore(noio_A)
>                                                              (restores A's token in B)
>
> Fixed by:
> call flags = memalloc_noio_save() directly in mdraid, where:
> 	1) after array suspend succeed;
> 	2) before allocating memory
>
> Validation:
> repeatedly updates the array's suspend_lo and suspend_hi sysfs from many
> concurrent userspace workers. That makes multiple tasks to call
> mddev_suspend()/mddev_resume() concurrently.
>
> Each worker:
>    - reads its initial /proc/self/stat flags and verifies that PF_MEMALLOC_NOIO is not already
>      set
>    - writes 0 to either suspend_lo or suspend_hi
>    - immediately reads its own task flags again
>    - reports success if flags & PF_MEMALLOC_NOIO is true after the write returns
>
> Link:https://github.com/chencheng-fnnas/reproducer/blob/main/repro-md-noio-token-leak.sh
> Fixes: 78f57ef9d50a ("md: use memalloc scope APIs in mddev_suspend()/mddev_resume()")
>
> Signed-off-by: Chen Cheng<[email protected]>
> ---
>
> rfc -> v1:
>          - dm-raid side just bypass because suspend and resume not in the
>            same task context..
>
> v1 -> v2:
>          - just call flags = memalloc_noio_save() directly in mdraid
>                  (suggest by Yu Kuai)
> ---
>   drivers/md/md-bitmap.c |  3 +++
>   drivers/md/md.c        | 52 ++++++++++++++++++++++++++++--------------
>   drivers/md/md.h        |  1 -
>   drivers/md/raid5.c     | 14 ++++++++----
>   4 files changed, 47 insertions(+), 23 deletions(-)
Reviewed-by: Yu Kuai <[email protected]>

-- 
Thanks,
Kuai