Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sysmon As proposed in



details:   https://anonhg.NetBSD.org/src/rev/1d057490c779
branches:  trunk
changeset: 341046:1d057490c779
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Oct 15 13:35:30 2015 +0000

description:
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.

diffstat:

 sys/dev/sysmon/sysmon_envsys_events.c |  17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diffs (45 lines):

diff -r 3c2278c80884 -r 1d057490c779 sys/dev/sysmon/sysmon_envsys_events.c
--- a/sys/dev/sysmon/sysmon_envsys_events.c     Thu Oct 15 12:00:02 2015 +0000
+++ b/sys/dev/sysmon/sysmon_envsys_events.c     Thu Oct 15 13:35:30 2015 +0000
@@ -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 @@
                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);
 }
 



Home | Main Index | Thread Index | Old Index