[PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep

Brendan Jackman posted 1 patch 1 week, 4 days ago
There is a newer version of this series
mm/vmalloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by Brendan Jackman 1 week, 4 days ago
The only reason vmap_range_noflush() can sleep is because of pagetable
allocations. This might_sleep() is accurate, but we have a more
precise way to express this particular case, so help readers out by
using that.

Note that the actual GFP flags used to allocate here are arch-specific.
But as long as GFP_PGTABLE_KERNEL includes blockable flags, it should
serve as a reasonable common-denominator here.

This also ensures there is an fs_reclaim_acquire() even no pagetables
are actually allocated, which could potentially do a better job at
catching filesystem bugs.

---
Signed-off-by: Brendan Jackman <jackmanb@google.com>
---
 mm/vmalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index a53c7462671bdd896f95712af71398ffbe22fb80..ff1876588b94ec69168324e93399dbd117a6959a 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -305,7 +305,7 @@ static int vmap_range_noflush(unsigned long addr, unsigned long end,
 	int err;
 	pgtbl_mod_mask mask = 0;
 
-	might_sleep();
+	might_alloc(GFP_PGTABLE_KERNEL);
 	BUG_ON(addr >= end);
 
 	start = addr;

---
base-commit: ecc46e02e0abe025a6e840cba2d647f23fd1d721
change-id: 20251208-b4-vmalloc-might_alloc-754a791e4e10

Best regards,
-- 
Brendan Jackman <jackmanb@google.com>
Re: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by kernel test robot 1 week, 3 days ago
Hi Brendan,

kernel test robot noticed the following build errors:

[auto build test ERROR on ecc46e02e0abe025a6e840cba2d647f23fd1d721]

url:    https://github.com/intel-lab-lkp/linux/commits/Brendan-Jackman/mm-vmalloc-clarify-why-vmap_range_noflush-might-sleep/20251208-132202
base:   ecc46e02e0abe025a6e840cba2d647f23fd1d721
patch link:    https://lore.kernel.org/r/20251208-b4-vmalloc-might_alloc-v1-1-94a9bb8ecb08%40google.com
patch subject: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20251209/202512090959.BWqYaOOg-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251209/202512090959.BWqYaOOg-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512090959.BWqYaOOg-lkp@intel.com/

All errors (new ones prefixed by >>):

>> mm/vmalloc.c:308:14: error: use of undeclared identifier 'GFP_PGTABLE_KERNEL'
     308 |         might_alloc(GFP_PGTABLE_KERNEL);
         |                     ^
   1 error generated.


vim +/GFP_PGTABLE_KERNEL +308 mm/vmalloc.c

   297	
   298	static int vmap_range_noflush(unsigned long addr, unsigned long end,
   299				phys_addr_t phys_addr, pgprot_t prot,
   300				unsigned int max_page_shift)
   301	{
   302		pgd_t *pgd;
   303		unsigned long start;
   304		unsigned long next;
   305		int err;
   306		pgtbl_mod_mask mask = 0;
   307	
 > 308		might_alloc(GFP_PGTABLE_KERNEL);
   309		BUG_ON(addr >= end);
   310	
   311		start = addr;
   312		pgd = pgd_offset_k(addr);
   313		do {
   314			next = pgd_addr_end(addr, end);
   315			err = vmap_p4d_range(pgd, addr, next, phys_addr, prot,
   316						max_page_shift, &mask);
   317			if (err)
   318				break;
   319		} while (pgd++, phys_addr += (next - addr), addr = next, addr != end);
   320	
   321		if (mask & ARCH_PAGE_TABLE_SYNC_MASK)
   322			arch_sync_kernel_mappings(start, end);
   323	
   324		return err;
   325	}
   326	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by kernel test robot 1 week, 3 days ago
Hi Brendan,

kernel test robot noticed the following build errors:

[auto build test ERROR on ecc46e02e0abe025a6e840cba2d647f23fd1d721]

url:    https://github.com/intel-lab-lkp/linux/commits/Brendan-Jackman/mm-vmalloc-clarify-why-vmap_range_noflush-might-sleep/20251208-132202
base:   ecc46e02e0abe025a6e840cba2d647f23fd1d721
patch link:    https://lore.kernel.org/r/20251208-b4-vmalloc-might_alloc-v1-1-94a9bb8ecb08%40google.com
patch subject: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
config: nios2-allnoconfig (https://download.01.org/0day-ci/archive/20251209/202512090844.OmozcWcI-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251209/202512090844.OmozcWcI-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512090844.OmozcWcI-lkp@intel.com/

All errors (new ones prefixed by >>):

   mm/vmalloc.c: In function 'vmap_range_noflush':
>> mm/vmalloc.c:308:21: error: 'GFP_PGTABLE_KERNEL' undeclared (first use in this function)
     308 |         might_alloc(GFP_PGTABLE_KERNEL);
         |                     ^~~~~~~~~~~~~~~~~~
   mm/vmalloc.c:308:21: note: each undeclared identifier is reported only once for each function it appears in


vim +/GFP_PGTABLE_KERNEL +308 mm/vmalloc.c

   297	
   298	static int vmap_range_noflush(unsigned long addr, unsigned long end,
   299				phys_addr_t phys_addr, pgprot_t prot,
   300				unsigned int max_page_shift)
   301	{
   302		pgd_t *pgd;
   303		unsigned long start;
   304		unsigned long next;
   305		int err;
   306		pgtbl_mod_mask mask = 0;
   307	
 > 308		might_alloc(GFP_PGTABLE_KERNEL);
   309		BUG_ON(addr >= end);
   310	
   311		start = addr;
   312		pgd = pgd_offset_k(addr);
   313		do {
   314			next = pgd_addr_end(addr, end);
   315			err = vmap_p4d_range(pgd, addr, next, phys_addr, prot,
   316						max_page_shift, &mask);
   317			if (err)
   318				break;
   319		} while (pgd++, phys_addr += (next - addr), addr = next, addr != end);
   320	
   321		if (mask & ARCH_PAGE_TABLE_SYNC_MASK)
   322			arch_sync_kernel_mappings(start, end);
   323	
   324		return err;
   325	}
   326	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
[syzbot ci] Re: mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by syzbot ci 1 week, 4 days ago
syzbot ci has tested the following series

[v1] mm/vmalloc: clarify why vmap_range_noflush() might sleep
https://lore.kernel.org/all/20251208-b4-vmalloc-might_alloc-v1-1-94a9bb8ecb08@google.com
* [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep

and found the following issue:
kernel build error

Full report is available here:
https://ci.syzbot.org/series/ca5fb0b1-49a4-4066-b78d-d144e56e0d2b

***

kernel build error

tree:      mm-new
URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base:      3f43be96f919cc611dcb2a4e38dd464831f4513e
arch:      amd64
compiler:  Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
config:    https://ci.syzbot.org/builds/1d630f58-694e-4568-8ac0-62e02ea8a59d/config

mm/vmalloc.c:308:14: error: use of undeclared identifier 'GFP_PGTABLE_KERNEL'

***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
Re: [syzbot ci] Re: mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by Brendan Jackman 1 week, 3 days ago
On Mon Dec 8, 2025 at 8:51 AM UTC, syzbot ci wrote:
> kernel build error
>
> tree:      mm-new
> URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
> base:      3f43be96f919cc611dcb2a4e38dd464831f4513e
> arch:      amd64

Um, so apparently I didn't even compile this code for x86? Sorry about
this.

FWIW, I do test my patches [0]! Apparently in this case I just decided
to post it without actually checking the results.

[0] https://github.com/bjackman/limmat-kernel-nix
Re: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by Anshuman Khandual 1 week, 4 days ago

On 08/12/25 10:49 AM, Brendan Jackman wrote:
> The only reason vmap_range_noflush() can sleep is because of pagetable
> allocations. This might_sleep() is accurate, but we have a more
> precise way to express this particular case, so help readers out by
> using that.
> 
> Note that the actual GFP flags used to allocate here are arch-specific.
> But as long as GFP_PGTABLE_KERNEL includes blockable flags, it should

Currently GFP_PGTABLE_KERNEL does have a blocking flag via GFP_KERNEL.

#define GFP_PGTABLE_KERNEL	(GFP_KERNEL | __GFP_ZERO)
#define GFP_KERNEL		(__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define __GFP_RECLAIM 		((__force gfp_t)(___GFP_DIRECT_RECLAIM|___GFP_KSWAPD_RECLAIM))

> serve as a reasonable common-denominator here.

Agreed.

> 
> This also ensures there is an fs_reclaim_acquire() even no pagetables
> are actually allocated, which could potentially do a better job at
> catching filesystem bugs.

Makes sense.

> 
> ---
> Signed-off-by: Brendan Jackman <jackmanb@google.com>
> ---
>  mm/vmalloc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index a53c7462671bdd896f95712af71398ffbe22fb80..ff1876588b94ec69168324e93399dbd117a6959a 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -305,7 +305,7 @@ static int vmap_range_noflush(unsigned long addr, unsigned long end,
>  	int err;
>  	pgtbl_mod_mask mask = 0;
>  
> -	might_sleep();
> +	might_alloc(GFP_PGTABLE_KERNEL);

This will invariably add a might_sleep() and hence preserves the existing
behaviour besides adding fs_reclaim_acquire() which is an improvement.

>  	BUG_ON(addr >= end);
>  
>  	start = addr;
> 
> ---
> base-commit: ecc46e02e0abe025a6e840cba2d647f23fd1d721
> change-id: 20251208-b4-vmalloc-might_alloc-754a791e4e10
> 
> Best regards,

Please add <asm-generic/pgalloc.h> in mm/vmalloc.c - otherwise it does not
get built as GFP_PGTABLE_KERNEL is not available. But otherwise LGTM.

After fixing the build.

Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Re: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by Brendan Jackman 1 week, 4 days ago
Hi Anshuman, thanks a lot for taking a look.

On Mon Dec 8, 2025 at 6:41 AM UTC, Anshuman Khandual wrote:
> Please add <asm-generic/pgalloc.h> in mm/vmalloc.c - otherwise it does not
> get built as GFP_PGTABLE_KERNEL is not available. But otherwise LGTM.

Oh, but that's not correct, IIUC we shouldn't directly be including
asm-generic headers from here.

So while in principle GFP_PGTABLE_KERNEL is a sensible common
demoninator here, it doesn't actually exist at all everywhere, e.g. it
doesn't look like m68k defines it for Motorola. 

So maybe the best way here is a really vague:

/* 
 * Different archs allocate pagetables in different ways, assume
 * GFP_KERNEL as a common denominator.
 */
might_alloc(GFP_KERNEL)

... a bit yucky but I think still useful.

Any thoughts?
Re: [PATCH] mm/vmalloc: clarify why vmap_range_noflush() might sleep
Posted by Uladzislau Rezki 1 week, 3 days ago
On Mon, Dec 08, 2025 at 07:39:39AM +0000, Brendan Jackman wrote:
> Hi Anshuman, thanks a lot for taking a look.
> 
> On Mon Dec 8, 2025 at 6:41 AM UTC, Anshuman Khandual wrote:
> > Please add <asm-generic/pgalloc.h> in mm/vmalloc.c - otherwise it does not
> > get built as GFP_PGTABLE_KERNEL is not available. But otherwise LGTM.
> 
> Oh, but that's not correct, IIUC we shouldn't directly be including
> asm-generic headers from here.
> 
> So while in principle GFP_PGTABLE_KERNEL is a sensible common
> demoninator here, it doesn't actually exist at all everywhere, e.g. it
> doesn't look like m68k defines it for Motorola. 
> 
> So maybe the best way here is a really vague:
> 
> /* 
>  * Different archs allocate pagetables in different ways, assume
>  * GFP_KERNEL as a common denominator.
>  */
> might_alloc(GFP_KERNEL)
> 
> ... a bit yucky but I think still useful.
> 
> Any thoughts?
>
Maybe just add a comment why that might_sleep() is there?

We can simply state that page table allocation path is hard-coded
internally to use GFP_KERNEL flag.

Thanks!

--
Uladzislau Rezki