Module Name:    src
Committed By:   bouyer
Date:           Thu Oct 15 13:35:30 UTC 2015

Modified Files:
        src/sys/dev/sysmon: sysmon_envsys_events.c

Log Message:
As proposed in
https://mail-index.netbsd.org/tech-kern/2015/10/14/msg019511.html
don't sleep on sme->sme_mtx in the callout but use mutex_tryenter()
and just reschedule the callout if we can't get the mutex now.
This fixes a deadlock which can happen if the backed wants to
sleep with timeout (e.g. cv_timedwait()) as the backed is called with
sme->sme_mtx held.

This is a stopgap measure for netbsd-7; sysmon should be changed to not
sleep (or call a backend which will sleep) with mutexes held.


To generate a diff of this commit:
cvs rdiff -u -r1.117 -r1.118 src/sys/dev/sysmon/sysmon_envsys_events.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/sysmon/sysmon_envsys_events.c
diff -u src/sys/dev/sysmon/sysmon_envsys_events.c:1.117 src/sys/dev/sysmon/sysmon_envsys_events.c:1.118
--- src/sys/dev/sysmon/sysmon_envsys_events.c:1.117	Tue Jun 23 19:22:56 2015
+++ src/sys/dev/sysmon/sysmon_envsys_events.c	Thu Oct 15 13:35:30 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsys_events.c,v 1.117 2015/06/23 19:22:56 pgoyette Exp $ */
+/* $NetBSD: sysmon_envsys_events.c,v 1.118 2015/10/15 13:35:30 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2007, 2008 Juan Romero Pardines.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.117 2015/06/23 19:22:56 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.118 2015/10/15 13:35:30 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -739,18 +739,21 @@ sme_events_check(void *arg)
 		mutex_exit(&sme->sme_work_mtx);
 		return;
 	}
-	mutex_exit(&sme->sme_work_mtx);
-
-	mutex_enter(&sme->sme_mtx);
-	mutex_enter(&sme->sme_work_mtx);
+	if (!mutex_tryenter(&sme->sme_mtx)) {
+		/* can't get lock - try again later */
+		if (!sysmon_low_power)
+			sme_schedule_callout(sme);
+		mutex_exit(&sme->sme_work_mtx);
+		return;
+	}
 	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);
+	mutex_exit(&sme->sme_work_mtx);
 	mutex_exit(&sme->sme_mtx);
 }
 

Reply via email to