From f816f9be4cdf8e4dcac0b11fad8924ab389449ee Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 28 Sep 2011 13:18:18 +0200 Subject: [PATCH] Introduce gfp_mask variants of _stp allocation functions. * runtime/alloc.c: Add _stp_kmalloc_gfp(), _stp_kzalloc_gfp() and _stp_kmalloc_node_gfp() which take a gfp_mask in case you really know what you are doing. * translate.cxx (emit_module_init): Use with GFP_KERNEL for context alloc. * runtime/map.c: Use for init and new functions called at module_init time. * runtime/stat.c: Likewise. --- runtime/alloc.c | 40 ++++++++++++++++++++++++++++------------ runtime/map.c | 11 +++++++---- runtime/stat.c | 5 +++-- translate.cxx | 3 ++- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/runtime/alloc.c b/runtime/alloc.c index 58c40ad8a..e261c4a58 100644 --- a/runtime/alloc.c +++ b/runtime/alloc.c @@ -246,7 +246,7 @@ static void _stp_mem_debug_validate(void *addr) #endif #endif -static void *_stp_kmalloc(size_t size) +static void *_stp_kmalloc_gfp(size_t size, gfp_t gfp_mask) { void *ret; #ifdef STP_MAXMEMORY @@ -256,13 +256,13 @@ static void *_stp_kmalloc(size_t size) } #endif #ifdef DEBUG_MEM - ret = kmalloc(size + MEM_DEBUG_SIZE, STP_ALLOC_FLAGS); + ret = kmalloc(size + MEM_DEBUG_SIZE, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; ret = _stp_mem_debug_setup(ret, size, MEM_KMALLOC); } #else - ret = kmalloc(size, STP_ALLOC_FLAGS); + ret = kmalloc(size, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; } @@ -270,7 +270,12 @@ static void *_stp_kmalloc(size_t size) return ret; } -static void *_stp_kzalloc(size_t size) +static void *_stp_kmalloc(size_t size) +{ + return _stp_kmalloc_gfp(size, STP_ALLOC_FLAGS); +} + +static void *_stp_kzalloc_gfp(size_t size, gfp_t gfp_mask) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) { void *ret; @@ -281,14 +286,14 @@ static void *_stp_kzalloc(size_t size) } #endif #ifdef DEBUG_MEM - ret = kmalloc(size + MEM_DEBUG_SIZE, STP_ALLOC_FLAGS); + ret = kmalloc(size + MEM_DEBUG_SIZE, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; ret = _stp_mem_debug_setup(ret, size, MEM_KMALLOC); memset (ret, 0, size); } #else - ret = kmalloc(size, STP_ALLOC_FLAGS); + ret = kmalloc(size, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; memset (ret, 0, size); @@ -306,13 +311,13 @@ static void *_stp_kzalloc(size_t size) } #endif #ifdef DEBUG_MEM - ret = kzalloc(size + MEM_DEBUG_SIZE, STP_ALLOC_FLAGS); + ret = kzalloc(size + MEM_DEBUG_SIZE, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; ret = _stp_mem_debug_setup(ret, size, MEM_KMALLOC); } #else - ret = kzalloc(size, STP_ALLOC_FLAGS); + ret = kzalloc(size, gfp_mask); if (likely(ret)) { _stp_allocated_memory += size; } @@ -321,12 +326,18 @@ static void *_stp_kzalloc(size_t size) } #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) */ +static void *_stp_kzalloc(size_t size) +{ + return _stp_kzalloc_gfp(size, STP_ALLOC_FLAGS); +} + #ifdef PCPU_MIN_UNIT_SIZE #define _STP_MAX_PERCPU_SIZE PCPU_MIN_UNIT_SIZE #else #define _STP_MAX_PERCPU_SIZE 131072 #endif +/* Note, calls __alloc_percpu which may sleep and always uses GFP_KERNEL. */ static void *_stp_alloc_percpu(size_t size) { void *ret; @@ -349,7 +360,7 @@ static void *_stp_alloc_percpu(size_t size) #endif #ifdef DEBUG_MEM if (likely(ret)) { - struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), STP_ALLOC_FLAGS); + struct _stp_mem_entry *m = kmalloc(sizeof(struct _stp_mem_entry), GFP_KERNEL); if (unlikely(m == NULL)) { free_percpu(ret); return NULL; @@ -367,8 +378,9 @@ static void *_stp_alloc_percpu(size_t size) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) #define _stp_kmalloc_node(size,node) _stp_kmalloc(size) +#define _stp_kmalloc_node_gfp(size,node,gfp) _stp_kmalloc_gfp(size,gfp) #else -static void *_stp_kmalloc_node(size_t size, int node) +static void *_stp_kmalloc_node_gfp(size_t size, int node, gfp_t gfp_mask) { void *ret; #ifdef STP_MAXMEMORY @@ -378,19 +390,23 @@ static void *_stp_kmalloc_node(size_t size, int node) } #endif #ifdef DEBUG_MEM - ret = kmalloc_node(size + MEM_DEBUG_SIZE, STP_ALLOC_FLAGS, node); + ret = kmalloc_node(size + MEM_DEBUG_SIZE, gfp_mask, node); if (likely(ret)) { _stp_allocated_memory += size; ret = _stp_mem_debug_setup(ret, size, MEM_KMALLOC); } #else - ret = kmalloc_node(size, STP_ALLOC_FLAGS, node); + ret = kmalloc_node(size, gfp_mask, node); if (likely(ret)) { _stp_allocated_memory += size; } #endif return ret; } +static void *_stp_kmalloc_node(size_t size, int node) +{ + return _stp_kmalloc_node_gfp(size, node, STP_ALLOC_FLAGS); +} #endif /* LINUX_VERSION_CODE */ static void _stp_kfree(void *addr) diff --git a/runtime/map.c b/runtime/map.c index 20d8a48c7..05ef8c7cd 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -190,10 +190,11 @@ static int _stp_map_init(MAP m, unsigned max_entries, int type, int key_size, in for (i = 0; i < max_entries; i++) { + /* Called at module init time, so user context. */ if (cpu < 0) - tmp = _stp_kmalloc(size); + tmp = _stp_kmalloc_gfp(size, GFP_KERNEL); else - tmp = _stp_kmalloc_node(size, cpu_to_node(cpu)); + tmp = _stp_kmalloc_node_gfp(size, cpu_to_node(cpu), GFP_KERNEL); if (!tmp) return -1; @@ -211,7 +212,8 @@ static int _stp_map_init(MAP m, unsigned max_entries, int type, int key_size, in static MAP _stp_map_new(unsigned max_entries, int type, int key_size, int data_size) { - MAP m = (MAP) _stp_kzalloc(sizeof(struct map_root)); + /* Called from module_init, so user context, may sleep alloc. */ + MAP m = (MAP) _stp_kzalloc_gfp(sizeof(struct map_root), GFP_KERNEL); if (m == NULL) return NULL; @@ -229,7 +231,8 @@ static PMAP _stp_pmap_new(unsigned max_entries, int type, int key_size, int data int i; MAP map, m; - PMAP pmap = (PMAP) _stp_kzalloc(sizeof(struct pmap)); + /* Called from module_init, so user context, may sleep alloc. */ + PMAP pmap = (PMAP) _stp_kzalloc_gfp(sizeof(struct pmap), GFP_KERNEL); if (pmap == NULL) return NULL; diff --git a/runtime/stat.c b/runtime/stat.c index 689a84fe6..e0f084965 100644 --- a/runtime/stat.c +++ b/runtime/stat.c @@ -97,7 +97,8 @@ static Stat _stp_stat_init (int type, ...) } va_end (ap); } - st = (Stat) _stp_kmalloc (sizeof(struct _Stat)); + /* Called from module_init, so user context, may sleep alloc. */ + st = (Stat) _stp_kmalloc_gfp (sizeof(struct _Stat), GFP_KERNEL); if (st == NULL) return NULL; @@ -116,7 +117,7 @@ static Stat _stp_stat_init (int type, ...) } #endif - agg = (stat *)_stp_kmalloc(size); + agg = (stat *)_stp_kmalloc_gfp(size, GFP_KERNEL); if (agg == NULL) goto exit2; diff --git a/translate.cxx b/translate.cxx index 0aff9d1ef..12c6ed3b0 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1225,7 +1225,8 @@ c_unparser::emit_module_init () // per-cpu context o->newline() << "for_each_possible_cpu(cpu) {"; o->indent(1); - o->newline() << "contexts[cpu] = _stp_kzalloc(sizeof(struct context));"; + // Module init, so in user context, safe to use "sleeping" allocation. + o->newline() << "contexts[cpu] = _stp_kzalloc_gfp(sizeof(struct context), GFP_KERNEL);"; o->newline() << "if (contexts[cpu] == NULL) {"; o->indent(1); o->newline() << "_stp_error (\"context (size %lu) allocation failed\", (unsigned long) sizeof (struct context));"; -- 2.43.5