linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent
@ 2025-10-30 16:43 Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 1/4] mm/vmalloc: warn on invalid vmalloc gfp flags Vishal Moola (Oracle)
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Vishal Moola (Oracle) @ 2025-10-30 16:43 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Uladzislau Rezki, Andrew Morton, Christoph Hellwig,
	Vishal Moola (Oracle)

We should do a better job at enforcing gfp flags for vmalloc. Right now, we
have a kernel-doc for __vmalloc_node_range(), and hope callers pass in
supported flags. If a caller were to pass in an unsupported flag, we may
BUG, silently clear it, or completely ignore it.

If we are more proactive about enforcing gfp flags, we can making sure
callers know when they may be asking for unsupported behavior.

This patchset lets vmalloc control the incoming gfp flags, and cleans up
some confusing gfp code.

----------------
Based on mm-new

I did some digging and am not entirely sure what flags vmalloc does NOT
support. Is a better idea is to have explicitly supported flags and drop
all others?

__GFP_COMP is an obvious one due to a BUG call in split_page().
~GFP_BITS_MASK is also obvious.

Then I started following the kernel doc and added NORETRY and
RETRY_MAYFAIL, and after forking a couple hundred times, it turns out some
per-cpu allocations pass in the NORETRY flag right now.

Does anyone have a handy-dandy list of supported/unsupported vmalloc flags
that we should reject/clear? Ulad?

Vishal Moola (Oracle) (4):
  mm/vmalloc: warn on invalid vmalloc gfp flags
  mm/vmalloc: Add a helper to optimize vmalloc allocation gfps
  mm/vmalloc: cleanup large_gfp in vm_area_alloc_pages()
  mm/vmalloc: cleanup gfp flag use in new_vmap_block()

 mm/vmalloc.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

-- 
2.51.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH 1/4] mm/vmalloc: warn on invalid vmalloc gfp flags
  2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
@ 2025-10-30 16:43 ` Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 2/4] mm/vmalloc: Add a helper to optimize vmalloc allocation gfps Vishal Moola (Oracle)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Vishal Moola (Oracle) @ 2025-10-30 16:43 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Uladzislau Rezki, Andrew Morton, Christoph Hellwig,
	Vishal Moola (Oracle)

There are some gfp flags that are not supported by vmalloc.
vmalloc has been trying to handle these by clearing and setting flags
wherever necessary. This is messy and makes the code harder to
understand, when we could simply check for these unsupported flags
immediately.

Define a helper mask and function telling callers they have passed in
invalid flags, and clear those unsupported vmalloc flags.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
 mm/vmalloc.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 0832f944544c..b86c36d51833 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3911,6 +3911,20 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 	return NULL;
 }
 
+#define GFP_VMALLOC_BUG_MASK (__GFP_COMP|__GFP_RETRY_MAYFAIL|\
+			      ~__GFP_BITS_MASK)
+static gfp_t vmalloc_fix_flags(gfp_t flags)
+{
+	gfp_t invalid_mask = flags & GFP_VMALLOC_BUG_MASK;
+
+	flags &= ~GFP_VMALLOC_BUG_MASK;
+	pr_warn("Unexpected gfp: %#x (%pGg). Fixing up to gfp: %#x (%pGg). Fix your code!\n",
+			invalid_mask, &invalid_mask, flags, &flags);
+	dump_stack();
+
+	return flags;
+}
+
 /**
  * __vmalloc_node_range - allocate virtually contiguous memory
  * @size:		  allocation size
@@ -3961,6 +3975,9 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
 		return NULL;
 	}
 
+	if (unlikely(gfp_mask & GFP_VMALLOC_BUG_MASK))
+		gfp_mask = vmalloc_fix_flags(gfp_mask);
+
 	if (vmap_allow_huge && (vm_flags & VM_ALLOW_HUGE_VMAP)) {
 		/*
 		 * Try huge pages. Only try for PAGE_KERNEL allocations,
-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 2/4] mm/vmalloc: Add a helper to optimize vmalloc allocation gfps
  2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 1/4] mm/vmalloc: warn on invalid vmalloc gfp flags Vishal Moola (Oracle)
@ 2025-10-30 16:43 ` Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 3/4] mm/vmalloc: cleanup large_gfp in vm_area_alloc_pages() Vishal Moola (Oracle)
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Vishal Moola (Oracle) @ 2025-10-30 16:43 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Uladzislau Rezki, Andrew Morton, Christoph Hellwig,
	Vishal Moola (Oracle)

vm_area_alloc_pages() attempts to use different gfp flags as a way
to optimize allocations. This has been done inline which makes things
harder to read.

