Add a new ddb command 'show sleepq'. It takes a wait channel as an

argument and looks for a sleep queue associated with that wait channel.
If it finds one it will display information such as the list of threads
sleeping on that queue.  If it can't find a sleep queue for that wait
channel, then it will see if that address matches any of the active
sleep queues.  If so, it will display information about the sleepq at the
specified address.
This commit is contained in:
John Baldwin 2006-01-27 22:24:07 +00:00
parent 6966c33482
commit f126e754e0

View File

@ -59,11 +59,12 @@
* variables.
*/
#include "opt_sleepqueue_profiling.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_sleepqueue_profiling.h"
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/lock.h>
@ -77,6 +78,10 @@ __FBSDID("$FreeBSD$");
#include <sys/sleepqueue.h>
#include <sys/sysctl.h>
#ifdef DDB
#include <ddb/ddb.h>
#endif
/*
* Constants for the hash table of sleep queue chains. These constants are
* the same ones that 4BSD (and possibly earlier versions of BSD) used.
@ -842,3 +847,60 @@ sleepq_abort(struct thread *td)
sleepq_remove(td, wchan);
mtx_lock_spin(&sched_lock);
}
#ifdef DDB
DB_SHOW_COMMAND(sleepq, db_show_sleepqueue)
{
struct sleepqueue_chain *sc;
struct sleepqueue *sq;
struct lock_object *lock;
struct thread *td;
void *wchan;
int i;
if (!have_addr)
return;
/*
* First, see if there is an active sleep queue for the wait channel
* indicated by the address.
*/
wchan = (void *)addr;
sc = SC_LOOKUP(wchan);
LIST_FOREACH(sq, &sc->sc_queues, sq_hash)
if (sq->sq_wchan == wchan)
goto found;
/*
* Second, see if there is an active sleep queue at the address
* indicated.
*/
for (i = 0; i < SC_TABLESIZE; i++)
LIST_FOREACH(sq, &sleepq_chains[i].sc_queues, sq_hash) {
if (sq == (struct sleepqueue *)addr)
goto found;
}
db_printf("Unable to locate a sleep queue via %p\n", (void *)addr);
return;
found:
db_printf("Wait channel: %p\n", sq->sq_wchan);
#ifdef INVARIANTS
db_printf("Queue type: %d\n", sq->sq_type);
if (sq->sq_lock) {
lock = &sq->sq_lock->mtx_object;
db_printf("Associated Interlock: %p - (%s) %s\n", lock,
LOCK_CLASS(lock)->lc_name, lock->lo_name);
}
#endif
db_printf("Blocked threads:\n");
if (TAILQ_EMPTY(&sq->sq_blocked))
db_printf("\tempty\n");
else
TAILQ_FOREACH(td, &sq->sq_blocked, td_slpq) {
db_printf("\t%p (tid %d, pid %d, \"%s\")\n", td,
td->td_tid, td->td_proc->p_pid,
td->td_proc->p_comm);
}
}
#endif