diff --git a/include/sys/debug.h b/include/sys/debug.h index 3cde97635..0d7b0b772 100644 --- a/include/sys/debug.h +++ b/include/sys/debug.h @@ -218,17 +218,32 @@ struct page_collection { #define __ASSERT_TAGE_INVARIANT(x) ((void)0) #define ASSERT(x) ((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 VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned 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, "%llu", \ + (unsigned long long)) #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) -#define ASSERT3S(x,y,z) VERIFY3S(x, y, z) -#define ASSERT3U(x,y,z) VERIFY3U(x, y, z) -#define ASSERT3P(x,y,z) VERIFY3P(x, y, z) +#define ASSERT3S(x,y,z) ((void)0) +#define ASSERT3U(x,y,z) ((void)0) +#define ASSERT3P(x,y,z) ((void)0) #else /* NDEBUG */ @@ -270,7 +285,7 @@ do { \ #define __ASSERT(cond) \ do { \ if (unlikely(!(cond))) { \ - printk(KERN_ERR "ASSERTION(" #cond ") failed"); \ + printk(KERN_ERR "ASSERTION(" #cond ") failed\n"); \ BUG(); \ } \ } while (0) @@ -322,8 +337,9 @@ do { \ } \ } while (0) -#define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long)) -#define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned 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, "%llu`", \ + (unsigned long long)) #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *)) #define ASSERT3S(x,y,z) VERIFY3S(x, y, z) diff --git a/modules/spl/spl-kmem.c b/modules/spl/spl-kmem.c index 3b5ecfb46..e580fbbdd 100644 --- a/modules/spl/spl-kmem.c +++ b/modules/spl/spl-kmem.c @@ -222,6 +222,18 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line, (unsigned long long) size, flags, 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 */ if (node_alloc) { 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)) { + kfree(dptr->kd_func); kfree(dptr); CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", (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_size = size; - dptr->kd_func = func; dptr->kd_line = line; 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), kmem_alloc_max); + kfree(dptr->kd_func); + memset(dptr, 0x5a, sizeof(kmem_debug_t)); 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", sizeof(kmem_debug_t), flags); } 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, PAGE_KERNEL); if (unlikely(ptr == NULL)) { + kfree(dptr->kd_func); kfree(dptr); CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n", (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_size = size; - dptr->kd_func = func; dptr->kd_line = line; 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), vmem_alloc_max); + kfree(dptr->kd_func); + memset(dptr, 0x5a, sizeof(kmem_debug_t)); kfree(dptr);