aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2017-08-24 15:12:16 +0000
committerConrad Meyer <cem@FreeBSD.org>2017-08-24 15:12:16 +0000
commit0c1d923efbbf22fb2377ff33213e73be8e5d6bf4 (patch)
tree51baf07ea3d0bedd724b2861396c1c0fb7bcb269 /sys
parent2624320fccf024cdc642d0e88ac380b82c831317 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_turnstile.c88
1 files changed, 17 insertions, 71 deletions
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c
index dd39835d0dc2..94af470f523b 100644
--- a/sys/kern/subr_turnstile.c
+++ b/sys/kern/subr_turnstile.c
@@ -1096,7 +1096,7 @@ found:
/*
* Show all the threads a particular thread is waiting on based on
- * non-sleepable and non-spin locks.
+ * non-spin locks.
*/
static void
print_lockchain(struct thread *td, const char *prefix)
@@ -1104,10 +1104,11 @@ print_lockchain(struct thread *td, const char *prefix)
struct lock_object *lock;
struct lock_class *class;
struct turnstile *ts;
+ struct thread *owner;
/*
* Follow the chain. We keep walking as long as the thread is
- * blocked on a turnstile that has an owner.
+ * blocked on a lock that has an owner.
*/
while (!db_pager_quit) {
db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
@@ -1136,6 +1137,17 @@ print_lockchain(struct thread *td, const char *prefix)
return;
td = ts->ts_owner;
break;
+ } else if (TD_ON_SLEEPQ(td)) {
+ if (!lockmgr_chain(td, &owner) &&
+ !sx_chain(td, &owner)) {
+ db_printf("sleeping on %p \"%s\"\n",
+ td->td_wchan, td->td_wmesg);
+ return;
+ }
+ if (owner == NULL)
+ return;
+ td = owner;
+ break;
}
db_printf("inhibited\n");
return;
@@ -1158,6 +1170,7 @@ DB_SHOW_COMMAND(lockchain, db_show_lockchain)
print_lockchain(td, "");
}
+DB_SHOW_ALIAS(sleepchain, db_show_lockchain);
DB_SHOW_ALL_COMMAND(chains, db_show_allchains)
{
@@ -1168,14 +1181,11 @@ DB_SHOW_ALL_COMMAND(chains, db_show_allchains)
i = 1;
FOREACH_PROC_IN_SYSTEM(p) {
FOREACH_THREAD_IN_PROC(p, td) {
- if (TD_ON_LOCK(td) && LIST_EMPTY(&td->td_contested)) {
+ if ((TD_ON_LOCK(td) && LIST_EMPTY(&td->td_contested))
+ || (TD_IS_INHIBITED(td) && TD_ON_SLEEPQ(td))) {
db_printf("chain %d:\n", i++);
print_lockchain(td, " ");
}
- if (TD_IS_INHIBITED(td) && TD_ON_SLEEPQ(td)) {
- db_printf("chain %d:\n", i++);
- print_sleepchain(td, " ");
- }
if (db_pager_quit)
return;
}
@@ -1183,70 +1193,6 @@ DB_SHOW_ALL_COMMAND(chains, db_show_allchains)
}
DB_SHOW_ALIAS(allchains, db_show_allchains)
-/*
- * Show all the threads a particular thread is waiting on based on
- * sleepable locks.
- */
-static void
-print_sleepchain(struct thread *td, const char *prefix)
-{
- struct thread *owner;
-
- /*
- * Follow the chain. We keep walking as long as the thread is
- * blocked on a sleep lock that has an owner.
- */
- while (!db_pager_quit) {
- db_printf("%sthread %d (pid %d, %s) ", prefix, td->td_tid,
- td->td_proc->p_pid, td->td_name);
- switch (td->td_state) {
- case TDS_INACTIVE:
- db_printf("is inactive\n");
- return;
- case TDS_CAN_RUN:
- db_printf("can run\n");
- return;
- case TDS_RUNQ:
- db_printf("is on a run queue\n");
- return;
- case TDS_RUNNING:
- db_printf("running on CPU %d\n", td->td_oncpu);
- return;
- case TDS_INHIBITED:
- if (TD_ON_SLEEPQ(td)) {
- if (lockmgr_chain(td, &owner) ||
- sx_chain(td, &owner)) {
- if (owner == NULL)
- return;
- td = owner;
- break;
- }
- db_printf("sleeping on %p \"%s\"\n",
- td->td_wchan, td->td_wmesg);
- return;
- }
- db_printf("inhibited\n");
- return;
- default:
- db_printf("??? (%#x)\n", td->td_state);
- return;
- }
- }
-}
-
-DB_SHOW_COMMAND(sleepchain, db_show_sleepchain)
-{
- struct thread *td;
-
- /* Figure out which thread to start with. */
- if (have_addr)
- td = db_lookup_thread(addr, true);
- else
- td = kdb_thread;
-
- print_sleepchain(td, "");
-}
-
static void print_waiters(struct turnstile *ts, int indent);
static void