summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-01-20 02:04:44 +0000
committerjhb <jhb@FreeBSD.org>2001-01-20 02:04:44 +0000
commita11e21597d3b3fd5943eab7683f1b2f629e945d6 (patch)
tree3e82df62aa72ee95a21d7796e195aed7a29f822c /sys
parent3427c48eabd960e4cb662a111aad5f34b748c079 (diff)
downloadFreeBSD-src-a11e21597d3b3fd5943eab7683f1b2f629e945d6.zip
FreeBSD-src-a11e21597d3b3fd5943eab7683f1b2f629e945d6.tar.gz
Be more careful with sched_lock in the SIGINFO handler. Specifically, do
not hold sched_lock while calling ttyprintf(). If we are on a serial console, then ttyprintf() will end up getting the sio lock, resulting in a lock order violation. Noticed by: des
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/tty.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index b80d266..3f11c4f 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -2234,6 +2234,8 @@ ttyinfo(tp)
register struct proc *p, *pick;
struct timeval utime, stime;
int tmp;
+ const char *s;
+ long l;
if (ttycheckoutq(tp,0) == 0)
return;
@@ -2255,11 +2257,14 @@ ttyinfo(tp)
pick = p;
mtx_enter(&sched_lock, MTX_SPIN);
+ s = pick->p_stat == SRUN ? "running" :
+ pick->p_wmesg ? pick->p_wmesg : "iowait";
+ mtx_exit(&sched_lock, MTX_SPIN);
ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
- pick->p_stat == SRUN ? "running" :
- pick->p_wmesg ? pick->p_wmesg : "iowait");
-
+ s);
+ mtx_enter(&sched_lock, MTX_SPIN);
if (pick->p_flag & P_INMEM) {
+ mtx_exit(&sched_lock, MTX_SPIN);
calcru(pick, &utime, &stime, NULL);
/* Print user time. */
@@ -2269,17 +2274,23 @@ ttyinfo(tp)
/* Print system time. */
ttyprintf(tp, "%ld.%02lds ",
stime.tv_sec, stime.tv_usec / 10000);
- } else
+ } else {
+ mtx_exit(&sched_lock, MTX_SPIN);
ttyprintf(tp, "?.??u ?.??s ");
+ }
/* Print percentage cpu, resident set size. */
+ mtx_enter(&sched_lock, MTX_SPIN);
tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
- ttyprintf(tp, "%d%% %ldk\n",
- tmp / 100,
- pick->p_stat == SIDL || pick->p_stat == SWAIT ||
- pick->p_stat == SZOMB ? 0 :
- (long)pgtok(vmspace_resident_count(pick->p_vmspace)));
- mtx_exit(&sched_lock, MTX_SPIN);
+ if (pick->p_stat == SIDL || pick->p_stat == SWAIT ||
+ pick->p_stat == SZOMB) {
+ mtx_exit(&sched_lock, MTX_SPIN);
+ l = 0;
+ } else {
+ mtx_exit(&sched_lock, MTX_SPIN);
+ l = pgtok(vmspace_resident_count(pick->p_vmspace));
+ }
+ ttyprintf(tp, "%d%% %ldk\n", tmp / 100, l);
}
tp->t_rocount = 0; /* so pending input will be retyped if BS */
}
OpenPOWER on IntegriCloud