mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 11:29:36 +03:00
Remove kmem_set_warning() interface replace with __GFP_NOWARN flag.
Remove the kmem_set_warning() hack used by the kmem-splat regression tests with a per-allocation flag called __GFP_NOWARN. This matches the lower level linux flag of similar by slightly different function. The idea is you can then explicitly set this flag on requests where you know your breaking the max 8k rule but you need/want to do it anyway. This is currently used by the regression tests where we intentionally push things to the limit but don't want the log noise. Additionally, we are forced to use it in spl_kmem_cache_create() because by default NR_CPUS is very large and theres no easy way to handle that. Finally, I've added a stack_dump() call to the warning when it is trigger to make to clear exactly where the allocation is taking place.
This commit is contained in:
parent
627a74972c
commit
5198ea0e71
@ -228,13 +228,11 @@ unsigned long long kmem_alloc_max = 0;
|
|||||||
atomic_t vmem_alloc_used = ATOMIC_INIT(0);
|
atomic_t vmem_alloc_used = ATOMIC_INIT(0);
|
||||||
unsigned long long vmem_alloc_max = 0;
|
unsigned long long vmem_alloc_max = 0;
|
||||||
# endif /* _LP64 */
|
# endif /* _LP64 */
|
||||||
int kmem_warning_flag = 1;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(kmem_alloc_used);
|
EXPORT_SYMBOL(kmem_alloc_used);
|
||||||
EXPORT_SYMBOL(kmem_alloc_max);
|
EXPORT_SYMBOL(kmem_alloc_max);
|
||||||
EXPORT_SYMBOL(vmem_alloc_used);
|
EXPORT_SYMBOL(vmem_alloc_used);
|
||||||
EXPORT_SYMBOL(vmem_alloc_max);
|
EXPORT_SYMBOL(vmem_alloc_max);
|
||||||
EXPORT_SYMBOL(kmem_warning_flag);
|
|
||||||
|
|
||||||
/* When DEBUG_KMEM_TRACKING is enabled not only will total bytes be tracked
|
/* When DEBUG_KMEM_TRACKING is enabled not only will total bytes be tracked
|
||||||
* but also the location of every alloc and free. When the SPL module is
|
* but also the location of every alloc and free. When the SPL module is
|
||||||
@ -280,12 +278,7 @@ EXPORT_SYMBOL(vmem_lock);
|
|||||||
EXPORT_SYMBOL(vmem_table);
|
EXPORT_SYMBOL(vmem_table);
|
||||||
EXPORT_SYMBOL(vmem_list);
|
EXPORT_SYMBOL(vmem_list);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
int kmem_set_warning(int flag) { return (kmem_warning_flag = !!flag); }
|
|
||||||
#else
|
|
||||||
int kmem_set_warning(int flag) { return 0; }
|
|
||||||
#endif
|
#endif
|
||||||
EXPORT_SYMBOL(kmem_set_warning);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Slab allocation interfaces
|
* Slab allocation interfaces
|
||||||
@ -397,10 +390,12 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
|||||||
} else {
|
} else {
|
||||||
/* Marked unlikely because we should never be doing this,
|
/* Marked unlikely because we should never be doing this,
|
||||||
* we tolerate to up 2 pages but a single page is best. */
|
* we tolerate to up 2 pages but a single page is best. */
|
||||||
if (unlikely((size) > (PAGE_SIZE * 2)) && kmem_warning_flag)
|
if (unlikely((size > PAGE_SIZE*2) && !(flags & __GFP_NOWARN))) {
|
||||||
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
|
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags,
|
(unsigned long long) size, flags,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
|
spl_debug_dumpstack(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* We use kstrdup() below because the string pointed to by
|
/* We use kstrdup() below because the string pointed to by
|
||||||
* __FUNCTION__ might not be available by the time we want
|
* __FUNCTION__ might not be available by the time we want
|
||||||
@ -610,10 +605,12 @@ kmem_alloc_debug(size_t size, int flags, const char *func, int line,
|
|||||||
|
|
||||||
/* Marked unlikely because we should never be doing this,
|
/* Marked unlikely because we should never be doing this,
|
||||||
* we tolerate to up 2 pages but a single page is best. */
|
* we tolerate to up 2 pages but a single page is best. */
|
||||||
if (unlikely(size > (PAGE_SIZE * 2)) && kmem_warning_flag)
|
if (unlikely((size > PAGE_SIZE * 2) && !(flags & __GFP_NOWARN))) {
|
||||||
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
|
CWARN("Large kmem_alloc(%llu, 0x%x) (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags,
|
(unsigned long long) size, flags,
|
||||||
kmem_alloc_used_read(), kmem_alloc_max);
|
kmem_alloc_used_read(), kmem_alloc_max);
|
||||||
|
spl_debug_dumpstack(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use the correct allocator */
|
/* Use the correct allocator */
|
||||||
if (node_alloc) {
|
if (node_alloc) {
|
||||||
@ -1242,8 +1239,13 @@ spl_kmem_cache_create(char *name, size_t size, size_t align,
|
|||||||
if (current_thread_info()->preempt_count || irqs_disabled())
|
if (current_thread_info()->preempt_count || irqs_disabled())
|
||||||
kmem_flags = KM_NOSLEEP;
|
kmem_flags = KM_NOSLEEP;
|
||||||
|
|
||||||
/* Allocate new cache memory and initialize. */
|
/* Allocate memry for a new cache an initialize it. Unfortunately,
|
||||||
skc = (spl_kmem_cache_t *)kmem_zalloc(sizeof(*skc), kmem_flags);
|
* this usually ends up being a large allocation of ~32k because
|
||||||
|
* we need to allocate enough memory for the worst case number of
|
||||||
|
* cpus in the magazine, skc_mag[NR_CPUS]. Because of this we
|
||||||
|
* explicitly pass __GFP_NOWARN to suppress the kmem warning */
|
||||||
|
skc = (spl_kmem_cache_t *)kmem_zalloc(sizeof(*skc),
|
||||||
|
kmem_flags | __GFP_NOWARN);
|
||||||
if (skc == NULL)
|
if (skc == NULL)
|
||||||
RETURN(NULL);
|
RETURN(NULL);
|
||||||
|
|
||||||
|
@ -90,15 +90,11 @@ splat_kmem_test1(struct file *file, void *arg)
|
|||||||
int size = PAGE_SIZE;
|
int size = PAGE_SIZE;
|
||||||
int i, count, rc = 0;
|
int i, count, rc = 0;
|
||||||
|
|
||||||
/* We are intentionally going to push kmem_alloc to its max
|
|
||||||
* allocation size, so suppress the console warnings for now */
|
|
||||||
kmem_set_warning(0);
|
|
||||||
|
|
||||||
while ((!rc) && (size <= (PAGE_SIZE * 32))) {
|
while ((!rc) && (size <= (PAGE_SIZE * 32))) {
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
|
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
|
||||||
ptr[i] = kmem_alloc(size, KM_SLEEP);
|
ptr[i] = kmem_alloc(size, KM_SLEEP | __GFP_NOWARN);
|
||||||
if (ptr[i])
|
if (ptr[i])
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -116,8 +112,6 @@ splat_kmem_test1(struct file *file, void *arg)
|
|||||||
size *= 2;
|
size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
kmem_set_warning(1);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,15 +122,11 @@ splat_kmem_test2(struct file *file, void *arg)
|
|||||||
int size = PAGE_SIZE;
|
int size = PAGE_SIZE;
|
||||||
int i, j, count, rc = 0;
|
int i, j, count, rc = 0;
|
||||||
|
|
||||||
/* We are intentionally going to push kmem_alloc to its max
|
|
||||||
* allocation size, so suppress the console warnings for now */
|
|
||||||
kmem_set_warning(0);
|
|
||||||
|
|
||||||
while ((!rc) && (size <= (PAGE_SIZE * 32))) {
|
while ((!rc) && (size <= (PAGE_SIZE * 32))) {
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
|
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
|
||||||
ptr[i] = kmem_zalloc(size, KM_SLEEP);
|
ptr[i] = kmem_zalloc(size, KM_SLEEP | __GFP_NOWARN);
|
||||||
if (ptr[i])
|
if (ptr[i])
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -166,8 +156,6 @@ splat_kmem_test2(struct file *file, void *arg)
|
|||||||
size *= 2;
|
size *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
kmem_set_warning(1);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user