Quick fix for locking fixes in r172250. The lock added there was per-
virtual-device, but needs to be per-physical-device so that it protects shared data. Usually, scp->sc->write_in_progress got corrupted first and further corruption was limited when this variable was left at nonzero with no write in progress. Attempt to fix missing lock destruction in r162285. Put it with the lock destruction for r172250 after moving the latter. Both might be unreachable. To demonstrate the bug, find a buggy syscall or sysctl that calls printf(9) and run this often. Run hd /dev/zero >/dev/ttyvN for any N != 0. The console spam goes to ttyv0 and the non-console spam goes to ttyvN, so the lock provided no protection (but it helped for N == 0).
This commit is contained in:
parent
0df377cbb8
commit
40de550ba7
@ -2688,13 +2688,13 @@ sc_puts(scr_stat *scp, u_char *buf, int len, int kernel)
|
||||
#endif
|
||||
|
||||
if (scp->tsw) {
|
||||
if (!kdb_active && !mtx_owned(&scp->scr_lock)) {
|
||||
if (!kdb_active && !mtx_owned(&scp->sc->scr_lock)) {
|
||||
need_unlock = 1;
|
||||
mtx_lock_spin(&scp->scr_lock);
|
||||
mtx_lock_spin(&scp->sc->scr_lock);
|
||||
}
|
||||
(*scp->tsw->te_puts)(scp, buf, len, kernel);
|
||||
if (need_unlock)
|
||||
mtx_unlock_spin(&scp->scr_lock);
|
||||
mtx_unlock_spin(&scp->sc->scr_lock);
|
||||
}
|
||||
|
||||
if (scp->sc->delayed_next_scr)
|
||||
@ -2859,8 +2859,10 @@ scinit(int unit, int flags)
|
||||
* disappeared...
|
||||
*/
|
||||
sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
|
||||
if ((sc->flags & SC_INIT_DONE) == 0)
|
||||
if ((sc->flags & SC_INIT_DONE) == 0) {
|
||||
mtx_init(&sc->scr_lock, "scrlock", NULL, MTX_SPIN);
|
||||
SC_VIDEO_LOCKINIT(sc);
|
||||
}
|
||||
|
||||
adp = NULL;
|
||||
if (sc->adapter >= 0) {
|
||||
@ -3077,7 +3079,8 @@ scterm(int unit, int flags)
|
||||
(*scp->tsw->te_term)(scp, &scp->ts);
|
||||
if (scp->ts != NULL)
|
||||
free(scp->ts, M_DEVBUF);
|
||||
mtx_destroy(&scp->scr_lock);
|
||||
mtx_destroy(&sc->scr_lock);
|
||||
mtx_destroy(&sc->video_mtx);
|
||||
|
||||
/* clear the structure */
|
||||
if (!(flags & SC_KERNEL_CONSOLE)) {
|
||||
@ -3302,8 +3305,6 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
|
||||
scp->history = NULL;
|
||||
scp->history_pos = 0;
|
||||
scp->history_size = 0;
|
||||
|
||||
mtx_init(&scp->scr_lock, "scrlock", NULL, MTX_SPIN);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -230,6 +230,7 @@ typedef struct sc_softc {
|
||||
char switch_in_progress;
|
||||
char write_in_progress;
|
||||
char blink_in_progress;
|
||||
struct mtx scr_lock; /* mutex for sc_puts() */
|
||||
struct mtx video_mtx;
|
||||
|
||||
long scrn_time_stamp;
|
||||
@ -344,7 +345,6 @@ typedef struct scr_stat {
|
||||
|
||||
int splash_save_mode; /* saved mode for splash screen */
|
||||
int splash_save_status; /* saved status for splash screen */
|
||||
struct mtx scr_lock; /* mutex for sc_puts() */
|
||||
#ifdef _SCR_MD_STAT_DECLARED_
|
||||
scr_md_stat_t md; /* machine dependent vars */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user