Date: Mon, 15 Aug 2016 12:56:45 +0000 (UTC) From: Bruce Evans <bde@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r304153 - head/sys/dev/syscons Message-ID: <201608151256.u7FCujHw048832@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bde Date: Mon Aug 15 12:56:45 2016 New Revision: 304153 URL: https://svnweb.freebsd.org/changeset/base/304153 Log: 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). Modified: head/sys/dev/syscons/syscons.c head/sys/dev/syscons/syscons.h Modified: head/sys/dev/syscons/syscons.c ============================================================================== --- head/sys/dev/syscons/syscons.c Mon Aug 15 12:13:14 2016 (r304152) +++ head/sys/dev/syscons/syscons.c Mon Aug 15 12:56:45 2016 (r304153) @@ -2688,13 +2688,13 @@ sc_puts(scr_stat *scp, u_char *buf, int #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_st scp->history = NULL; scp->history_pos = 0; scp->history_size = 0; - - mtx_init(&scp->scr_lock, "scrlock", NULL, MTX_SPIN); } int Modified: head/sys/dev/syscons/syscons.h ============================================================================== --- head/sys/dev/syscons/syscons.h Mon Aug 15 12:13:14 2016 (r304152) +++ head/sys/dev/syscons/syscons.h Mon Aug 15 12:56:45 2016 (r304153) @@ -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608151256.u7FCujHw048832>