Include the associated wait channel message for context switch ktrace

records.  kdump supports both the old and new messages.

Submitted by:	Andrey Zonov  andrey zonov org
MFC after:	1 week
This commit is contained in:
John Baldwin 2012-04-20 15:32:36 +00:00
parent e7babf043f
commit 88bf5036fc
7 changed files with 44 additions and 22 deletions

View File

@ -103,7 +103,7 @@ _cv_wait(struct cv *cvp, struct lock_object *lock)
lock_state = 0; lock_state = 0;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, cv_wmesg(cvp));
#endif #endif
CV_ASSERT(cvp, lock, td); CV_ASSERT(cvp, lock, td);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
@ -140,7 +140,7 @@ _cv_wait(struct cv *cvp, struct lock_object *lock)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, cv_wmesg(cvp));
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
if (lock != &Giant.lock_object) { if (lock != &Giant.lock_object) {
@ -162,7 +162,7 @@ _cv_wait_unlock(struct cv *cvp, struct lock_object *lock)
td = curthread; td = curthread;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, cv_wmesg(cvp));
#endif #endif
CV_ASSERT(cvp, lock, td); CV_ASSERT(cvp, lock, td);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
@ -197,7 +197,7 @@ _cv_wait_unlock(struct cv *cvp, struct lock_object *lock)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, cv_wmesg(cvp));
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
} }
@ -220,7 +220,7 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock)
lock_state = 0; lock_state = 0;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, cv_wmesg(cvp));
#endif #endif
CV_ASSERT(cvp, lock, td); CV_ASSERT(cvp, lock, td);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
@ -258,7 +258,7 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, cv_wmesg(cvp));
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
if (lock != &Giant.lock_object) { if (lock != &Giant.lock_object) {
@ -286,7 +286,7 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo)
lock_state = 0; lock_state = 0;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, cv_wmesg(cvp));
#endif #endif
CV_ASSERT(cvp, lock, td); CV_ASSERT(cvp, lock, td);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
@ -324,7 +324,7 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, cv_wmesg(cvp));
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
if (lock != &Giant.lock_object) { if (lock != &Giant.lock_object) {
@ -353,7 +353,7 @@ _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo)
lock_state = 0; lock_state = 0;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, cv_wmesg(cvp));
#endif #endif
CV_ASSERT(cvp, lock, td); CV_ASSERT(cvp, lock, td);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
@ -392,7 +392,7 @@ _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, cv_wmesg(cvp));
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
if (lock != &Giant.lock_object) { if (lock != &Giant.lock_object) {

View File

@ -733,8 +733,9 @@ ktrpsig(sig, action, mask, code)
} }
void void
ktrcsw(out, user) ktrcsw(out, user, wmesg)
int out, user; int out, user;
const char *wmesg;
{ {
struct thread *td = curthread; struct thread *td = curthread;
struct ktr_request *req; struct ktr_request *req;
@ -746,6 +747,10 @@ ktrcsw(out, user)
kc = &req->ktr_data.ktr_csw; kc = &req->ktr_data.ktr_csw;
kc->out = out; kc->out = out;
kc->user = user; kc->user = user;
if (wmesg != NULL)
strlcpy(kc->wmesg, wmesg, sizeof(kc->wmesg));
else
bzero(kc->wmesg, sizeof(kc->wmesg));
ktr_enqueuerequest(td, req); ktr_enqueuerequest(td, req);
ktrace_exit(td); ktrace_exit(td);
} }

View File

@ -142,7 +142,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
p = td->td_proc; p = td->td_proc;
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 0); ktrcsw(1, 0, wmesg);
#endif #endif
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
"Sleeping on \"%s\"", wmesg); "Sleeping on \"%s\"", wmesg);
@ -236,7 +236,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
} }
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, wmesg);
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
if (lock != NULL && lock != &Giant.lock_object && !(priority & PDROP)) { if (lock != NULL && lock != &Giant.lock_object && !(priority & PDROP)) {
@ -298,7 +298,7 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) { if (KTRPOINT(td, KTR_CSW)) {
sleepq_release(ident); sleepq_release(ident);
ktrcsw(1, 0); ktrcsw(1, 0, wmesg);
sleepq_lock(ident); sleepq_lock(ident);
} }
#endif #endif
@ -316,7 +316,7 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
} }
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 0); ktrcsw(0, 0, wmesg);
#endif #endif
PICKUP_GIANT(); PICKUP_GIANT();
mtx_lock_spin(mtx); mtx_lock_spin(mtx);

View File

