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:
Juergen Gross authored and Jan Beulich committed 2024-03-19 11:26:34 +01:00
1 parent cc3e8df542
commit b053075d1a
2 files changed
+30 -12

No files matched your search

+20 -8
View File
@@ -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,
+10 -4
View File
@@ -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 )
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.