Remove KMC_KMEM and KMC_VMEM
`KMC_KMEM` and `KMC_VMEM` are now unused since all SPL-implemented caches are `KMC_KVMEM`. KMC_KMEM: Given the default value of `spl_kmem_cache_kmem_limit`, we don't use kmalloc to back the SPL caches, instead we use kvmalloc (KMC_KVMEM). The flag, module parameter, /proc entries, and associated code are removed. KMC_VMEM: This flag is not used, and kvmalloc() is always preferable to vmalloc(). The flag, /proc entries, and associated code are removed. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Matthew Ahrens <mahrens@delphix.com> Closes #10673
This commit is contained in:
parent
3df0c2fa32
commit
994de7e4b7
|
@ -37,8 +37,6 @@
|
|||
*/
|
||||
typedef enum kmc_bit {
|
||||
KMC_BIT_NODEBUG = 1, /* Default behavior */
|
||||
KMC_BIT_KMEM = 5, /* Use kmem cache */
|
||||
KMC_BIT_VMEM = 6, /* Use vmem cache */
|
||||
KMC_BIT_KVMEM = 7, /* Use kvmalloc linux allocator */
|
||||
KMC_BIT_SLAB = 8, /* Use Linux slab cache */
|
||||
KMC_BIT_DEADLOCKED = 14, /* Deadlock detected */
|
||||
|
@ -60,8 +58,6 @@ typedef enum kmem_cbrc {
|
|||
} kmem_cbrc_t;
|
||||
|
||||
#define KMC_NODEBUG (1 << KMC_BIT_NODEBUG)
|
||||
#define KMC_KMEM (1 << KMC_BIT_KMEM)
|
||||
#define KMC_VMEM (1 << KMC_BIT_VMEM)
|
||||
#define KMC_KVMEM (1 << KMC_BIT_KVMEM)
|
||||
#define KMC_SLAB (1 << KMC_BIT_SLAB)
|
||||
#define KMC_DEADLOCKED (1 << KMC_BIT_DEADLOCKED)
|
||||
|
|
|
@ -402,8 +402,6 @@ void procfs_list_add(procfs_list_t *procfs_list, void *p);
|
|||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define KMC_KMEM 0x0
|
||||
#define KMC_VMEM 0x0
|
||||
#define KMC_KVMEM 0x0
|
||||
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
|
||||
#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
|
||||
|
|
|
@ -131,37 +131,6 @@ cutoff of 16K was determined to be optimal for architectures using 4K pages.
|
|||
Default value: \fB16,384\fR
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
\fBspl_kmem_cache_kmem_limit\fR (uint)
|
||||
.ad
|
||||
.RS 12n
|
||||
Depending on the size of a cache object it may be backed by kmalloc()'d
|
||||
or vmalloc()'d memory. This is because the size of the required allocation
|
||||
greatly impacts the best way to allocate the memory.
|
||||
.sp
|
||||
When objects are small and only a small number of memory pages need to be
|
||||
allocated, ideally just one, then kmalloc() is very efficient. However,
|
||||
when allocating multiple pages with kmalloc() it gets increasingly expensive
|
||||
because the pages must be physically contiguous.
|
||||
.sp
|
||||
For this reason we shift to vmalloc() for slabs of large objects which
|
||||
which removes the need for contiguous pages. We cannot use vmalloc() in
|
||||
all cases because there is significant locking overhead involved. This
|
||||
function takes a single global lock over the entire virtual address range
|
||||
which serializes all allocations. Using slightly different allocation
|
||||
functions for small and large objects allows us to handle a wide range of
|
||||
object sizes.
|
||||
.sp
|
||||
The \fBspl_kmem_cache_kmem_limit\fR value is used to determine this cutoff
|
||||
size. One quarter the PAGE_SIZE is used as the default value because
|
||||
\fBspl_kmem_cache_obj_per_slab\fR defaults to 16. This means that at
|
||||
most we will need to allocate four contiguous pages.
|
||||
.sp
|
||||
Default value: \fBPAGE_SIZE/4\fR
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
|
|
|
@ -112,17 +112,6 @@ module_param(spl_kmem_cache_slab_limit, uint, 0644);
|
|||
MODULE_PARM_DESC(spl_kmem_cache_slab_limit,
|
||||
"Objects less than N bytes use the Linux slab");
|
||||
|
||||
/*
|
||||
* This value defaults to a threshold designed to avoid allocations which
|
||||
* have been deemed costly by the kernel.
|
||||
*/
|
||||
unsigned int spl_kmem_cache_kmem_limit =
|
||||
((1 << (PAGE_ALLOC_COSTLY_ORDER - 1)) * PAGE_SIZE) /
|
||||
SPL_KMEM_CACHE_OBJ_PER_SLAB;
|
||||
module_param(spl_kmem_cache_kmem_limit, uint, 0644);
|
||||
MODULE_PARM_DESC(spl_kmem_cache_kmem_limit,
|
||||
"Objects less than N bytes use the kmalloc");
|
||||
|
||||
/*
|
||||
* The number of threads available to allocate new slabs for caches. This
|
||||
* should not need to be tuned but it is available for performance analysis.
|
||||
|
@ -177,12 +166,7 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags)
|
|||
gfp_t lflags = kmem_flags_convert(flags);
|
||||
void *ptr;
|
||||
|
||||
if (skc->skc_flags & KMC_KMEM) {
|
||||
ASSERT(ISP2(size));
|
||||
ptr = (void *)__get_free_pages(lflags, get_order(size));
|
||||
} else {
|
||||
ptr = spl_vmalloc(size, lflags | __GFP_HIGHMEM);
|
||||
}
|
||||
ptr = spl_vmalloc(size, lflags | __GFP_HIGHMEM);
|
||||
|
||||
/* Resulting allocated memory will be page aligned */
|
||||
ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));
|
||||
|
@ -205,12 +189,7 @@ kv_free(spl_kmem_cache_t *skc, void *ptr, int size)
|
|||
if (current->reclaim_state)
|
||||
current->reclaim_state->reclaimed_slab += size >> PAGE_SHIFT;
|
||||
|
||||
if (skc->skc_flags & KMC_KMEM) {
|
||||
ASSERT(ISP2(size));
|
||||
free_pages((unsigned long)ptr, get_order(size));
|
||||
} else {
|
||||
vfree(ptr);
|
||||
}
|
||||
vfree(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -563,18 +542,6 @@ spl_slab_size(spl_kmem_cache_t *skc, uint32_t *objs, uint32_t *size)
|
|||
max_size = (spl_kmem_cache_max_size * 1024 * 1024);
|
||||
tgt_size = (spl_kmem_cache_obj_per_slab * obj_size + sks_size);
|
||||
|
||||
/*
|
||||
* KMC_KMEM slabs are allocated by __get_free_pages() which
|
||||
* rounds up to the nearest order. Knowing this the size
|
||||
* should be rounded up to the next power of two with a hard
|
||||
* maximum defined by the maximum allowed allocation order.
|
||||
*/
|
||||
if (skc->skc_flags & KMC_KMEM) {
|
||||
max_size = SPL_MAX_ORDER_NR_PAGES * PAGE_SIZE;
|
||||
tgt_size = MIN(max_size,
|
||||
PAGE_SIZE * (1 << MAX(get_order(tgt_size) - 1, 1)));
|
||||
}
|
||||
|
||||
if (tgt_size <= max_size) {
|
||||
tgt_objs = (tgt_size - sks_size) / obj_size;
|
||||
} else {
|
||||
|
@ -714,8 +681,6 @@ spl_magazine_destroy(spl_kmem_cache_t *skc)
|
|||
* priv cache private data for ctor/dtor/reclaim
|
||||
* vmp unused must be NULL
|
||||
* flags
|
||||
* KMC_KMEM Force SPL kmem backed cache
|
||||
* KMC_VMEM Force SPL vmem backed cache
|
||||
* KMC_KVMEM Force kvmem backed SPL cache
|
||||
* KMC_SLAB Force Linux slab backed cache
|
||||
* KMC_NODEBUG Disable debugging (unsupported)
|
||||
|
@ -801,7 +766,7 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
|||
* linuxslab) then select a cache type based on the object size
|
||||
* and default tunables.
|
||||
*/
|
||||
if (!(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_SLAB | KMC_KVMEM))) {
|
||||
if (!(skc->skc_flags & (KMC_SLAB | KMC_KVMEM))) {
|
||||
if (spl_kmem_cache_slab_limit &&
|
||||
size <= (size_t)spl_kmem_cache_slab_limit) {
|
||||
/*
|
||||
|
@ -809,13 +774,6 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
|||
* use the Linux slab for better space-efficiency.
|
||||
*/
|
||||
skc->skc_flags |= KMC_SLAB;
|
||||
} else if (spl_obj_size(skc) <= spl_kmem_cache_kmem_limit) {
|
||||
/*
|
||||
* Small objects, less than spl_kmem_cache_kmem_limit
|
||||
* per object should use kmem because their slabs are
|
||||
* small.
|
||||
*/
|
||||
skc->skc_flags |= KMC_KMEM;
|
||||
} else {
|
||||
/*
|
||||
* All other objects are considered large and are
|
||||
|
@ -828,7 +786,7 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
|||
/*
|
||||
* Given the type of slab allocate the required resources.
|
||||
*/
|
||||
if (skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_KVMEM)) {
|
||||
if (skc->skc_flags & KMC_KVMEM) {
|
||||
rc = spl_slab_size(skc,
|
||||
&skc->skc_slab_objs, &skc->skc_slab_size);
|
||||
if (rc)
|
||||
|
@ -905,7 +863,7 @@ spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
|
|||
taskqid_t id;
|
||||
|
||||
ASSERT(skc->skc_magic == SKC_MAGIC);
|
||||
ASSERT(skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_KVMEM | KMC_SLAB));
|
||||
ASSERT(skc->skc_flags & (KMC_KVMEM | KMC_SLAB));
|
||||
|
||||
down_write(&spl_kmem_cache_sem);
|
||||
list_del_init(&skc->skc_list);
|
||||
|
@ -927,7 +885,7 @@ spl_kmem_cache_destroy(spl_kmem_cache_t *skc)
|
|||
*/
|
||||
wait_event(wq, atomic_read(&skc->skc_ref) == 0);
|
||||
|
||||
if (skc->skc_flags & (KMC_KMEM | KMC_VMEM | KMC_KVMEM)) {
|
||||
if (skc->skc_flags & KMC_KVMEM) {
|
||||
spl_magazine_destroy(skc);
|
||||
spl_slab_reclaim(skc);
|
||||
} else {
|
||||
|
@ -1079,21 +1037,13 @@ spl_cache_grow(spl_kmem_cache_t *skc, int flags, void **obj)
|
|||
}
|
||||
|
||||
/*
|
||||
* To reduce the overhead of context switch and improve NUMA locality,
|
||||
* it tries to allocate a new slab in the current process context with
|
||||
* KM_NOSLEEP flag. If it fails, it will launch a new taskq to do the
|
||||
* allocation.
|
||||
* Note: It would be nice to reduce the overhead of context switch
|
||||
* and improve NUMA locality, by trying to allocate a new slab in the
|
||||
* current process context with KM_NOSLEEP flag.
|
||||
*
|
||||
* However, this can't be applied to KVM_VMEM due to a bug that
|
||||
* However, this can't be applied to vmem/kvmem due to a bug that
|
||||
* spl_vmalloc() doesn't honor gfp flags in page table allocation.
|
||||
*/
|
||||
if (!(skc->skc_flags & KMC_VMEM) && !(skc->skc_flags & KMC_KVMEM)) {
|
||||
rc = __spl_cache_grow(skc, flags | KM_NOSLEEP);
|
||||
if (rc == 0) {
|
||||
wake_up_all(&skc->skc_waitq);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is handled by dispatching a work request to the global work
|
||||
|
|
|
@ -631,60 +631,6 @@ static struct ctl_table spl_kmem_table[] = {
|
|||
.proc_handler = &proc_doulongvec_minmax,
|
||||
},
|
||||
#endif /* DEBUG_KMEM */
|
||||
{
|
||||
.procname = "slab_kmem_total",
|
||||
.data = (void *)(KMC_KMEM | KMC_TOTAL),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_kmem_alloc",
|
||||
.data = (void *)(KMC_KMEM | KMC_ALLOC),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_kmem_max",
|
||||
.data = (void *)(KMC_KMEM | KMC_MAX),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_vmem_total",
|
||||
.data = (void *)(KMC_VMEM | KMC_TOTAL),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_vmem_alloc",
|
||||
.data = (void *)(KMC_VMEM | KMC_ALLOC),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_vmem_max",
|
||||
.data = (void *)(KMC_VMEM | KMC_MAX),
|
||||
.maxlen = sizeof (unsigned long),
|
||||
.extra1 = &table_min,
|
||||
.extra2 = &table_max,
|
||||
.mode = 0444,
|
||||
.proc_handler = &proc_doslab,
|
||||
},
|
||||
{
|
||||
.procname = "slab_kvmem_total",
|
||||
.data = (void *)(KMC_KVMEM | KMC_TOTAL),
|
||||
|
|
Loading…
Reference in New Issue