mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
* spl-09-fix-kmem-track-oops.patch
This fixes an oops when unloading the modules, in the case where memory tracking was enabled and there were memory leaks. The comment in the code explains what was the problem. * spl-10-fix-assert-verify-ndebug.patch This fixes ASSERT*() and VERIFY*() macros in non-debug builds. VERIFY*() macros are supposed to check the condition and panic even in production builds, and ASSERT*() macros don't need to evaluate the arguments. Also some 32-bit fixes. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@165 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
parent
c22e7a427b
commit
c8e60837b7
@ -218,17 +218,32 @@ struct page_collection {
|
|||||||
#define __ASSERT_TAGE_INVARIANT(x) ((void)0)
|
#define __ASSERT_TAGE_INVARIANT(x) ((void)0)
|
||||||
#define ASSERT(x) ((void)0)
|
#define ASSERT(x) ((void)0)
|
||||||
#define ASSERTF(x, y, z...) ((void)0)
|
#define ASSERTF(x, y, z...) ((void)0)
|
||||||
#define VERIFY(x) ((void)(x))
|
#define VERIFY(cond) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!(cond))) { \
|
||||||
|
printk(KERN_ERR "VERIFY(" #cond ") failed\n"); \
|
||||||
|
SBUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3_IMPL(x, y, z, t, f, c) if ((x) == (z)) ((void)0)
|
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
|
||||||
|
do { \
|
||||||
|
if (!((TYPE)(LEFT) OP (TYPE)(RIGHT))) { \
|
||||||
|
printk(KERN_ERR "VERIFY3(" #LEFT " " #OP " " #RIGHT \
|
||||||
|
" failed (" FMT ", " FMT ")\n", CAST (LEFT), \
|
||||||
|
CAST (RIGHT)); \
|
||||||
|
SBUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long))
|
#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
|
||||||
#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned long))
|
#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu", \
|
||||||
|
(unsigned long long))
|
||||||
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
||||||
|
|
||||||
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
|
#define ASSERT3S(x,y,z) ((void)0)
|
||||||
#define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
|
#define ASSERT3U(x,y,z) ((void)0)
|
||||||
#define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
|
#define ASSERT3P(x,y,z) ((void)0)
|
||||||
|
|
||||||
#else /* NDEBUG */
|
#else /* NDEBUG */
|
||||||
|
|
||||||
@ -270,7 +285,7 @@ do { \
|
|||||||
#define __ASSERT(cond) \
|
#define __ASSERT(cond) \
|
||||||
do { \
|
do { \
|
||||||
if (unlikely(!(cond))) { \
|
if (unlikely(!(cond))) { \
|
||||||
printk(KERN_ERR "ASSERTION(" #cond ") failed"); \
|
printk(KERN_ERR "ASSERTION(" #cond ") failed\n"); \
|
||||||
BUG(); \
|
BUG(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -322,8 +337,9 @@ do { \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long))
|
#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%lld", (long long))
|
||||||
#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned long))
|
#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%llu`", \
|
||||||
|
(unsigned long long))
|
||||||
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
#define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
|
||||||
|
|
||||||
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
|
#define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
|
||||||
|
@ -222,6 +222,18 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
|||||||
(unsigned long long) size, flags,
|
(unsigned long long) size, flags,
|
||||||
atomic64_read(&kmem_alloc_used), kmem_alloc_max);
|
atomic64_read(&kmem_alloc_used), kmem_alloc_max);
|
||||||
|
|
||||||
|
/* We use kstrdup() below because the string pointed to by
|
||||||
|
* __FUNCTION__ might not be available by the time we want
|
||||||
|
* to print it since the module might have been unloaded. */
|
||||||
|
dptr->kd_func = kstrdup(func, flags & ~__GFP_ZERO);
|
||||||
|
if (unlikely(dptr->kd_func == NULL)) {
|
||||||
|
kfree(dptr);
|
||||||
|
CWARN("kstrdup() failed in kmem_alloc(%llu, 0x%x) "
|
||||||
|
"(%lld/%llu)\n", (unsigned long long) size, flags,
|
||||||
|
atomic64_read(&kmem_alloc_used), kmem_alloc_max);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Use the correct allocator */
|
/* Use the correct allocator */
|
||||||
if (node_alloc) {
|
if (node_alloc) {
|
||||||
ASSERT(!(flags & __GFP_ZERO));
|
ASSERT(!(flags & __GFP_ZERO));
|
||||||
@ -233,6 +245,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
|
kfree(dptr->kd_func);
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
|
CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags,
|
(unsigned long long) size, flags,
|
||||||
@ -251,7 +264,6 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
|
|||||||
|
|
||||||
dptr->kd_addr = ptr;
|
dptr->kd_addr = ptr;
|
||||||
dptr->kd_size = size;
|
dptr->kd_size = size;
|
||||||
dptr->kd_func = func;
|
|
||||||
dptr->kd_line = line;
|
dptr->kd_line = line;
|
||||||
|
|
||||||
spin_lock_irqsave(&kmem_lock, irq_flags);
|
spin_lock_irqsave(&kmem_lock, irq_flags);
|
||||||
@ -294,6 +306,8 @@ kmem_free_track(void *ptr, size_t size)
|
|||||||
(unsigned long long) size, atomic64_read(&kmem_alloc_used),
|
(unsigned long long) size, atomic64_read(&kmem_alloc_used),
|
||||||
kmem_alloc_max);
|
kmem_alloc_max);
|
||||||
|
|
||||||
|
kfree(dptr->kd_func);
|
||||||
|
|
||||||
memset(dptr, 0x5a, sizeof(kmem_debug_t));
|
memset(dptr, 0x5a, sizeof(kmem_debug_t));
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
|
|
||||||
@ -319,10 +333,23 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
|||||||
CWARN("vmem_alloc(%ld, 0x%x) debug failed\n",
|
CWARN("vmem_alloc(%ld, 0x%x) debug failed\n",
|
||||||
sizeof(kmem_debug_t), flags);
|
sizeof(kmem_debug_t), flags);
|
||||||
} else {
|
} else {
|
||||||
|
/* We use kstrdup() below because the string pointed to by
|
||||||
|
* __FUNCTION__ might not be available by the time we want
|
||||||
|
* to print it, since the module might have been unloaded. */
|
||||||
|
dptr->kd_func = kstrdup(func, flags & ~__GFP_ZERO);
|
||||||
|
if (unlikely(dptr->kd_func == NULL)) {
|
||||||
|
kfree(dptr);
|
||||||
|
CWARN("kstrdup() failed in vmem_alloc(%llu, 0x%x) "
|
||||||
|
"(%lld/%llu)\n", (unsigned long long) size, flags,
|
||||||
|
atomic64_read(&vmem_alloc_used), vmem_alloc_max);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ptr = __vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO,
|
ptr = __vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO,
|
||||||
PAGE_KERNEL);
|
PAGE_KERNEL);
|
||||||
|
|
||||||
if (unlikely(ptr == NULL)) {
|
if (unlikely(ptr == NULL)) {
|
||||||
|
kfree(dptr->kd_func);
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
|
CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
|
||||||
(unsigned long long) size, flags,
|
(unsigned long long) size, flags,
|
||||||
@ -344,7 +371,6 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
|
|||||||
|
|
||||||
dptr->kd_addr = ptr;
|
dptr->kd_addr = ptr;
|
||||||
dptr->kd_size = size;
|
dptr->kd_size = size;
|
||||||
dptr->kd_func = func;
|
|
||||||
dptr->kd_line = line;
|
dptr->kd_line = line;
|
||||||
|
|
||||||
spin_lock_irqsave(&vmem_lock, irq_flags);
|
spin_lock_irqsave(&vmem_lock, irq_flags);
|
||||||
@ -385,6 +411,8 @@ vmem_free_track(void *ptr, size_t size)
|
|||||||
(unsigned long long) size, atomic64_read(&vmem_alloc_used),
|
(unsigned long long) size, atomic64_read(&vmem_alloc_used),
|
||||||
vmem_alloc_max);
|
vmem_alloc_max);
|
||||||
|
|
||||||
|
kfree(dptr->kd_func);
|
||||||
|
|
||||||
memset(dptr, 0x5a, sizeof(kmem_debug_t));
|
memset(dptr, 0x5a, sizeof(kmem_debug_t));
|
||||||
kfree(dptr);
|
kfree(dptr);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user