Make kzalloc a macro

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



How about this patch making kzalloc a macro?

---

Make kzalloc a macro and use __GFP_ZERO for zeroed slab allocations

kzalloc is right now a function call. The optimization that the kmalloc macro
provides does not work for kzalloc invocations. kmalloc also determines the
slab to use at compile time and fails the compilation if the size is too big.
kzalloc cannot do not.

Moreover there is no kzalloc_node.

This patch adds the ability to the slab allocator to indicate that an entity
should be zeroed by using __GFP_ZERO in the same way to the page allocator.

__GFP_ZERO may be specified when using any slab allocation operation.

Then kzalloc can be defined as a simple macro which will then perform all the
compile time checks of kmalloc and also check the sizes.

Signed-off-by: Christoph Lameter

Index: linux-2.6.14-rc2/include/linux/slab.h
===================================================================
--- linux-2.6.14-rc2.orig/include/linux/slab.h	2005-09-19 20:00:41.000000000 -0700
+++ linux-2.6.14-rc2/include/linux/slab.h	2005-09-22 16:25:25.000000000 -0700
@@ -99,7 +99,7 @@ found:
 	return __kmalloc(size, flags);
 }
 
-extern void *kzalloc(size_t, unsigned int __nocast);
+#define kzalloc(__size, __flags) kmalloc(__size, (__flags) | __GFP_ZERO)
 
 /**
  * kcalloc - allocate memory for an array. The memory is set to zero.
Index: linux-2.6.14-rc2/mm/slab.c
===================================================================
--- linux-2.6.14-rc2.orig/mm/slab.c	2005-09-22 11:58:45.000000000 -0700
+++ linux-2.6.14-rc2/mm/slab.c	2005-09-23 08:53:16.000000000 -0700
@@ -1190,7 +1190,7 @@ static void *kmem_getpages(kmem_cache_t 
 	void *addr;
 	int i;
 
-	flags |= cachep->gfpflags;
+	flags = (flags | cachep->gfpflags) & ~__GFP_ZERO;
 	if (likely(nodeid == -1)) {
 		page = alloc_pages(flags, cachep->gfporder);
 	} else {
@@ -2508,11 +2508,23 @@ cache_alloc_debugcheck_after(kmem_cache_
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
+static inline void *obj_checkout(kmem_cache_t *cachep, unsigned int __nocast flags, void *objp)
+{
+	if (likely(objp)) {
+		objp = cache_alloc_debugcheck_after(cachep, flags, objp,
+					__builtin_return_address(0));
+		if (unlikely(flags & __GFP_ZERO))
+			memset(objp, 0, obj_reallen(cachep));
+		else
+			prefetchw(objp);
+	}
+	return objp;
+}
 
 static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
 {
 	unsigned long save_flags;
-	void* objp;
+	void *objp;
 	struct array_cache *ac;
 
 	cache_alloc_debugcheck_before(cachep, flags);
@@ -2528,10 +2540,7 @@ static inline void *__cache_alloc(kmem_c
 		objp = cache_alloc_refill(cachep, flags);
 	}
 	local_irq_restore(save_flags);
-	objp = cache_alloc_debugcheck_after(cachep, flags, objp,
-					__builtin_return_address(0));
-	prefetchw(objp);
-	return objp;
+	return obj_checkout(cachep, flags, objp);
 }
 
 #ifdef CONFIG_NUMA
@@ -2550,14 +2559,23 @@ static void *__cache_alloc_node(kmem_cac
  	l3 = cachep->nodelists[nodeid];
  	BUG_ON(!l3);
 
+	cache_alloc_debugcheck_before(cachep, flags);
+
 retry:
  	spin_lock(&l3->list_lock);
  	entry = l3->slabs_partial.next;
  	if (entry == &l3->slabs_partial) {
  		l3->free_touched = 1;
  		entry = l3->slabs_free.next;
- 		if (entry == &l3->slabs_free)
- 			goto must_grow;
+ 		if (entry == &l3->slabs_free) {
+ 			spin_unlock(&l3->list_lock);
+ 			x = cache_grow(cachep, flags, nodeid);
+
+		 	if (!x)
+ 				return NULL;
+
+ 			goto retry;
+		}
  	}
 
  	slabp = list_entry(entry, struct slab, list);
@@ -2590,18 +2608,7 @@ retry:
  	}
 
  	spin_unlock(&l3->list_lock);
- 	goto done;
-
-must_grow:
- 	spin_unlock(&l3->list_lock);
- 	x = cache_grow(cachep, flags, nodeid);
-
- 	if (!x)
- 		return NULL;
-
- 	goto retry;
-done:
- 	return obj;
+	return obj_checkout(cachep, flags, obj);
 }
 #endif
 
@@ -2980,20 +2987,6 @@ void kmem_cache_free(kmem_cache_t *cache
 EXPORT_SYMBOL(kmem_cache_free);
 
 /**
- * kzalloc - allocate memory. The memory is set to zero.
- * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- */
-void *kzalloc(size_t size, unsigned int __nocast flags)
-{
-	void *ret = kmalloc(size, flags);
-	if (ret)
-		memset(ret, 0, size);
-	return ret;
-}
-EXPORT_SYMBOL(kzalloc);
-
-/**
  * kfree - free previously allocated memory
  * @objp: pointer returned by kmalloc.
  *
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux