From 2a9d466332523e6c2d4eb9fd0495ec2f79314658 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 11 Dec 2010 00:38:45 -0800 Subject: [PATCH] kernel - Record token & mplock collisions in thread->td_wmesg * Record token & mplock collisions which the lwkt thread schedule spins on in the thread wmesg, which will show up in ps, top, etc. This makes it a lot more obvious when a thread is stalling on a token or the mplock and is generally superior to the old per-cpu collision record. --- sys/kern/lwkt_thread.c | 26 +++++--------------------- sys/kern/lwkt_token.c | 5 ++--- sys/sys/mplock2.h | 13 +++++++++++++ sys/sys/thread.h | 2 +- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/sys/kern/lwkt_thread.c b/sys/kern/lwkt_thread.c index 6d32a6b6ac..49f5cedeb9 100644 --- a/sys/kern/lwkt_thread.c +++ b/sys/kern/lwkt_thread.c @@ -498,8 +498,6 @@ lwkt_switch(void) int mpheld; #endif int didaccumulate; - const char *lmsg; /* diagnostic - 'systat -pv 1' */ - const void *laddr; /* * Switching from within a 'fast' (non thread switched) interrupt or IPI @@ -672,9 +670,10 @@ lwkt_switch(void) if (ntd->td_fairq_accum >= 0 && #ifdef SMP (ntd->td_mpcount + ntd->td_xpcount == 0 || - mpheld || cpu_try_mplock()) && + mpheld || cpu_try_mplock_msg(&ntd->td_wmesg)) && #endif - (!TD_TOKS_HELD(ntd) || lwkt_getalltokens(ntd, &lmsg, &laddr)) + (!TD_TOKS_HELD(ntd) || + lwkt_getalltokens(ntd)) ) { #ifdef SMP clr_cpu_contention_mask(gd); @@ -682,18 +681,11 @@ lwkt_switch(void) goto havethread; } - lmsg = NULL; - laddr = NULL; - #ifdef SMP if (ntd->td_fairq_accum >= 0) set_cpu_contention_mask(gd); /* Reload mpheld (it become stale after mplock/token ops) */ mpheld = MP_LOCK_HELD(gd); - if (ntd->td_mpcount + ntd->td_xpcount && mpheld == 0) { - lmsg = "mplock"; - laddr = ntd->td_mplock_stallpc; - } #endif /* @@ -778,9 +770,6 @@ lwkt_switch(void) */ if (didaccumulate) break; /* try again from the top, almost */ - if (lmsg) - strlcpy(cpu_time.cp_msg, lmsg, sizeof(cpu_time.cp_msg)); - cpu_time.cp_stallpc = (uintptr_t)laddr; goto haveidle; } @@ -794,9 +783,9 @@ lwkt_switch(void) user_pri_sched) && ntd->td_fairq_accum >= 0 && #ifdef SMP (ntd->td_mpcount + ntd->td_xpcount == 0 || - mpheld || cpu_try_mplock()) && + mpheld || cpu_try_mplock_msg(&ntd->td_wmesg)) && #endif - (!TD_TOKS_HELD(ntd) || lwkt_getalltokens(ntd, &lmsg, &laddr)) + (!TD_TOKS_HELD(ntd) || lwkt_getalltokens(ntd)) ) { #ifdef SMP clr_cpu_contention_mask(gd); @@ -809,17 +798,12 @@ lwkt_switch(void) * resources (tokens and/or mplock). */ #ifdef SMP - ntd->td_wmesg = lmsg; if (ntd->td_fairq_accum >= 0) set_cpu_contention_mask(gd); /* * Reload mpheld (it become stale after mplock/token ops). */ mpheld = MP_LOCK_HELD(gd); - if (ntd->td_mpcount + ntd->td_xpcount && mpheld == 0) { - lmsg = "mplock"; - laddr = ntd->td_mplock_stallpc; - } if (ntd->td_pri >= TDPRI_KERN_LPSCHED && ntd->td_fairq_accum >= 0) nquserok = 0; #endif diff --git a/sys/kern/lwkt_token.c b/sys/kern/lwkt_token.c index 18a930ae06..5d6fdb8ad8 100644 --- a/sys/kern/lwkt_token.c +++ b/sys/kern/lwkt_token.c @@ -226,7 +226,7 @@ _lwkt_tokref_init(lwkt_tokref_t ref, lwkt_token_t tok, thread_t td) * Called from a critical section. */ int -lwkt_getalltokens(thread_t td, const char **msgp, const void **addrp) +lwkt_getalltokens(thread_t td) { lwkt_tokref_t scan; lwkt_tokref_t ref; @@ -267,8 +267,7 @@ lwkt_getalltokens(thread_t td, const char **msgp, const void **addrp) * Otherwise we failed to acquire all the tokens. * Undo and return. */ - *msgp = tok->t_desc; - *addrp = scan->tr_stallpc; + td->td_wmesg = tok->t_desc; atomic_add_long(&tok->t_collisions, 1); lwkt_relalltokens(td); return(FALSE); diff --git a/sys/sys/mplock2.h b/sys/sys/mplock2.h index 1f25fd1dde..110899367e 100644 --- a/sys/sys/mplock2.h +++ b/sys/sys/mplock2.h @@ -21,6 +21,7 @@ #define get_mplock() get_mplock_debug(__FILE__, __LINE__) #define try_mplock() try_mplock_debug(__FILE__, __LINE__) #define cpu_try_mplock() cpu_try_mplock_debug(__FILE__, __LINE__) +#define cpu_try_mplock_msg(lmsg) cpu_try_mplock_msg_debug(lmsg, __FILE__, __LINE__) void _get_mplock_predisposed(const char *file, int line); void _get_mplock_contested(const char *file, int line); @@ -151,6 +152,18 @@ cpu_try_mplock_debug(const char *file, int line) return(1); } +static __inline +int +cpu_try_mplock_msg_debug(const char **lmsg, const char *file, int line) +{ + if (cpu_try_mplock_debug(file, line)) { + return(1); + } else { + *lmsg = "mplock"; + return(0); + } +} + /* * A cpu wanted the MP lock but could not get it. This function is also * called directly from the LWKT scheduler. diff --git a/sys/sys/thread.h b/sys/sys/thread.h index 0477040444..84eea7a15a 100644 --- a/sys/sys/thread.h +++ b/sys/sys/thread.h @@ -444,7 +444,7 @@ extern void lwkt_gettoken_hard(lwkt_token_t); extern int lwkt_trytoken(lwkt_token_t); extern void lwkt_reltoken(lwkt_token_t); extern void lwkt_reltoken_hard(lwkt_token_t); -extern int lwkt_getalltokens(thread_t, const char **, const void **); +extern int lwkt_getalltokens(thread_t); extern void lwkt_relalltokens(thread_t); extern void lwkt_drain_token_requests(void); extern void lwkt_token_init(lwkt_token_t, int, const char *); -- 2.41.0