From 4d88dfc7abf9e2b566136037bc405942c35a452c Mon Sep 17 00:00:00 2001 From: fche Date: Tue, 29 May 2007 19:24:36 +0000 Subject: [PATCH] 2007-05-29 Frank Ch. Eigler PR 2224 * map.h (NEED_MAP_LOCKS): New config macro, defaults to 0. (MAP_GET_CPU, MAP_PUT_CPU): Wrappers, default to ~no-op. * map.c (_stp_pmap_clear,agg): Use them. * pmap-gen.c (_stp_pmap_new,set,add,get_cpu,get,del): Ditto. --- runtime/ChangeLog | 9 +++++++++ runtime/map.c | 10 ++++++++++ runtime/map.h | 19 +++++++++++++++++++ runtime/pmap-gen.c | 47 +++++++++++++++++++++++++++++++++++----------- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/runtime/ChangeLog b/runtime/ChangeLog index d2cd04049..eb5f03bfe 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2007-05-29 Frank Ch. Eigler + + PR 2224 + * map.h (NEED_MAP_LOCKS): New config macro, defaults to 0. + (MAP_GET_CPU, MAP_PUT_CPU): Wrappers, default to ~no-op. + * map.c (_stp_pmap_clear,agg): Use them. + * pmap-gen.c (_stp_pmap_new,set,add,get_cpu,get,del): Ditto. + 2007-05-15 Martin Hunt * vsprintf.c: Add comment about %p. @@ -35,6 +43,7 @@ 2007-03-21 Martin Hunt + * sym.h: Declare _stp_module_relocate. * sym.c (_stp_module_relocate): Add comments, reformat, add a way for "last" cached values to be cleared when modules diff --git a/runtime/map.c b/runtime/map.c index e4235901c..2acf2fe2f 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -369,9 +369,13 @@ void _stp_pmap_clear(PMAP pmap) for_each_cpu(i) { MAP m = per_cpu_ptr (pmap->map, i); +#if NEED_MAP_LOCKS spin_lock(&m->lock); +#endif _stp_map_clear(m); +#if NEED_MAP_LOCKS spin_unlock(&m->lock); +#endif } _stp_map_clear(&pmap->agg); } @@ -873,7 +877,9 @@ MAP _stp_pmap_agg (PMAP pmap) for_each_cpu(i) { m = per_cpu_ptr (pmap->map, i); +#if NEED_MAP_LOCKS spin_lock(&m->lock); +#endif /* walk the hash chains. */ for (hash = 0; hash < HASH_TABLE_SIZE; hash++) { head = &m->hashes[hash]; @@ -892,13 +898,17 @@ MAP _stp_pmap_agg (PMAP pmap) _stp_add_agg(aptr, ptr); else { if (!_stp_new_agg(agg, ahead, ptr)) { +#if NEED_MAP_LOCKS spin_unlock(&m->lock); +#endif return NULL; } } } } +#if NEED_MAP_LOCKS spin_unlock(&m->lock); +#endif } return agg; } diff --git a/runtime/map.h b/runtime/map.h index 4bb8aee2e..f89dc5217 100644 --- a/runtime/map.h +++ b/runtime/map.h @@ -19,6 +19,23 @@ * @{ */ + +/* Include map spinlocks only on demand. Otherwise, assume that + caller does the right thing. */ +#ifndef NEED_MAP_LOCKS +#define NEED_MAP_LOCKS 0 +#endif + +#if NEED_MAP_LOCKS +#define MAP_GET_CPU() get_cpu() +#define MAP_PUT_CPU() put_cpu() +#else +/* get/put_cpu wrappers. Unnecessary if caller is already atomic. */ +#define MAP_GET_CPU() smp_processor_id() +#define MAP_PUT_CPU() do {} while (0) +#endif + + /* This sets the size of the hash table. */ #ifndef HASH_TABLE_BITS #define HASH_TABLE_BITS 8 @@ -102,7 +119,9 @@ struct map_root { int data_offset; +#ifdef NEED_MAP_LOCKS spinlock_t lock; +#endif /* the hash table for this array */ struct hlist_head hashes[HASH_TABLE_SIZE]; diff --git a/runtime/pmap-gen.c b/runtime/pmap-gen.c index 34bb91044..f84b9db76 100644 --- a/runtime/pmap-gen.c +++ b/runtime/pmap-gen.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- * pmap API generator - * Copyright (C) 2005 Red Hat Inc. + * Copyright (C) 2005-2007 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 @@ -411,7 +411,9 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries) m->get_key = KEYSYM(pmap_get_key); m->copy = KEYSYM(pmap_copy_keys); m->cmp = KEYSYM(pmap_key_cmp); +#if NEED_MAP_LOCKS m->lock = SPIN_LOCK_UNLOCKED; +#endif } m = &pmap->agg; m->get_key = KEYSYM(pmap_get_key); @@ -469,7 +471,9 @@ PMAP KEYSYM(_stp_pmap_new) (unsigned max_entries, int htype, ...) m->get_key = KEYSYM(pmap_get_key); m->copy = KEYSYM(pmap_copy_keys); m->cmp = KEYSYM(pmap_key_cmp); +#if NEED_MAP_LOCKS m->lock = SPIN_LOCK_UNLOCKED; +#endif } m = &pmap->agg; m->get_key = KEYSYM(pmap_get_key); @@ -530,24 +534,32 @@ int KEYSYM(__stp_pmap_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add) int KEYSYM(_stp_pmap_set) (PMAP pmap, ALLKEYSD(key), VSTYPE val) { int res; - MAP m = per_cpu_ptr (pmap->map, get_cpu()); + MAP m = per_cpu_ptr (pmap->map, MAP_GET_CPU ()); +#if NEED_MAP_LOCKS if (!spin_trylock(&m->lock)) return -3; +#endif res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 0); +#if NEED_MAP_LOCKS spin_unlock(&m->lock); - put_cpu(); +#endif + MAP_PUT_CPU (); return res; } int KEYSYM(_stp_pmap_add) (PMAP pmap, ALLKEYSD(key), VSTYPE val) { int res; - MAP m = per_cpu_ptr (pmap->map, get_cpu()); + MAP m = per_cpu_ptr (pmap->map, MAP_GET_CPU()); +#if NEED_MAP_LOCKS if (!spin_trylock(&m->lock)) return -3; +#endif res = KEYSYM(__stp_pmap_set) (m, ALLKEYS(key), val, 1); +#if NEED_MAP_LOCKS spin_unlock(&m->lock); - put_cpu(); +#endif + MAP_PUT_CPU (); return res; } @@ -564,14 +576,15 @@ VALTYPE KEYSYM(_stp_pmap_get_cpu) (PMAP pmap, ALLKEYSD(key)) if (pmap == NULL) return NULLRET; - map = per_cpu_ptr (pmap->map, get_cpu()); + map = per_cpu_ptr (pmap->map, MAP_GET_CPU ()); hv = KEYSYM(phash) (ALLKEYS(key)); head = &map->hashes[hv]; +#if NEED_MAP_LOCKS if (!spin_trylock(&map->lock)) return NULLRET; - +#endif hlist_for_each(e, head) { n = (struct KEYSYM(pmap_node) *)((long)e - sizeof(struct list_head)); if (KEY1_EQ_P(n->key1, key1) @@ -589,14 +602,18 @@ VALTYPE KEYSYM(_stp_pmap_get_cpu) (PMAP pmap, ALLKEYSD(key)) #endif ) { res = MAP_GET_VAL((struct map_node *)n); +#if NEED_MAP_LOCKS spin_unlock(&map->lock); - put_cpu(); +#endif + MAP_PUT_CPU (); return res; } } /* key not found */ +#if NEED_MAP_LOCKS spin_unlock(&map->lock); - put_cpu(); +#endif + MAP_PUT_CPU (); return NULLRET; } @@ -645,8 +662,10 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key)) map = per_cpu_ptr (pmap->map, cpu); head = &map->hashes[hv]; +#if NEED_MAP_LOCKS if (!spin_trylock(&map->lock)) return NULLRET; +#endif hlist_for_each(e, head) { n = (struct KEYSYM(pmap_node) *)((long)e - sizeof(struct list_head)); @@ -676,7 +695,9 @@ VALTYPE KEYSYM(_stp_pmap_get) (PMAP pmap, ALLKEYSD(key)) } } } +#if NEED_MAP_LOCKS spin_unlock(&map->lock); +#endif } if (anode && !clear_agg) return MAP_GET_VAL(anode); @@ -730,12 +751,16 @@ int KEYSYM(__stp_pmap_del) (MAP map, ALLKEYSD(key)) int KEYSYM(_stp_pmap_del) (PMAP pmap, ALLKEYSD(key)) { int res; - MAP m = per_cpu_ptr (pmap->map, get_cpu()); + MAP m = per_cpu_ptr (pmap->map, MAP_GET_CPU ()); +#if NEED_MAP_LOCKS if (!spin_trylock(&m->lock)) return -1; +#endif res = KEYSYM(__stp_pmap_del) (m, ALLKEYS(key)); +#if NEED_MAP_LOCKS spin_unlock(&m->lock); - put_cpu(); +#endif + MAP_PUT_CPU (); return res; } -- 2.43.5