diff options
author | hunt <hunt> | 2006-01-25 09:15:15 +0000 |
---|---|---|
committer | hunt <hunt> | 2006-01-25 09:15:15 +0000 |
commit | 98ec387a8443f7185814715175c4c0d86390c9b6 (patch) | |
tree | bff384e50bc08423bc4231c2d2ed93832bf2fd43 /runtime/alloc.c | |
parent | f10925a5b61a32ae45c7ad6946fdb53569616676 (diff) | |
download | systemtap-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.c | 64 |
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_ */ |