From 842d3bd0912be4b0e309151e50eef2374c9cd72b Mon Sep 17 00:00:00 2001
From: Ricardo M. Correia <ricardo.correia@oracle.com>
Date: Mon, 24 May 2010 11:18:12 +0000
Subject: [PATCH] (local) Make the SPL use the debug_vmalloc APIs.

---
 Makefile.in             |    2 +-
 include/sys/kmem.h      |   20 ++++++++++++--------
 module/spl/spl-debug.c  |   19 ++++++++++---------
 module/spl/spl-kmem.c   |   44 ++++++++++++++++++--------------------------
 module/spl/spl-kobj.c   |    6 +++---
 module/spl/spl-module.c |   15 ++++++++-------
 module/spl/spl-vnode.c  |    4 ++--
 7 files changed, 54 insertions(+), 56 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index a36b926..ae990d0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -463,7 +463,7 @@ distdir: $(DISTFILES)
 	      || exit 1; \
 	  fi; \
 	done
-	-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	-find $(distdir) -type d ! -perm -755 -exec chmod a+rwx,go+rx {} \; -o \
 	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
 	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
 	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
diff --git a/include/sys/kmem.h b/include/sys/kmem.h
index 442f4c2..a2cbd26 100644
--- a/include/sys/kmem.h
+++ b/include/sys/kmem.h
@@ -36,6 +36,7 @@ extern "C" {
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/debug_vmalloc.h>
 #include <linux/mm_compat.h>
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
@@ -76,7 +77,7 @@ kmalloc_nofail(size_t size, gfp_t flags)
 	void *ptr;
 
 	do {
-		ptr = kmalloc(size, flags);
+		ptr = debug_vmalloc(size, flags);
 	} while (ptr == NULL && (flags & __GFP_WAIT));
 
 	return ptr;
@@ -88,9 +89,12 @@ kzalloc_nofail(size_t size, gfp_t flags)
 	void *ptr;
 
 	do {
-		ptr = kzalloc(size, flags);
+		ptr = debug_vmalloc(size, flags);
 	} while (ptr == NULL && (flags & __GFP_WAIT));
 
+	if (ptr != NULL)
+		memset(ptr, 0, size);
+
 	return ptr;
 }
 
@@ -101,7 +105,7 @@ kmalloc_node_nofail(size_t size, gfp_t flags, int node)
 	void *ptr;
 
 	do {
-		ptr = kmalloc_node(size, flags, node);
+		ptr = debug_vmalloc(size, flags);
 	} while (ptr == NULL && (flags & __GFP_WAIT));
 
 	return ptr;
@@ -200,7 +204,7 @@ extern void vmem_free_debug(void *ptr, size_t size);
 
 # define kmem_alloc(size, flags)              kmalloc_nofail((size), (flags))
 # define kmem_zalloc(size, flags)             kzalloc_nofail((size), (flags))
-# define kmem_free(ptr, size)                 ((void)(size), kfree(ptr))
+# define kmem_free(ptr, size)                 ((void)(size), debug_vfree(ptr))
 
 # ifdef HAVE_KMALLOC_NODE
 #  define kmem_alloc_node(size, flags, node)                                  \
@@ -210,16 +214,16 @@ extern void vmem_free_debug(void *ptr, size_t size);
           kmalloc_nofail((size), (flags))
 # endif
 
-# define vmem_alloc(size, flags)              __vmalloc((size), ((flags) |    \
-                                                  __GFP_HIGHMEM), PAGE_KERNEL)
+# define vmem_alloc(size, flags)              debug_vmalloc((size), ((flags) |    \
+                                                  __GFP_HIGHMEM))
 # define vmem_zalloc(size, flags)                                             \
 ({                                                                            \
-        void *_ptr_ = __vmalloc((size),((flags)|__GFP_HIGHMEM),PAGE_KERNEL);  \
+        void *_ptr_ = debug_vmalloc((size),((flags)|__GFP_HIGHMEM));  \
         if (_ptr_)                                                            \
                 memset(_ptr_, 0, (size));                                     \
         _ptr_;                                                                \
 })
-# define vmem_free(ptr, size)           ((void)(size), vfree(ptr))
+# define vmem_free(ptr, size)           ((void)(size), debug_vfree(ptr))
 
 #endif /* DEBUG_KMEM */
 
