[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v5 05/13] xen/spinlock: make struct lock_profile rspinlock_t aware
Struct lock_profile contains a pointer to the spinlock it is associated with. Prepare support of differing spinlock_t and rspinlock_t types by adding a type indicator of the pointer. Use the highest bit of the block_cnt member for this indicator in order to not grow the struct while hurting only the slow path with slightly less performant code. Note that this requires a cast when printing the value in order to be format compliant. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Acked-by: Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx> Acked-by: Julien Grall <jgrall@xxxxxxxxxx> --- V2: - new patch V5: - use bool for is_rlock (Julien Grall) - use unsigned int for lockval in spinlock_profile_print_elem() (Jan Beulich) - don't use anonymous union (Jan Beulich) --- xen/common/spinlock.c | 28 ++++++++++++++++++++-------- xen/include/xen/spinlock.h | 14 ++++++++++---- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c index 5ef0ac7f89..0e8b525cec 100644 --- a/xen/common/spinlock.c +++ b/xen/common/spinlock.c @@ -538,19 +538,31 @@ static void spinlock_profile_iterate(lock_profile_subfunc *sub, void *par) static void cf_check spinlock_profile_print_elem(struct lock_profile *data, int32_t type, int32_t idx, void *par) { - struct spinlock *lock = data->lock; + unsigned int cpu; + unsigned int lockval; + + if ( data->is_rlock ) + { + cpu = data->ptr.rlock->debug.cpu; + lockval = data->ptr.rlock->tickets.head_tail; + } + else + { + cpu = data->ptr.lock->debug.cpu; + lockval = data->ptr.lock->tickets.head_tail; + } printk("%s ", lock_profile_ancs[type].name); if ( type != LOCKPROF_TYPE_GLOBAL ) printk("%d ", idx); - printk("%s: addr=%p, lockval=%08x, ", data->name, lock, - lock->tickets.head_tail); - if ( lock->debug.cpu == SPINLOCK_NO_CPU ) + printk("%s: addr=%p, lockval=%08x, ", data->name, data->ptr.lock, lockval); + if ( cpu == SPINLOCK_NO_CPU ) printk("not locked\n"); else - printk("cpu=%d\n", lock->debug.cpu); - printk(" lock:%" PRId64 "(%" PRI_stime "), block:%" PRId64 "(%" PRI_stime ")\n", - data->lock_cnt, data->time_hold, data->block_cnt, data->time_block); + printk("cpu=%u\n", cpu); + printk(" lock:%" PRIu64 "(%" PRI_stime "), block:%" PRIu64 "(%" PRI_stime ")\n", + data->lock_cnt, data->time_hold, (uint64_t)data->block_cnt, + data->time_block); } void cf_check spinlock_profile_printall(unsigned char key) @@ -680,7 +692,7 @@ static int __init cf_check lock_prof_init(void) { (*q)->next = lock_profile_glb_q.elem_q; lock_profile_glb_q.elem_q = *q; - (*q)->lock->profile = *q; + (*q)->ptr.lock->profile = *q; } _lock_profile_register_struct(LOCKPROF_TYPE_GLOBAL, diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h index afa24c8e29..49c5115f52 100644 --- a/xen/include/xen/spinlock.h +++ b/xen/include/xen/spinlock.h @@ -77,13 +77,19 @@ union lock_debug { }; */ struct spinlock; +/* Temporary hack until a dedicated struct rspinlock is existing. */ +#define rspinlock spinlock struct lock_profile { struct lock_profile *next; /* forward link */ const char *name; /* lock name */ - struct spinlock *lock; /* the lock itself */ + union { + struct spinlock *lock; /* the lock itself */ + struct rspinlock *rlock; /* the recursive lock itself */ + } ptr; uint64_t lock_cnt; /* # of complete locking ops */ - uint64_t block_cnt; /* # of complete wait for lock */ + uint64_t block_cnt:63; /* # of complete wait for lock */ + bool is_rlock:1; /* use rlock pointer */ s_time_t time_hold; /* cumulated lock time */ s_time_t time_block; /* cumulated wait time */ s_time_t time_locked; /* system time of last locking */ @@ -95,7 +101,7 @@ struct lock_profile_qhead { int32_t idx; /* index for printout */ }; -#define LOCK_PROFILE_(lockname) { .name = #lockname, .lock = &(lockname), } +#define LOCK_PROFILE_(lockname) { .name = #lockname, .ptr.lock = &(lockname), } #define LOCK_PROFILE_PTR_(name) \ static struct lock_profile * const lock_profile__##name \ __used_section(".lockprofile.data") = \ @@ -128,7 +134,7 @@ struct lock_profile_qhead { break; \ } \ prof->name = #l; \ - prof->lock = &(s)->l; \ + prof->ptr.lock = &(s)->l; \ prof->next = (s)->profile_head.elem_q; \ (s)->profile_head.elem_q = prof; \ } while( 0 ) -- 2.35.3
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |