Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/sysmon Pull workqueue_destroy out of sme->sme_mtx



details:   https://anonhg.NetBSD.org/src/rev/fb2c98f883c1
branches:  trunk
changeset: 804090:fb2c98f883c1
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Sun Nov 23 10:00:20 2014 +0000

description:
Pull workqueue_destroy out of sme->sme_mtx

workqueue_destroy may sleep so we shouldn't run it with holding a mutex.

Requested by riastradh@.

diffstat:

 sys/dev/sysmon/sysmon_envsys.c        |  21 +++++++++---
 sys/dev/sysmon/sysmon_envsys_events.c |  57 +++++++++++++++++++++++-----------
 sys/dev/sysmon/sysmon_envsysvar.h     |   3 +-
 3 files changed, 55 insertions(+), 26 deletions(-)

diffs (212 lines):

diff -r 2da49711f9ac -r fb2c98f883c1 sys/dev/sysmon/sysmon_envsys.c
--- a/sys/dev/sysmon/sysmon_envsys.c    Sun Nov 23 09:05:23 2014 +0000
+++ b/sys/dev/sysmon/sysmon_envsys.c    Sun Nov 23 10:00:20 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sysmon_envsys.c,v 1.127 2014/08/10 16:44:36 tls Exp $  */
+/*     $NetBSD: sysmon_envsys.c,v 1.128 2014/11/23 10:00:20 ozaki-r Exp $      */
 
 /*-
  * Copyright (c) 2007, 2008 Juan Romero Pardines.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.127 2014/08/10 16:44:36 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.128 2014/11/23 10:00:20 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -579,6 +579,7 @@
 {
        envsys_data_t *oedata;
        bool found = false;
+       bool destroy = false;
 
        KASSERT(sme != NULL || edata != NULL);
 
@@ -604,11 +605,18 @@
         * remove it, unhook from rnd(4), and decrement the sensors count.
         */
        sme_event_unregister_sensor(sme, edata);
+       if (LIST_EMPTY(&sme->sme_events_list)) {
+               sme_events_halt_callout(sme);
+               destroy = true;
+       }
        TAILQ_REMOVE(&sme->sme_sensors_list, edata, sensors_head);
        sme->sme_nsensors--;
        sysmon_envsys_release(sme, true);
        mutex_exit(&sme->sme_mtx);
 
+       if (destroy)
+               sme_events_destroy(sme);
+
        return 0;
 }
 
@@ -918,10 +926,6 @@
        KASSERT(sme != NULL);
 
        /*
-        * Unregister all events associated with device.
-        */
-       sme_event_unregister_all(sme);
-       /*
         * Decrement global sensors counter and the first_sensor index
         * for remaining devices in the list (only used for compatibility
         * with previous API), and remove the device from the list.
@@ -936,6 +940,11 @@
        mutex_exit(&sme_global_mtx);
 
        /*
+        * Unregister all events associated with device.
+        */
+       sme_event_unregister_all(sme);
+
+       /*
         * Remove the device (and all its objects) from the global dictionary.
         */
        array = prop_dictionary_get(sme_propd, sme->sme_name);
