mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
rhashtable: Add bucket_table_free_atomic() helper
rhashtable_insert_rehash() allocates a new bucket table with GFP_ATOMIC, as it is called from an RCU read-side critical section. If rhashtable_rehash_attach() then fails, the new table is freed via kvfree(). This is unsafe, since kvfree() may fall back to vfree() for vmalloc-backed allocations, which can sleep and trigger: BUG: sleeping function called from invalid context Add bucket_table_free_atomic(), which uses kvfree_atomic() so the table can be freed safely from non-sleeping context. Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
dad0d91cc2
commit
d1fa83ecac
|
|
@ -114,6 +114,14 @@ static void bucket_table_free(const struct bucket_table *tbl)
|
|||
kvfree(tbl);
|
||||
}
|
||||
|
||||
static void bucket_table_free_atomic(const struct bucket_table *tbl)
|
||||
{
|
||||
if (tbl->nest)
|
||||
nested_bucket_table_free(tbl);
|
||||
|
||||
kvfree_atomic(tbl);
|
||||
}
|
||||
|
||||
static void bucket_table_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
bucket_table_free(container_of(head, struct bucket_table, rcu));
|
||||
|
|
@ -496,7 +504,7 @@ static int rhashtable_insert_rehash(struct rhashtable *ht,
|
|||
|
||||
err = rhashtable_rehash_attach(ht, tbl, new_tbl);
|
||||
if (err) {
|
||||
bucket_table_free(new_tbl);
|
||||
bucket_table_free_atomic(new_tbl);
|
||||
if (err == -EEXIST)
|
||||
err = 0;
|
||||
} else
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user