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

"yu kuai" <[email protected]> Fri, 31 Jul 2026 13:30:47 +0800
Newsgroups org.kernel.vger.linux-raid,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
=E5=9C=A8 2026/7/18 16:42, Chen Cheng =E5=86=99=E9=81=93:

> 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
> =3D=3D=3D=3D=3D=3D                          =3D=3D=3D=3D=3D=3D=3D        =
             =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> write suspend_lo
> mddev_suspend()
>                                  suspended =3D=3D 0
>                                  drain active_io
>                                  suspended =3D 1
> A: noio_A =3D memalloc_noio_save()
> A returns with PF_MEMALLOC_NOIO set
>
>                                                              write suspen=
d_hi
>                                                              mddev_suspen=
d()
>                                  suspended =3D=3D 1
>                                  suspended =3D 2
>                                                              B returns
>                                                              (no save)
>
> mddev_resume()
>                                  suspended =3D 1
>                                  not last resume
> A returns
> A still has PF_MEMALLOC_NOIO   <-- leaked
>
>                                                              mddev_resume=
()
>                                  suspended =3D 0
>                                                              memalloc_noi=
o_restore(noio_A)
>                                                              (restores A'=
s token in B)
>
> Fixed by:
> call flags =3D 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_MEMALLO=
C_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-noi=
o-token-leak.sh
> Fixes: 78f57ef9d50a ("md: use memalloc scope APIs in mddev_suspend()/mdde=
v_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 =3D 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(-)
Rebase and applied to md-7.3

--=20
Thanks,
Kuai