mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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@suse.com> Acked-by: Alejandro Vallejo <alejandro.vallejo@cloud.com> Acked-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
1 parent
cc3e8df542
commit
b053075d1a
2 files changed
+30
-12
No files matched your search
+20
-8
@@ -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,
|
||||
|
||||
@@ -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 )
|
||||
|
||||