Commit b78b728e21c3 for kernel

commit b78b728e21c32ec4c330b299f657fb1eb02dffc2
Author: Hao Ge <hao.ge@linux.dev>
Date:   Wed Sep 23 14:37:59 2026 +0800

    netfs: Fix missing alloc tagging of direct mempool allocations

    Commit 1d78d56c43ef ("netfs: Fix folio_queue ENOMEM in writeback by
    adding a mempool") added a mempool for the folio_queues and made the
    request, subrequest and folio_queue allocations distinguish between
    writeback and everything else.  Writeback is part of memory reclaim
    and must not fail due to ENOMEM, so it allocates under GFP_NOFS
    through mempool_alloc(), which may dip into the pool's reserve and,
    if that runs empty, wait for elements to be returned.  The
    GFP_KERNEL paths, which can return -ENOMEM to their callers, invoke
    the pool's ->alloc() callback directly instead.

    The direct call, however, skips the alloc_hooks() wrapper that the
    mempool_alloc() macro provides.  The pool callbacks, mempool_alloc_slab()
    and mempool_kmalloc(), call kmem_cache_alloc_noprof() and kmalloc_noprof()
    and rely on current->alloc_tag having been set by the caller.  With
    CONFIG_MEM_ALLOC_PROFILING_DEBUG=y this leads to

        current->alloc_tag not set
        WARNING: ./include/linux/alloc_tag.h:161 at __alloc_tagging_slab_alloc_hook
        alloc_tag was not set
        WARNING: ./include/linux/alloc_tag.h:166 at __alloc_tagging_slab_free_hook

    at allocation and free time respectively, as reported when reading
    files on a CIFS mount.  The allocations are also missing from
    /proc/allocinfo.

    Wrap the direct ->alloc() invocations in alloc_hooks() with a new
    mempool_alloc_noreserve() helper in include/linux/mempool.h, next to
    the other alloc_hooks()-wrapped macros such as mempool_alloc().  The
    GFP_KERNEL paths keep their failable allocation semantics, they just
    get tagged now.

    Fixes: 1d78d56c43ef ("netfs: Fix folio_queue ENOMEM in writeback by adding a mempool")
    Reported-by: Erhard Furtner <erhard_f@mailbox.org>
    Closes: https://lore.kernel.org/all/0b004319-9ef7-437c-a4dd-174d6a9a83db@mailbox.org/
    Tested-by: Erhard Furtner <erhard_f@mailbox.org>
    Suggested-by: Suren Baghdasaryan <surenb@google.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Hao Ge <hao.ge@linux.dev>
    Link: https://patch.msgid.link/20260923063759.34667-1-hao.ge@linux.dev
    Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
    Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>

diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
index 7f6a3e912602..ad549daa9c79 100644
--- a/fs/netfs/objects.c
+++ b/fs/netfs/objects.c
@@ -34,7 +34,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,

 		rreq = mempool_alloc(mempool, gfp);
 	} else {
-		rreq = mempool->alloc(gfp, mempool->pool_data);
+		rreq = mempool_alloc_noreserve(mempool, gfp);
 		if (!rreq)
 			return ERR_PTR(-ENOMEM);
 	}
@@ -214,7 +214,7 @@ struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq
 	struct kmem_cache *cache = mempool->pool_data;

 	if (rreq->gfp == GFP_KERNEL)
-		subreq = mempool->alloc(rreq->gfp, mempool->pool_data);
+		subreq = mempool_alloc_noreserve(mempool, rreq->gfp);
 	else
 		subreq = mempool_alloc(mempool, rreq->gfp);
 	if (!subreq)
diff --git a/fs/netfs/rolling_buffer.c b/fs/netfs/rolling_buffer.c
index 424e77a9a109..d30d5ef6d86e 100644
--- a/fs/netfs/rolling_buffer.c
+++ b/fs/netfs/rolling_buffer.c
@@ -29,7 +29,7 @@ struct folio_queue *netfs_folioq_alloc(unsigned int rreq_id, gfp_t gfp,
 	struct folio_queue *fq;

 	if (gfp == GFP_KERNEL)
-		fq = netfs_folioq_pool.alloc(gfp, netfs_folioq_pool.pool_data);
+		fq = mempool_alloc_noreserve(&netfs_folioq_pool, gfp);
 	else
 		fq = mempool_alloc(&netfs_folioq_pool, gfp);
 	if (fq) {
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index a0fa6d43e0dc..6da502aef2f7 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -70,6 +70,13 @@ int mempool_alloc_bulk_noprof(struct mempool *pool, void **elem,
 #define mempool_alloc_bulk(...)						\
 	alloc_hooks(mempool_alloc_bulk_noprof(__VA_ARGS__))

+/*
+ * Allocate a new element without dipping into the pool's reserves or
+ * waiting.  Returns NULL on failure.
+ */
+#define mempool_alloc_noreserve(_pool, _gfp)				\
+	alloc_hooks((_pool)->alloc(_gfp, (_pool)->pool_data))
+
 void *mempool_alloc_preallocated(struct mempool *pool) __malloc;
 void mempool_free(void *element, struct mempool *pool);
 unsigned int mempool_free_bulk(struct mempool *pool, void **elem,