svn commit: r319720 - head/sys/dev/vt
Jonathan T. Looney
jtl at FreeBSD.org
Thu Jun 8 20:47:20 UTC 2017
Author: jtl
Date: Thu Jun 8 20:47:18 2017
New Revision: 319720
URL: https://svnweb.freebsd.org/changeset/base/319720
Log:
With EARLY_AP_STARTUP enabled, we are seeing crashes in softclock_call_cc()
during bootup. Debugging information shows that softclock_call_cc() is
trying to execute the vt_consdev.vd_timer callout, and the callout
structure contains a NULL c_func.
This appears to be due to a race between vt_upgrade() running
callout_reset() and vt_resume_flush_timer() calling callout_schedule().
Fix the race by ensuring that vd_timer_armed is always set before
attempting to (re)schedule the callout.
Discussed with: emaste
MFC after: 2 weeks
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D9828
Modified:
head/sys/dev/vt/vt_core.c
Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c Thu Jun 8 20:41:28 2017 (r319719)
+++ head/sys/dev/vt/vt_core.c Thu Jun 8 20:47:18 2017 (r319720)
@@ -2610,10 +2610,17 @@ vt_upgrade(struct vt_device *vd)
/* Init 25 Hz timer. */
callout_init_mtx(&vd->vd_timer, &vd->vd_lock, 0);
- /* Start timer when everything ready. */
+ /*
+ * Start timer when everything ready.
+ * Note that the operations here are purposefully ordered.
+ * We need to ensure vd_timer_armed is non-zero before we set
+ * the VDF_ASYNC flag. That prevents this function from
+ * racing with vt_resume_flush_timer() to update the
+ * callout structure.
+ */
+ atomic_add_acq_int(&vd->vd_timer_armed, 1);
vd->vd_flags |= VDF_ASYNC;
callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd);
- vd->vd_timer_armed = 1;
register_handlers = 1;
}
More information about the svn-src-head
mailing list