diff options
| author | Liam R. Howlett (Oracle) <liam@infradead.org> | 2026-06-30 15:08:37 -0400 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-07-25 21:49:10 -0700 |
| commit | 7a043f6fc714139a3fa04b5f010f67cefa63a9ec (patch) | |
| tree | f2c012bf53582aaf0ac9f9f0b67e308965c7f09f /lib | |
| parent | faa5f9de97c3eeeba643f37a112d6a95faf693c3 (diff) | |
| download | linux-next-7a043f6fc714139a3fa04b5f010f67cefa63a9ec.tar.gz linux-next-7a043f6fc714139a3fa04b5f010f67cefa63a9ec.zip | |
maple_tree: document that erase may use GFP_KERNEL for allocations
State that the mas_erase() and mtree_erase() functions may use GFP_KERNEL
on allocation retry. Don't just depend on people reading the
documentation by adding a check that will warn of the use.
Link: https://lore.kernel.org/20260630190843.3563858-14-liam@infradead.org
Signed-off-by: Liam R. Howlett (Oracle) <liam@infradead.org>
Reviewed-by: Rik van Riel <riel@surriel.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Chris Mason <clm@meta.com>
Cc: Chuck Lever <cel@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Joe Perches <joe@perches.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/maple_tree.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 1bc177bf42f9..15e8081f6180 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -5657,6 +5657,10 @@ EXPORT_SYMBOL_GPL(mas_find_range_rev); * Searches for @mas->index, sets @mas->index and @mas->last to the range and * erases that range. * + * Note that erase requires allocations and will use GFP_KERNEL to do so if + * necessary. If the allocation fails, the internal lock will be dropped to + * retry. + * * Return: the entry that was erased or %NULL, @mas->index and @mas->last are updated. */ void *mas_erase(struct ma_state *mas) @@ -5665,13 +5669,21 @@ void *mas_erase(struct ma_state *mas) unsigned long index = mas->index; MA_WR_STATE(wr_mas, mas, NULL); + /* + * In low memory situations, the allocation is retried with the gfp flag + * GFP_KERNEL. The internal spinlock is dropped in mas_nomem(), however + * the external lock is not dropped. + */ + if (mt_external_lock(mas->tree)) + might_alloc(GFP_KERNEL); + if (!mas_is_active(mas) || !mas_is_start(mas)) mas->status = ma_start; write_retry: entry = mas_state_walk(mas); if (!entry) - return NULL; + goto out; /* Must reset to ensure spanning writes of last slot are detected */ mas_reset(mas); @@ -5682,8 +5694,10 @@ write_retry: goto write_retry; } - if (mas_is_err(mas)) + if (mas_is_err(mas)) { + entry = NULL; goto out; + } mas_wr_store_entry(&wr_mas); out: @@ -6011,6 +6025,10 @@ EXPORT_SYMBOL(mtree_alloc_rrange); * Erasing is the same as a walk to an entry then a store of a NULL to that * ENTIRE range. In fact, it is implemented as such using the advanced API. * + * Note that erase requires allocations and will use GFP_KERNEL to do so if + * necessary. If the allocation fails, the internal lock will be dropped to + * retry. + * * Return: The entry stored at the @index or %NULL */ void *mtree_erase(struct maple_tree *mt, unsigned long index) @@ -6020,6 +6038,7 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index) MA_STATE(mas, mt, index, index); trace_ma_op(TP_FCT, &mas); + might_alloc(GFP_KERNEL); mtree_lock(mt); entry = mas_erase(&mas); mtree_unlock(mt); |
