summaryrefslogtreecommitdiffstats
path: root/runtime/alloc.c
diff options
context:
space:
mode:
authorhunt <hunt>2006-01-25 09:15:15 +0000
committerhunt <hunt>2006-01-25 09:15:15 +0000
commit98ec387a8443f7185814715175c4c0d86390c9b6 (patch)
treebff384e50bc08423bc4231c2d2ed93832bf2fd43 /runtime/alloc.c
parentf10925a5b61a32ae45c7ad6946fdb53569616676 (diff)
downloadsystemtap-steved-98ec387a8443f7185814715175c4c0d86390c9b6.tar.gz
systemtap-steved-98ec387a8443f7185814715175c4c0d86390c9b6.tar.xz
systemtap-steved-98ec387a8443f7185814715175c4c0d86390c9b6.zip
2006-01-25 Martin Hunt <hunt@redhat.com>
* stat.c (_stp_stat_init): Use _stp_alloc_percpu(). (_stp_stat_del): New function. * alloc.c (_stp_alloc_percpu): New function. (_stp_free_percpu): New function.
Diffstat (limited to 'runtime/alloc.c')
-rw-r--r--runtime/alloc.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/runtime/alloc.c b/runtime/alloc.c
index d52c6080..a09a515d 100644
--- a/runtime/alloc.c
+++ b/runtime/alloc.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* Memory allocation functions
- * Copyright (C) 2005 Red Hat Inc.
+ * Copyright (C) 2005, 2006 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -11,11 +11,71 @@
#ifndef _ALLOC_C_
#define _ALLOC_C_
-/* does this file really need to exist? */
+/* This file exists because all the NUMA-compatible allocators keep
+ changing in 2.6 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
#define kmalloc_node(size,flags,node) kmalloc(size,flags)
#endif /* LINUX_VERSION_CODE */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+#define _stp_alloc_percpu(size) __alloc_percpu(size, 8)
+#else
+#ifdef CONFIG_SMP
+/* This is like alloc_percpu() except it simply takes a size, instead of a type. */
+void *_stp_alloc_percpu(size_t size)
+{
+ int i;
+ struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ for_each_cpu(i) {
+ int node = cpu_to_node(i);
+
+ if (node_online(node))
+ pdata->ptrs[i] = kmalloc_node(size, GFP_KERNEL, node);
+ else
+ pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
+
+ if (!pdata->ptrs[i])
+ goto unwind_oom;
+ memset(pdata->ptrs[i], 0, size);
+ }
+
+ /* Catch derefs w/o wrappers */
+ return (void *) (~(unsigned long) pdata);
+
+unwind_oom:
+ while (--i >= 0) {
+ if (!cpu_possible(i))
+ continue;
+ kfree(pdata->ptrs[i]);
+ }
+ kfree(pdata);
+ return NULL;
+}
+
+void _stp_free_percpu(const void *objp)
+{
+ int i;
+ struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
+
+ for_each_cpu(i)
+ kfree(p->ptrs[i]);
+ kfree(p);
+}
+#else
+void *_stp_alloc_percpu(size_t size)
+{
+ void *ret = kmalloc(size, GFP_KERNEL);
+ if (ret)
+ memset(ret, 0, size);
+ return ret;
+}
+#define _stp_free_percpu(ptr) kfree(ptr)
+
+#endif /* CONFIG_SMP */
+#endif /* LINUX_VERSION_CODE */
#endif /* _ALLOC_C_ */