diff --git a/module/spl/spl-debug.c b/module/spl/spl-debug.c
index a3fcd74..f811713 100644
--- a/module/spl/spl-debug.c
+++ b/module/spl/spl-debug.c
@@ -34,6 +34,7 @@
 #include <linux/kmod.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/debug_vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
@@ -535,13 +536,13 @@ tage_alloc(int gfp)
         struct page *page;
         struct trace_page *tage;
 
-        page = alloc_pages(gfp | __GFP_NOWARN, 0);
+        page = debug_alloc_pages(gfp | __GFP_NOWARN, 0);
         if (page == NULL)
                 return NULL;
 
-        tage = kmalloc(sizeof(*tage), gfp);
+        tage = debug_vmalloc(sizeof(*tage), gfp);
         if (tage == NULL) {
-                __free_pages(page, 0);
+                __debug_free_pages(page, 0);
                 return NULL;
         }
 
@@ -557,8 +558,8 @@ tage_free(struct trace_page *tage)
         __ASSERT(tage != NULL);
         __ASSERT(tage->page != NULL);
 
-        __free_pages(tage->page, 0);
-        kfree(tage);
+        __debug_free_pages(tage->page, 0);
+        debug_vfree(tage);
         atomic_dec(&trace_tage_allocated);
 }
 
@@ -1158,7 +1159,7 @@ trace_init(int max_pages)
         /* initialize trace_data */
         memset(trace_data, 0, sizeof(trace_data));
         for (i = 0; i < TCD_TYPE_MAX; i++) {
-                trace_data[i] = kmalloc(sizeof(union trace_data_union) *
+                trace_data[i] = debug_vmalloc(sizeof(union trace_data_union) *
                                         NR_CPUS, GFP_KERNEL);
                 if (trace_data[i] == NULL)
                         goto out;
@@ -1180,7 +1181,7 @@ trace_init(int max_pages)
         for (i = 0; i < num_possible_cpus(); i++) {
                 for (j = 0; j < 3; j++) {
                         trace_console_buffers[i][j] =
-                                kmalloc(TRACE_CONSOLE_BUFFER_SIZE,
+                                debug_vmalloc(TRACE_CONSOLE_BUFFER_SIZE,
                                         GFP_KERNEL);
 
                         if (trace_console_buffers[i][j] == NULL)
@@ -1253,14 +1254,14 @@ trace_fini(void)
         for (i = 0; i < num_possible_cpus(); i++) {
                 for (j = 0; j < 3; j++) {
                         if (trace_console_buffers[i][j] != NULL) {
-                                kfree(trace_console_buffers[i][j]);
+                                debug_vfree(trace_console_buffers[i][j]);
                                 trace_console_buffers[i][j] = NULL;
                         }
                 }
         }
 
         for (i = 0; i < TCD_TYPE_MAX && trace_data[i] != NULL; i++) {
-                kfree(trace_data[i]);
+                debug_vfree(trace_data[i]);
                 trace_data[i] = NULL;
         }
 }
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index 0742777..629a225 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -407,7 +407,7 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
 		 * 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);
+			debug_vfree(dptr);
 			CWARN("kstrdup() failed in kmem_alloc(%llu, 0x%x) "
 			    "(%lld/%llu)\n", (unsigned long long) size, flags,
 			    kmem_alloc_used_read(), kmem_alloc_max);
@@ -425,8 +425,8 @@ kmem_alloc_track(size_t size, int flags, const char *func, int line,
 		}
 
 		if (unlikely(ptr == NULL)) {
-			kfree(dptr->kd_func);
-			kfree(dptr);
+			debug_vfree(dptr->kd_func);
+			debug_vfree(dptr);
 			CWARN("kmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
 			    (unsigned long long) size, flags,
 			    kmem_alloc_used_read(), kmem_alloc_max);
@@ -483,13 +483,13 @@ kmem_free_track(void *ptr, size_t size)
 	    (unsigned long long) size, kmem_alloc_used_read(),
 	    kmem_alloc_max);
 
-	kfree(dptr->kd_func);
+	debug_vfree(dptr->kd_func);
 
 	memset(dptr, 0x5a, sizeof(kmem_debug_t));
-	kfree(dptr);
+	debug_vfree(dptr);
 
 	memset(ptr, 0x5a, size);
-	kfree(ptr);
+	debug_vfree(ptr);
 
 	EXIT;
 }
@@ -516,19 +516,18 @@ vmem_alloc_track(size_t size, int flags, const char *func, int line)
 		 * 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);
+			debug_vfree(dptr);
 			CWARN("kstrdup() failed in vmem_alloc(%llu, 0x%x) "
 			    "(%lld/%llu)\n", (unsigned long long) size, flags,
 			    vmem_alloc_used_read(), vmem_alloc_max);
 			goto out;
 		}
 
