mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
Never spin in kmem_cache_alloc()
If we are reaping from the cache and a concurrent allocation occurs then the caller must block until the reaping is complete. This is signaled by the clearing of the KMC_BIT_REAPING bit. Otherwise the caller will be in a tight loop which takes and releases the skc->skc_cache lock. When there are multiple concurrent callers the system will thrash on the lock and appear to lock up. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
a1af8fb1ea
commit
dc1b30224f
@ -1725,6 +1725,13 @@ spl_cache_grow_wait(spl_kmem_cache_t *skc)
|
|||||||
return !test_bit(KMC_BIT_GROWING, &skc->skc_flags);
|
return !test_bit(KMC_BIT_GROWING, &skc->skc_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spl_cache_reclaim_wait(void *word)
|
||||||
|
{
|
||||||
|
schedule();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No available objects on any slabs, create a new slab.
|
* No available objects on any slabs, create a new slab.
|
||||||
*/
|
*/
|
||||||
@ -1739,12 +1746,14 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
|||||||
*obj = NULL;
|
*obj = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before allocating a new slab check if the slab is being reaped.
|
* Before allocating a new slab wait for any reaping to complete and
|
||||||
* If it is there is a good chance we can wait until it finishes
|
* then return so the local magazine can be rechecked for new objects.
|
||||||
* and then use one of the newly freed but not aged-out slabs.
|
|
||||||
*/
|
*/
|
||||||
if (test_bit(KMC_BIT_REAPING, &skc->skc_flags))
|
if (test_bit(KMC_BIT_REAPING, &skc->skc_flags)) {
|
||||||
SRETURN(-EAGAIN);
|
rc = wait_on_bit(&skc->skc_flags, KMC_BIT_REAPING,
|
||||||
|
spl_cache_reclaim_wait, TASK_UNINTERRUPTIBLE);
|
||||||
|
SRETURN(rc ? rc : -EAGAIN);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is handled by dispatching a work request to the global work
|
* This is handled by dispatching a work request to the global work
|
||||||
@ -2156,6 +2165,9 @@ spl_kmem_cache_reap_now(spl_kmem_cache_t *skc, int count)
|
|||||||
/* Reclaim from the cache, ignoring it's age and delay. */
|
/* Reclaim from the cache, ignoring it's age and delay. */
|
||||||
spl_slab_reclaim(skc, count, 1);
|
spl_slab_reclaim(skc, count, 1);
|
||||||
clear_bit(KMC_BIT_REAPING, &skc->skc_flags);
|
clear_bit(KMC_BIT_REAPING, &skc->skc_flags);
|
||||||
|
smp_mb__after_clear_bit();
|
||||||
|
wake_up_bit(&skc->skc_flags, KMC_BIT_REAPING);
|
||||||
|
|
||||||
atomic_dec(&skc->skc_ref);
|
atomic_dec(&skc->skc_ref);
|
||||||
|
|
||||||
SEXIT;
|
SEXIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user