mirror of
https://github.com/torvalds/linux.git
synced 2026-09-27 11:02:03 +02:00
netfs: Fix missing alloc tagging of direct mempool allocations
Commit1d78d56c43("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:1d78d56c43("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>
This commit is contained in:
parent
35d442ed1f
commit
b78b728e21
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user