-		ptr = __vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO,
-		    PAGE_KERNEL);
+		ptr = debug_vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO);
 
 		if (unlikely(ptr == NULL)) {
-			kfree(dptr->kd_func);
-			kfree(dptr);
+			debug_vfree(dptr->kd_func);
+			debug_vfree(dptr);
 			CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
 			    (unsigned long long) size, flags,
 			    vmem_alloc_used_read(), vmem_alloc_max);
@@ -587,13 +586,13 @@ vmem_free_track(void *ptr, size_t size)
 	    (unsigned long long) size, vmem_alloc_used_read(),
 	    vmem_alloc_max);
 
-	kfree(dptr->kd_func);
+	debug_vfree(dptr->kd_func);
 
 	memset(dptr, 0x5a, sizeof(kmem_debug_t));
-	kfree(dptr);
+	debug_vfree(dptr);
 
 	memset(ptr, 0x5a, size);
-	vfree(ptr);
+	debug_vfree(ptr);
 
 	EXIT;
 }
@@ -656,7 +655,7 @@ kmem_free_debug(void *ptr, size_t size)
 	    kmem_alloc_max);
 
 	memset(ptr, 0x5a, size);
-	kfree(ptr);
+	debug_vfree(ptr);
 
 	EXIT;
 }
@@ -670,8 +669,7 @@ vmem_alloc_debug(size_t size, int flags, const char *func, int line)
 
 	ASSERT(flags & KM_SLEEP);
 
-	ptr = __vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO,
-	    PAGE_KERNEL);
+	ptr = debug_vmalloc(size, (flags | __GFP_HIGHMEM) & ~__GFP_ZERO);
 	if (ptr == NULL) {
 		CWARN("vmem_alloc(%llu, 0x%x) failed (%lld/%llu)\n",
 		    (unsigned long long) size, flags,
@@ -707,7 +705,7 @@ vmem_free_debug(void *ptr, size_t size)
 	    vmem_alloc_max);
 
 	memset(ptr, 0x5a, size);
-	vfree(ptr);
+	debug_vfree(ptr);
 
 	EXIT;
 }
@@ -723,10 +721,7 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags)
 
 	ASSERT(ISP2(size));
 
-	if (skc->skc_flags & KMC_KMEM)
-		ptr = (void *)__get_free_pages(flags, get_order(size));
-	else
-		ptr = __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL);
+	ptr = debug_vmalloc(size, flags | __GFP_HIGHMEM);
 
 	/* Resulting allocated memory will be page aligned */
 	ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));
@@ -740,10 +735,7 @@ kv_free(spl_kmem_cache_t *skc, void *ptr, int size)
 	ASSERT(IS_P2ALIGNED(ptr, PAGE_SIZE));
 	ASSERT(ISP2(size));
 
-	if (skc->skc_flags & KMC_KMEM)
-		free_pages((unsigned long)ptr, get_order(size));
-	else
-		vfree(ptr);
+	debug_vfree(ptr);
 }
 
 /*
diff --git a/module/spl/spl-kobj.c b/module/spl/spl-kobj.c
index e78cd92..5a0ed2e 100644
--- a/module/spl/spl-kobj.c
+++ b/module/spl/spl-kobj.c
@@ -40,12 +40,12 @@ kobj_open_file(const char *name)
 	int rc;
 	ENTRY;
 
-	file = kmalloc(sizeof(_buf_t), GFP_KERNEL);
+	file = debug_vmalloc(sizeof(_buf_t), GFP_KERNEL);
 	if (file == NULL)
 		RETURN((_buf_t *)-1UL);
 
 	if ((rc = vn_open(name, UIO_SYSSPACE, FREAD, 0644, &vp, 0, 0))) {
-		kfree(file);
+		debug_vfree(file);
 		RETURN((_buf_t *)-1UL);
 	}
 
@@ -61,7 +61,7 @@ kobj_close_file(struct _buf *file)
 	ENTRY;
 	VOP_CLOSE(file->vp, 0, 0, 0, 0, 0);
 	VN_RELE(file->vp);
-        kfree(file);
+        debug_vfree(file);
         EXIT;
 } /* kobj_close_file() */
 EXPORT_SYMBOL(kobj_close_file);