diff -r 2da49711f9ac -r fb2c98f883c1 sys/dev/sysmon/sysmon_envsys_events.c
--- a/sys/dev/sysmon/sysmon_envsys_events.c     Sun Nov 23 09:05:23 2014 +0000
+++ b/sys/dev/sysmon/sysmon_envsys_events.c     Sun Nov 23 10:00:20 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsys_events.c,v 1.112 2014/11/22 15:09:30 ozaki-r Exp $ */
+/* $NetBSD: sysmon_envsys_events.c,v 1.113 2014/11/23 10:00:20 ozaki-r 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.112 2014/11/22 15:09:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.113 2014/11/23 10:00:20 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -345,6 +345,7 @@
 {
        sme_event_t *see;
        int evcounter = 0;
+       bool destroy = false;
 
        KASSERT(sme != NULL);
 
@@ -374,10 +375,15 @@
                }
        }
 
-       if (LIST_EMPTY(&sme->sme_events_list))
-               if (sme->sme_flags & SME_CALLOUT_INITIALIZED)
-                       sme_events_destroy(sme);
+       if (LIST_EMPTY(&sme->sme_events_list) &&
+           sme->sme_flags & SME_CALLOUT_INITIALIZED) {
+               sme_events_halt_callout(sme);
+               destroy = true;
+       }
        mutex_exit(&sme->sme_mtx);
+
+       if (destroy)
+               sme_events_destroy(sme);
 }
 
 /*
@@ -390,6 +396,7 @@
 {
        sme_event_t *see;
        bool found = false;
+       bool destroy = false;
 
        KASSERT(sensor != NULL);
 
@@ -420,7 +427,15 @@
 
        sme_remove_event(see, sme);
 
+       if (LIST_EMPTY(&sme->sme_events_list)) {
+               sme_events_halt_callout(sme);
+               destroy = true;
+       }
        mutex_exit(&sme->sme_mtx);
+
+       if (destroy)
+               sme_events_destroy(sme);
+
        return 0;
 }
 
@@ -470,15 +485,6 @@
        if (see->see_edata->flags & ENVSYS_FHAS_ENTROPY)
                rnd_detach_source(&see->see_edata->rnd_src);
        LIST_REMOVE(see, see_list);
-       /*
-        * So the events list is empty, we'll do the following:
-        *
-        *      - stop and destroy the callout.
-        *      - destroy the workqueue.
-        */
-       if (LIST_EMPTY(&sme->sme_events_list))
-               sme_events_destroy(sme);
-
        kmem_free(see, sizeof(*see));
 }
 
@@ -601,13 +607,12 @@
 }
 
 /*
- * sme_events_destroy:
+ * sme_events_halt_callout:
  *
- *     + Destroys the event framework for this device: callout
- *       stopped, workqueue destroyed and callout mutex destroyed.
+ *     + Halt the callout of the event framework for this device.
  */
 void
-sme_events_destroy(struct sysmon_envsys *sme)
+sme_events_halt_callout(struct sysmon_envsys *sme)
 {
        KASSERT(mutex_owned(&sme->sme_mtx));
 
@@ -618,9 +623,23 @@
        sme->sme_flags &= ~SME_CALLOUT_INITIALIZED;
 
        callout_halt(&sme->sme_callout, &sme->sme_mtx);
-       callout_destroy(&sme->sme_callout);
+}
 
+/*
+ * sme_events_destroy:
+ *
+ *     + Destroy the callout and the workqueue of the event framework
+ *       for this device.
+ */
+void
+sme_events_destroy(struct sysmon_envsys *sme)
+{
+       KASSERT(!mutex_owned(&sme->sme_mtx));
+       KASSERT((sme->sme_flags & SME_CALLOUT_INITIALIZED) == 0);
+
+       callout_destroy(&sme->sme_callout);
        workqueue_destroy(sme->sme_wq);
+
        DPRINTF(("%s: events framework destroyed for '%s'\n",
            __func__, sme->sme_name));
 }
diff -r 2da49711f9ac -r fb2c98f883c1 sys/dev/sysmon/sysmon_envsysvar.h
--- a/sys/dev/sysmon/sysmon_envsysvar.h Sun Nov 23 09:05:23 2014 +0000
+++ b/sys/dev/sysmon/sysmon_envsysvar.h Sun Nov 23 10:00:20 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsysvar.h,v 1.46 2012/12/14 03:31:10 pgoyette Exp $ */
+/* $NetBSD: sysmon_envsysvar.h,v 1.47 2014/11/23 10:00:20 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 2007, 2008 Juan Romero Pardines.
@@ -137,6 +137,7 @@
 void   sme_event_drvadd(void *);
 int    sme_events_init(struct sysmon_envsys *);
 void   sme_events_destroy(struct sysmon_envsys *);
+void   sme_events_halt_callout(struct sysmon_envsys *);
 void   sme_events_check(void *);
 void   sme_events_worker(struct work *, void *);
 void   sme_deliver_event(sme_event_t *);



Home | Main Index | Thread Index | Old Index