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 | |
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.
-rw-r--r-- | runtime/ChangeLog | 8 | ||||
-rw-r--r-- | runtime/alloc.c | 64 | ||||
-rw-r--r-- | runtime/stat.c | 16 |
3 files changed, 85 insertions, 3 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index bb04363c..546b907e 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +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. + 2006-01-19 Martin Hunt <hunt@redhat.com> * pmap-gen.c (_stp_pmap_get): Fix bug where old data 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_ */ diff --git a/runtime/stat.c b/runtime/stat.c index 29dcef9b..d9eff2c3 100644 --- a/runtime/stat.c +++ b/runtime/stat.c @@ -101,7 +101,7 @@ Stat _stp_stat_init (int type, ...) return NULL; size = buckets * sizeof(int64_t) + sizeof(stat); - sd = (stat *) __alloc_percpu (size, 8); + sd = (stat *) _stp_alloc_percpu (size); if (sd == NULL) goto exit1; @@ -135,6 +135,20 @@ exit1: return NULL; } +/** Delete Stat. + * Call this to free all memory allocated during initialization. + * + * @param st Stat + */ +void _stp_stat_del (Stat st) +{ + if (st) { + _stp_free_percpu (st->sd); + kfree (st->agg); + kfree (st); + } +} + /** Add to a Stat. * Add an int64 to a Stat. * |