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@.
This commit is contained in:
parent
17576ebebe
commit
87318503e5
@ -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 @@ sysmon_envsys_sensor_detach(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
{
|
||||
envsys_data_t *oedata;
|
||||
bool found = false;
|
||||
bool destroy = false;
|
||||
|
||||
KASSERT(sme != NULL || edata != NULL);
|
||||
|
||||
@ -604,11 +605,18 @@ sysmon_envsys_sensor_detach(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
* 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;
|
||||
}
|
||||
|
||||
@ -917,10 +925,6 @@ sysmon_envsys_unregister(struct sysmon_envsys *sme)
|
||||
|
||||
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
|
||||
@ -935,6 +939,11 @@ sysmon_envsys_unregister(struct sysmon_envsys *sme)
|
||||
LIST_REMOVE(sme, sme_list);
|
||||
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.
|
||||
*/
|
||||
|
@ -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_unregister_all(struct sysmon_envsys *sme)
|
||||
{
|
||||
sme_event_t *see;
|
||||
int evcounter = 0;
|
||||
bool destroy = false;
|
||||
|
||||
KASSERT(sme != NULL);
|
||||
|
||||
@ -374,10 +375,15 @@ sme_event_unregister_all(struct sysmon_envsys *sme)
|
||||
}
|
||||
}
|
||||
|
||||
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_unregister(struct sysmon_envsys *sme, const char *sensor, int type)
|
||||
{
|
||||
sme_event_t *see;
|
||||
bool found = false;
|
||||
bool destroy = false;
|
||||
|
||||
KASSERT(sensor != NULL);
|
||||
|
||||
@ -420,7 +427,15 @@ sme_event_unregister(struct sysmon_envsys *sme, const char *sensor, int type)
|
||||
|
||||
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 @@ sme_remove_event(sme_event_t *see, struct sysmon_envsys *sme)
|
||||
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_schedule_callout(struct sysmon_envsys *sme)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_events_destroy(struct sysmon_envsys *sme)
|
||||
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));
|
||||
}
|
||||
|
@ -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_unregister_all(struct sysmon_envsys *);
|
||||
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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user