@ -219,7 +219,7 @@ ast(struct trapframe *framep)
if (flags & TDF_NEEDRESCHED) { if (flags & TDF_NEEDRESCHED) {
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(1, 1); ktrcsw(1, 1, __func__);
#endif #endif
thread_lock(td); thread_lock(td);
sched_prio(td, td->td_user_pri); sched_prio(td, td->td_user_pri);
@ -227,7 +227,7 @@ ast(struct trapframe *framep)
thread_unlock(td); thread_unlock(td);
#ifdef KTRACE #ifdef KTRACE
if (KTRPOINT(td, KTR_CSW)) if (KTRPOINT(td, KTR_CSW))
ktrcsw(0, 1); ktrcsw(0, 1, __func__);
#endif #endif
} }

View File

@ -135,9 +135,15 @@ struct ktr_psig {
* KTR_CSW - trace context switches * KTR_CSW - trace context switches
*/ */
#define KTR_CSW 6 #define KTR_CSW 6
struct ktr_csw_old {
int out; /* 1 if switch out, 0 if switch in */
int user; /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
};
struct ktr_csw { struct ktr_csw {
int out; /* 1 if switch out, 0 if switch in */ int out; /* 1 if switch out, 0 if switch in */
int user; /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */ int user; /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
char wmesg[8];
}; };
/* /*
@ -244,7 +250,7 @@ struct ktr_faultend {
#ifdef _KERNEL #ifdef _KERNEL
void ktrnamei(char *); void ktrnamei(char *);
void ktrcsw(int, int); void ktrcsw(int, int, const char *);
void ktrpsig(int, sig_t, sigset_t *, int); void ktrpsig(int, sig_t, sigset_t *, int);
void ktrfault(vm_offset_t, int); void ktrfault(vm_offset_t, int);
void ktrfaultend(int); void ktrfaultend(int);

View File

@ -28,7 +28,7 @@
.\" @(#)kdump.1 8.1 (Berkeley) 6/6/93 .\" @(#)kdump.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 5, 2012 .Dd April 20, 2012
.Dt KDUMP 1 .Dt KDUMP 1
.Os .Os
.Sh NAME .Sh NAME
@ -167,7 +167,7 @@ The possible operations are:
.It Li NAMI Ta file name lookup Ta path to file .It Li NAMI Ta file name lookup Ta path to file
.It Li GIO Ta general I/O Ta fd, read/write, number of bytes .It Li GIO Ta general I/O Ta fd, read/write, number of bytes
.It Li PSIG Ta signal Ta signal name, handler, mask, code .It Li PSIG Ta signal Ta signal name, handler, mask, code
.It Li CSW Ta context switch Ta stop/resume user/kernel .It Li CSW Ta context switch Ta stop/resume user/kernel wmesg
.It Li USER Ta data from user process Ta the data .It Li USER Ta data from user process Ta the data
.It Li STRU Ta various syscalls Ta structure .It Li STRU Ta various syscalls Ta structure
.It Li SCTL Ta Xr sysctl 3 requests Ta MIB name .It Li SCTL Ta Xr sysctl 3 requests Ta MIB name

View File

@ -95,6 +95,7 @@ void visdump(char *, int, int);
void ktrgenio(struct ktr_genio *, int); void ktrgenio(struct ktr_genio *, int);
void ktrpsig(struct ktr_psig *); void ktrpsig(struct ktr_psig *);
void ktrcsw(struct ktr_csw *); void ktrcsw(struct ktr_csw *);
void ktrcsw_old(struct ktr_csw_old *);
void ktruser_malloc(unsigned char *); void ktruser_malloc(unsigned char *);
void ktruser_rtld(int, unsigned char *); void ktruser_rtld(int, unsigned char *);
void ktruser(int, unsigned char *); void ktruser(int, unsigned char *);
@ -298,7 +299,10 @@ main(int argc, char *argv[])
ktrpsig((struct ktr_psig *)m); ktrpsig((struct ktr_psig *)m);
break; break;
case KTR_CSW: case KTR_CSW:
ktrcsw((struct ktr_csw *)m); if (ktrlen == sizeof(struct ktr_csw_old))
ktrcsw_old((struct ktr_csw_old *)m);
else
ktrcsw((struct ktr_csw *)m);
break; break;
case KTR_USER: case KTR_USER:
ktruser(ktrlen, m); ktruser(ktrlen, m);
@ -1245,12 +1249,19 @@ ktrpsig(struct ktr_psig *psig)
} }
void void
ktrcsw(struct ktr_csw *cs) ktrcsw_old(struct ktr_csw_old *cs)
{ {
printf("%s %s\n", cs->out ? "stop" : "resume", printf("%s %s\n", cs->out ? "stop" : "resume",
cs->user ? "user" : "kernel"); cs->user ? "user" : "kernel");
} }
void
ktrcsw(struct ktr_csw *cs)
{
printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
cs->user ? "user" : "kernel", cs->wmesg);
}
#define UTRACE_DLOPEN_START 1 #define UTRACE_DLOPEN_START 1
#define UTRACE_DLOPEN_STOP 2 #define UTRACE_DLOPEN_STOP 2
#define UTRACE_DLCLOSE_START 3 #define UTRACE_DLCLOSE_START 3