Skip to contentSkip to conversation

kmalloc_percpu

PATCH In review Ravikiran G Thirumalai 3 participants 3 messages Oct 31, 2002 – Nov 5, 2002

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 kmalloc_percpu

Here's kmalloc_percpu interfaces ported (...mostly rediffed) to 2.5.45. (One last try for 2.6). I guess we can use DECLARE_PER_CPU interfaces most of the places; But for per_cpu stuff which could possibly be defined in modules, kmalloc_percpu might be useful (SNMP stats for ex...ipv6 can be compiled as a module).

-Kiran

Name: kmalloc_percpu
Description: Dynamic percpu allocator
Author: Dipankar Sarma & Ravikiran Thirumalai

include/linux/slab.h +37 -0
diff -X dontdiff -ruN linux-2.5.45/include/linux/slab.h kmalloc_percpu-2.5.45/include/linux/slab.h
@@ -13,6 +13,7 @@
 
 #include	<linux/gfp.h>
 #include	<linux/types.h>
+#include 	<linux/smp.h>
 
 /* flags for kmem_cache_alloc() */
 #define	SLAB_NOFS		GFP_NOFS
@@ -63,6 +64,42 @@
 
 extern int FASTCALL(kmem_cache_reap(int));
 
+#ifdef CONFIG_SMP
+
+struct percpu_data {
+	void *ptrs[NR_CPUS];
+	void *blkp;
+};
+
+#define per_cpu_ptr(ptr, cpu)                   \
+({                                              \
+        struct percpu_data *__p = (struct percpu_data *)~(unsigned long)(ptr); \
+        (__typeof__(ptr))__p->ptrs[(cpu)];	\
+})
+#define this_cpu_ptr(ptr) per_cpu_ptr(ptr, smp_processor_id())
+extern void *kmalloc_percpu(size_t size, int flags);
+extern void kfree_percpu(const void *);
+extern int percpu_interlaced_alloc(struct percpu_data *, size_t, int);
+extern void percpu_interlaced_free(struct percpu_data *);
+extern void percpu_data_sys_init(void);
+
+#else
+
+#define per_cpu_ptr(ptr, cpu) (ptr)
+#define this_cpu_ptr(ptr) (ptr)
+static inline void *kmalloc_percpu(size_t size, int flags)
+{
+	return(kmalloc(size, flags));
+}
+static inline void kfree_percpu(const void *ptr)
+{	
+	kfree(ptr);
+}
+static inline void percpu_data_sys_init(void) { }
+
+#endif
+
+
 /* System wide caches */
 extern kmem_cache_t	*vm_area_cachep;
 extern kmem_cache_t	*mm_cachep;
init/main.c +1 -0
diff -X dontdiff -ruN linux-2.5.45/init/main.c kmalloc_percpu-2.5.45/init/main.c
@@ -423,6 +423,7 @@
 	page_address_init();
 	mem_init();
 	kmem_cache_sizes_init();
+	percpu_data_sys_init();
 	pidhash_init();
 	pgtable_cache_init();
 	pte_chain_init();
kernel/ksyms.c +4 -0
diff -X dontdiff -ruN linux-2.5.45/kernel/ksyms.c kmalloc_percpu-2.5.45/kernel/ksyms.c
@@ -104,6 +104,10 @@
 EXPORT_SYMBOL(remove_shrinker);
 EXPORT_SYMBOL(kmalloc);
 EXPORT_SYMBOL(kfree);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(kmalloc_percpu);
+EXPORT_SYMBOL(kfree_percpu);
+#endif
 EXPORT_SYMBOL(vfree);
 EXPORT_SYMBOL(__vmalloc);
 EXPORT_SYMBOL(vmalloc);
mm/Makefile +3 -1
diff -X dontdiff -ruN linux-2.5.45/mm/Makefile kmalloc_percpu-2.5.45/mm/Makefile
@@ -2,7 +2,8 @@
 # Makefile for the linux memory manager.
 #
 
-export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o
+export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o \
+	       percpu_data.o
 
 obj-y	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
@@ -11,4 +12,5 @@
 	    pdflush.o page-writeback.o rmap.o madvise.o vcache.o \
 	    truncate.o
 
+obj-$(CONFIG_SMP) += percpu_data.o
 include $(TOPDIR)/Rules.make
mm/percpu_data.c +376 -0

376 lines not on this page · raw message

mm/slab.c +78 -0

90 lines not on this page · raw message

#1 lore raw
Quoted 2 lines · On Thu, 31 Oct 2002 21:36:40 +0530 Ravikiran G Thirumalai <[email protected]>…

Here's kmalloc_percpu interfaces ported (...mostly rediffed) to 2.5.45. (One last try for 2.6).

IMHO this is a "when we need it" patch. Baby steps...

Quoted 1 line

+#define this_cpu_ptr(ptr) per_cpu_ptr(ptr, smp_processor_id())

Probably want a get_cpu_ptr() & put_cpu_ptr() using get_cpu() and put_cpu() (and this would become __get_cpu_ptr()).

And probably move them all to linux/percpu.h.

include/linux/slab.h line 84

Quoted 5 lines
include/linux/slab.h +5 -0
+extern void *kmalloc_percpu(size_t size, int flags);
+extern void kfree_percpu(const void *);
+extern int percpu_interlaced_alloc(struct percpu_data *, size_t, int);
+extern void percpu_interlaced_free(struct percpu_data *);
+extern void percpu_data_sys_init(void);

Hmm... It'd be nice to remove these three from the header so that the interface is clear (which may mean exposing some slab.c internals so you can access them in mm/percpu_data.c).

mm/percpu_data.c line 190

Quoted 1 line
mm/percpu_data.c +1 -0
+	if(!blklist->cachep)

A space between the "if" and the "(" is traditional.

Cheers,
Rusty.

Signature · 2 lines
   there are those who do and those who hang on and you don't see too
   many doers quoting their contemporaries.  -- Larry McVoy
#2 lore raw
Quoted 7 lines · Rusty Russell
Quoted 2 lines · On Thu, 31 Oct 2002 21:36:40 +0530 Ravikiran G Thirumalai <[email protected]>…

Here's kmalloc_percpu interfaces ported (...mostly rediffed) to 2.5.45. (One last try for 2.6).

IMHO this is a "when we need it" patch. Baby steps...

Agreed. It could be useful if we want to use per-CPU statistics for things like disk I/O (now in struct gendisk).

Quoted 7 lines
Quoted 2 lines

+#define this_cpu_ptr(ptr) per_cpu_ptr(ptr, smp_processor_id())

Probably want a get_cpu_ptr() & put_cpu_ptr() using get_cpu() and put_cpu() (and this would become __get_cpu_ptr()).

And probably move them all to linux/percpu.h.

Yes, it needs to sync up with its static twin ;-)

Thanks
Dipankar