Add a helper function to make the code more readable.

Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
 mm/vmalloc.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index b86c36d51833..76c060ef2bf7 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3614,6 +3614,17 @@ void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot)
 EXPORT_SYMBOL_GPL(vmap_pfn);
 #endif /* CONFIG_VMAP_PFN */
 
+/*
+ * Helper for vmalloc to adjust the gfp flags for certain allocations.
+ */
+static inline gfp_t vmalloc_gfp_adjust(gfp_t flags, const bool large)
+{
+	flags |= __GFP_NOWARN;
+	if (large)
+		flags &= ~__GFP_NOFAIL;
+	return flags;
+}
+
 static inline unsigned int
 vm_area_alloc_pages(gfp_t gfp, int nid,
 		unsigned int order, unsigned int nr_pages, struct page **pages)
@@ -3852,9 +3863,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 	 * Please note, the __vmalloc_node_range_noprof() falls-back
 	 * to order-0 pages if high-order attempt is unsuccessful.
 	 */
-	area->nr_pages = vm_area_alloc_pages((page_order ?
-		gfp_mask & ~__GFP_NOFAIL : gfp_mask) | __GFP_NOWARN,
-		node, page_order, nr_small_pages, area->pages);
+	area->nr_pages = vm_area_alloc_pages(
+			vmalloc_gfp_adjust(gfp_mask, page_order), node,
+			page_order, nr_small_pages, area->pages);
 
 	atomic_long_add(area->nr_pages, &nr_vmalloc_pages);
 	/* All pages of vm should be charged to same memcg, so use first one. */
-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 3/4] mm/vmalloc: cleanup large_gfp in vm_area_alloc_pages()
  2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 1/4] mm/vmalloc: warn on invalid vmalloc gfp flags Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 2/4] mm/vmalloc: Add a helper to optimize vmalloc allocation gfps Vishal Moola (Oracle)
@ 2025-10-30 16:43 ` Vishal Moola (Oracle)
  2025-10-30 16:43 ` [RFC PATCH 4/4] mm/vmalloc: cleanup gfp flag use in new_vmap_block() Vishal Moola (Oracle)
  2025-11-03 12:57 ` [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Uladzislau Rezki
  4 siblings, 0 replies; 7+ messages in thread
From: Vishal Moola (Oracle) @ 2025-10-30 16:43 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Uladzislau Rezki, Andrew Morton, Christoph Hellwig,
	Vishal Moola (Oracle)

Now that we have already checked for unsupported flags, we can use the
helper function to set the necessary gfp flags for the large order
allocation optimization.

Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
 mm/vmalloc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 76c060ef2bf7..8ad0451a7bd7 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3634,10 +3634,8 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
 	unsigned int max_attempt_order = MAX_PAGE_ORDER;
 	struct page *page;
 	int i;
-	gfp_t large_gfp = (gfp &
-		~(__GFP_DIRECT_RECLAIM | __GFP_NOFAIL | __GFP_COMP))
-		| __GFP_NOWARN;
 	unsigned int large_order = ilog2(nr_remaining);
+	gfp_t large_gfp = vmalloc_gfp_adjust(gfp, large_order) & ~__GFP_DIRECT_RECLAIM;
 
 	large_order = min(max_attempt_order, large_order);
 
-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 4/4] mm/vmalloc: cleanup gfp flag use in new_vmap_block()
  2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
                   ` (2 preceding siblings ...)
  2025-10-30 16:43 ` [RFC PATCH 3/4] mm/vmalloc: cleanup large_gfp in vm_area_alloc_pages() Vishal Moola (Oracle)
@ 2025-10-30 16:43 ` Vishal Moola (Oracle)
  2025-11-03 12:57 ` [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Uladzislau Rezki
  4 siblings, 0 replies; 7+ messages in thread
From: Vishal Moola (Oracle) @ 2025-10-30 16:43 UTC (permalink / raw)
  To: linux-kernel, linux-mm
  Cc: Uladzislau Rezki, Andrew Morton, Christoph Hellwig,
	Vishal Moola (Oracle)

The only caller, vb_alloc(), passes GFP_KERNEL into new_vmap_block()
which is a subset of GFP_RECLAIM_MASK. Since there's no reason to use
this mask here, remove it.

Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
---
 mm/vmalloc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 8ad0451a7bd7..0259cf59e6a2 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2699,8 +2699,7 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask)
 
 	node = numa_node_id();
 
-	vb = kmalloc_node(sizeof(struct vmap_block),
-			gfp_mask & GFP_RECLAIM_MASK, node);
+	vb = kmalloc_node(sizeof(struct vmap_block), gfp_mask, node);
 	if (unlikely(!vb))
 		return ERR_PTR(-ENOMEM);
 
-- 
2.51.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent
  2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
                   ` (3 preceding siblings ...)
  2025-10-30 16:43 ` [RFC PATCH 4/4] mm/vmalloc: cleanup gfp flag use in new_vmap_block() Vishal Moola (Oracle)
@ 2025-11-03 12:57 ` Uladzislau Rezki
  2025-11-03 13:51   ` Christoph Hellwig
  4 siblings, 1 reply; 7+ messages in thread
From: Uladzislau Rezki @ 2025-11-03 12:57 UTC (permalink / raw)
  To: Vishal Moola (Oracle)
  Cc: linux-kernel, linux-mm, Uladzislau Rezki, Andrew Morton,
	Christoph Hellwig

On Thu, Oct 30, 2025 at 09:43:26AM -0700, Vishal Moola (Oracle) wrote:
> We should do a better job at enforcing gfp flags for vmalloc. Right now, we
> have a kernel-doc for __vmalloc_node_range(), and hope callers pass in
> supported flags. If a caller were to pass in an unsupported flag, we may
> BUG, silently clear it, or completely ignore it.
> 
> If we are more proactive about enforcing gfp flags, we can making sure
> callers know when they may be asking for unsupported behavior.
> 
> This patchset lets vmalloc control the incoming gfp flags, and cleans up
> some confusing gfp code.
> 
> ----------------
> Based on mm-new
> 
> I did some digging and am not entirely sure what flags vmalloc does NOT
> support. Is a better idea is to have explicitly supported flags and drop
> all others?
> 
> __GFP_COMP is an obvious one due to a BUG call in split_page().
> ~GFP_BITS_MASK is also obvious.
> 
> Then I started following the kernel doc and added NORETRY and
> RETRY_MAYFAIL, and after forking a couple hundred times, it turns out some
> per-cpu allocations pass in the NORETRY flag right now.
> 
> Does anyone have a handy-dandy list of supported/unsupported vmalloc flags
> that we should reject/clear? Ulad?
> 
We recently have added GFP_ATOMIC, GFP_NOWAIT support. Both are handled
based on gfpflags_allow_blocking() checking:

<snip>
* Supported GFP classes: %GFP_KERNEL, %GFP_ATOMIC, %GFP_NOWAIT,
 * %GFP_NOFS and %GFP_NOIO. Zone modifiers are not supported.
 * Please note %GFP_ATOMIC and %GFP_NOWAIT are supported only
 * by __vmalloc().
<snip>

>
> I did some digging and am not entirely sure what flags vmalloc does NOT
> support. Is a better idea is to have explicitly supported flags and drop
> all others?
>
Maybe we should look at it vice versa. Focus on supported flags. In the
slab there is an adjust function which modifies the gfp and emits the warning
if passed GFP is part of buggy mask.

--
Uladzislau Rezki


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent
  2025-11-03 12:57 ` [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Uladzislau Rezki
@ 2025-11-03 13:51   ` Christoph Hellwig
  0 siblings, 0 replies; 7+ messages in thread
From: Christoph Hellwig @ 2025-11-03 13:51 UTC (permalink / raw)
  To: Uladzislau Rezki
  Cc: Vishal Moola (Oracle), linux-kernel, linux-mm, Andrew Morton,
	Christoph Hellwig

On Mon, Nov 03, 2025 at 01:57:01PM +0100, Uladzislau Rezki wrote:
> > I did some digging and am not entirely sure what flags vmalloc does NOT
> > support. Is a better idea is to have explicitly supported flags and drop
> > all others?
> >
> Maybe we should look at it vice versa. Focus on supported flags. In the
> slab there is an adjust function which modifies the gfp and emits the warning
> if passed GFP is part of buggy mask.

Yes, explicitly whitelisting the (component)flags supported seems like
a much more maintainable approach.



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-11-03 13:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-30 16:43 [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Vishal Moola (Oracle)
2025-10-30 16:43 ` [RFC PATCH 1/4] mm/vmalloc: warn on invalid vmalloc gfp flags Vishal Moola (Oracle)
2025-10-30 16:43 ` [RFC PATCH 2/4] mm/vmalloc: Add a helper to optimize vmalloc allocation gfps Vishal Moola (Oracle)
2025-10-30 16:43 ` [RFC PATCH 3/4] mm/vmalloc: cleanup large_gfp in vm_area_alloc_pages() Vishal Moola (Oracle)
2025-10-30 16:43 ` [RFC PATCH 4/4] mm/vmalloc: cleanup gfp flag use in new_vmap_block() Vishal Moola (Oracle)
2025-11-03 12:57 ` [RFC PATCH 0/4] make vmalloc gfp flags usage more apparent Uladzislau Rezki
2025-11-03 13:51   ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).