Index: sysmonvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmonvar.h,v
retrieving revision 1.45
diff -p -u -2 -r1.45 sysmonvar.h
--- sysmonvar.h	22 Nov 2014 15:00:05 -0000	1.45
+++ sysmonvar.h	13 Mar 2015 17:21:50 -0000
@@ -208,5 +208,9 @@ struct sysmon_envsys {
 	 * Locking/synchronization.
 	 */
+	int sme_busy;			/* number of items on workqueue,
+					   sme_mtx or sme_work_mtx to read,
+					   both to write */
 	kmutex_t sme_mtx;
+	kmutex_t sme_work_mtx;
 	kcondvar_t sme_condvar;
 };
Index: sysmon_envsys.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon_envsys.c,v
retrieving revision 1.128
diff -p -u -2 -r1.128 sysmon_envsys.c
--- sysmon_envsys.c	23 Nov 2014 10:00:20 -0000	1.128
+++ sysmon_envsys.c	13 Mar 2015 17:21:50 -0000
@@ -486,4 +486,5 @@ sysmon_envsys_create(void)
 	LIST_INIT(&sme->sme_events_list);
 	mutex_init(&sme->sme_mtx, MUTEX_DEFAULT, IPL_NONE);
+	mutex_init(&sme->sme_work_mtx, MUTEX_DEFAULT, IPL_NONE);
 	cv_init(&sme->sme_condvar, "sme_wait");
 
@@ -509,4 +510,5 @@ sysmon_envsys_destroy(struct sysmon_envs
 	}
 	mutex_destroy(&sme->sme_mtx);
+	mutex_destroy(&sme->sme_work_mtx);
 	cv_destroy(&sme->sme_condvar);
 	kmem_free(sme, sizeof(*sme));
Index: sysmon_envsys_events.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon_envsys_events.c,v
retrieving revision 1.113
diff -p -u -2 -r1.113 sysmon_envsys_events.c
--- sysmon_envsys_events.c	23 Nov 2014 10:00:20 -0000	1.113
+++ sysmon_envsys_events.c	13 Mar 2015 17:21:50 -0000
@@ -732,9 +732,20 @@ sme_events_check(void *arg)
 	KASSERT(sme != NULL);
 
+	mutex_enter(&sme->sme_work_mtx);
+	if (sme->sme_busy > 0) {
+		printf("%s: workqueue busy: updates stopped\n", sme->sme_name);
+		mutex_exit(&sme->sme_work_mtx);
+		return;
+	}
+	mutex_exit(&sme->sme_work_mtx);
+
 	mutex_enter(&sme->sme_mtx);
+	mutex_enter(&sme->sme_work_mtx);
 	LIST_FOREACH(see, &sme->sme_events_list, see_list) {
 		workqueue_enqueue(sme->sme_wq, &see->see_wk, NULL);
 		see->see_edata->flags |= ENVSYS_FNEED_REFRESH;
+		sme->sme_busy++;
 	}
+	mutex_exit(&sme->sme_work_mtx);
 	if (!sysmon_low_power)
 		sme_schedule_callout(sme);
@@ -816,4 +827,8 @@ out:
 	see->see_flags &= ~SEE_EVENT_WORKING;
 	cv_broadcast(&sme->sme_condvar);
+	mutex_enter(&sme->sme_work_mtx);
+	KASSERT(sme->sme_busy > 0);
+	sme->sme_busy--;
+	mutex_exit(&sme->sme_work_mtx);
 	mutex_exit(&sme->sme_mtx);
 }