diff --git a/module/spl/spl-module.c b/module/spl/spl-module.c
index f179748..93847fa 100644
--- a/module/spl/spl-module.c
+++ b/module/spl/spl-module.c
@@ -104,13 +104,14 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
 	ASSERT(minor_num < di->di_minors);
 	ASSERT(!strcmp(node_type, DDI_PSEUDO));
 
-	fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
+	fops = debug_vmalloc(sizeof(struct file_operations), GFP_KERNEL);
 	if (fops == NULL)
 		RETURN(DDI_FAILURE);
+	memset(fops, 0, sizeof(struct file_operations));
 
 	cdev = cdev_alloc();
 	if (cdev == NULL) {
-		kfree(fops);
+		debug_vfree(fops);
 		RETURN(DDI_FAILURE);
 	}
 
@@ -170,7 +171,7 @@ __ddi_create_minor_node(dev_info_t *di, char *name, int spec_type,
 	rc = cdev_add(cdev, di->di_dev, 1);
 	if (rc) {
 		CERROR("Error adding cdev, %d\n", rc);
-		kfree(fops);
+		debug_vfree(fops);
 		cdev_del(cdev);
 		mutex_exit(&di->di_lock);
 		RETURN(DDI_FAILURE);
@@ -247,7 +248,7 @@ static struct dev_info *
 dev_info_alloc(major_t major, minor_t minors, struct dev_ops *ops) {
 	struct dev_info *di;
 
-	di = kmalloc(sizeof(struct dev_info), GFP_KERNEL);
+	di = debug_vmalloc(sizeof(struct dev_info), GFP_KERNEL);
 	if (di == NULL)
 		return NULL;
 
@@ -271,7 +272,7 @@ dev_info_free(struct dev_info *di)
 	__ddi_remove_minor_node_locked(di, NULL);
 	mutex_exit(&di->di_lock);
 	mutex_destroy(&di->di_lock);
-	kfree(di);
+	debug_vfree(di);
 }
 
 int
@@ -355,7 +356,7 @@ ldi_ident_from_mod(struct modlinkage *modlp, ldi_ident_t *lip)
 	ASSERT(modlp);
 	ASSERT(lip);
 
-	li = kmalloc(sizeof(struct ldi_ident), GFP_KERNEL);
+	li = debug_vmalloc(sizeof(struct ldi_ident), GFP_KERNEL);
 	if (li == NULL)
 		RETURN(ENOMEM);
 
@@ -371,7 +372,7 @@ ldi_ident_release(ldi_ident_t lip)
 {
 	ENTRY;
 	ASSERT(lip);
-	kfree(lip);
+	debug_vfree(lip);
 	EXIT;
 }
 EXPORT_SYMBOL(ldi_ident_release);
diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c
index 12e09b7..527fec4 100644
--- a/module/spl/spl-vnode.c
+++ b/module/spl/spl-vnode.c
@@ -167,13 +167,13 @@ vn_openat(const char *path, uio_seg_t seg, int flags, int mode,
 	ASSERT(vp == rootdir);
 
 	len = strlen(path) + 2;
-	realpath = kmalloc(len, GFP_KERNEL);
+	realpath = debug_vmalloc(len, GFP_KERNEL);
 	if (!realpath)
 		RETURN(ENOMEM);
 
 	(void)snprintf(realpath, len, "/%s", path);
 	rc = vn_open(realpath, seg, flags, mode, vpp, x1, x2);
-	kfree(realpath);
+	debug_vfree(realpath);
 
 	RETURN(rc);
 } /* vn_openat() */
-- 
1.6.2.2