mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-05-03 23:42:43 +03:00
Optimize vmem_alloc() retry path
For performance reasons the reworked kmem code maps vmem_alloc() to kmalloc_node() for allocations less than spa_kmem_alloc_max. This allows for more concurrency in the system and less contention of the virtual address space. Generally, this is a good thing. However, in the case when the kmalloc_node() fails it makes little sense to retry it using kmalloc_node() again. It will likely fail in exactly the same way. A smarter strategy is to abandon this optimization and retry using spl_vmalloc() which is very likely to succeed. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Closes #428
This commit is contained in:
parent
54cccfc2e3
commit
c7db36a3c4
@ -149,6 +149,7 @@ inline void *
|
|||||||
spl_kmem_alloc_impl(size_t size, int flags, int node)
|
spl_kmem_alloc_impl(size_t size, int flags, int node)
|
||||||
{
|
{
|
||||||
gfp_t lflags = kmem_flags_convert(flags);
|
gfp_t lflags = kmem_flags_convert(flags);
|
||||||
|
int use_vmem = 0;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -182,7 +183,7 @@ spl_kmem_alloc_impl(size_t size, int flags, int node)
|
|||||||
* impact performance so frequently manipulating the virtual
|
* impact performance so frequently manipulating the virtual
|
||||||
* address space is strongly discouraged.
|
* address space is strongly discouraged.
|
||||||
*/
|
*/
|
||||||
if (unlikely(size > spl_kmem_alloc_max)) {
|
if ((size > spl_kmem_alloc_max) || use_vmem) {
|
||||||
if (flags & KM_VMEM) {
|
if (flags & KM_VMEM) {
|
||||||
ptr = spl_vmalloc(size, lflags, PAGE_KERNEL);
|
ptr = spl_vmalloc(size, lflags, PAGE_KERNEL);
|
||||||
} else {
|
} else {
|
||||||
@ -195,6 +196,15 @@ spl_kmem_alloc_impl(size_t size, int flags, int node)
|
|||||||
if (likely(ptr) || (flags & KM_NOSLEEP))
|
if (likely(ptr) || (flags & KM_NOSLEEP))
|
||||||
return (ptr);
|
return (ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For vmem_alloc() and vmem_zalloc() callers retry immediately
|
||||||
|
* using spl_vmalloc() which is unlikely to fail.
|
||||||
|
*/
|
||||||
|
if ((flags & KM_VMEM) && (use_vmem == 0)) {
|
||||||
|
use_vmem = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(__ratelimit(&kmem_alloc_ratelimit_state))) {
|
if (unlikely(__ratelimit(&kmem_alloc_ratelimit_state))) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Possible memory allocation deadlock: "
|
"Possible memory allocation deadlock: "
|
||||||
|
Loading…
Reference in New Issue
Block a user