diff options
author | jhb <jhb@FreeBSD.org> | 2001-01-20 02:04:44 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-01-20 02:04:44 +0000 |
commit | a11e21597d3b3fd5943eab7683f1b2f629e945d6 (patch) | |
tree | 3e82df62aa72ee95a21d7796e195aed7a29f822c /sys | |
parent | 3427c48eabd960e4cb662a111aad5f34b748c079 (diff) | |
download | FreeBSD-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.c | 31 |
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 */ } |