summaryrefslogtreecommitdiff
path: root/sys/dev/sysmon
diff options
context:
space:
mode:
authorxtraeme <xtraeme@NetBSD.org>2007-08-30 18:01:26 +0000
committerxtraeme <xtraeme@NetBSD.org>2007-08-30 18:01:26 +0000
commitcac66f76dd9fe8677c0a3514d585f32e692ef20f (patch)
treec02a5670912b4a8d5b0fc40d32e61822e265e5fa /sys/dev/sysmon
parent36188e72963e54c64994576766a54da151d7736b (diff)
Some changes to improve locking on sysmon_envsys(9):
- Remove sme_mtx, a global lock (sme_list_mtx) is used to access to the sysmon envsys device. - Allocate memory with KM_NOSLEEP rather than KM_SLEEP if there's a mutex held, to avoid sleeping. - Remove sysmon_envsys_createplist() and add the logic into sysmon_envsys_register(). - sysmon_envsys_register: allocate the array and dictionaries required in advance for a device before the locking and adding the objects into the array happens. - Rename sme_make_dictionary() to sme_add_sensor_dictionary() and pass to it the dictionary on which the objects will be stored for a sensor. - Improve locking here and there. Thanks to Mindaugas Rasiukevicius and Andrew Doran for comments.
Diffstat (limited to 'sys/dev/sysmon')
-rw-r--r--sys/dev/sysmon/sysmon_envsys.c338
-rw-r--r--sys/dev/sysmon/sysmon_envsys_events.c77
-rw-r--r--sys/dev/sysmon/sysmon_envsysvar.h8
3 files changed, 212 insertions, 211 deletions
diff --git a/sys/dev/sysmon/sysmon_envsys.c b/sys/dev/sysmon/sysmon_envsys.c
index 39e7326a756..3d0de16f4db 100644
--- a/sys/dev/sysmon/sysmon_envsys.c
+++ b/sys/dev/sysmon/sysmon_envsys.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsys.c,v 1.46 2007/08/05 23:16:25 xtraeme Exp $ */
+/* $NetBSD: sysmon_envsys.c,v 1.47 2007/08/30 18:01:26 xtraeme Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.46 2007/08/05 23:16:25 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.47 2007/08/30 18:01:26 xtraeme Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -152,12 +152,13 @@ struct sme_sensor_names {
char desc[ENVSYS_DESCLEN];
};
+
static SLIST_HEAD(, sme_sensor_names) sme_names_list;
static prop_dictionary_t sme_propd;
static kcondvar_t sme_list_cv;
static int sme_uniqsensors = 0;
-kmutex_t sme_mtx, sme_list_mtx, sme_event_mtx;
+kmutex_t sme_list_mtx, sme_event_mtx;
kcondvar_t sme_event_cv;
#ifdef COMPAT_40
@@ -178,7 +179,6 @@ sysmon_envsys_init(void)
{
LIST_INIT(&sysmon_envsys_list);
LIST_INIT(&sme_events_list);
- mutex_init(&sme_mtx, MUTEX_DRIVER, IPL_NONE);
mutex_init(&sme_list_mtx, MUTEX_DRIVER, IPL_NONE);
mutex_init(&sme_event_mtx, MUTEX_DRIVER, IPL_NONE);
mutex_init(&sme_event_init_mtx, MUTEX_DRIVER, IPL_NONE);
@@ -239,16 +239,13 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (sme == NULL)
continue;
- mutex_enter(&sme_mtx);
error = sme_update_dictionary(sme);
if (error) {
DPRINTF(("%s: sme_update_dictionary, "
"error=%d\n", __func__, error));
mutex_exit(&sme_list_mtx);
- mutex_exit(&sme_mtx);
return error;
}
- mutex_exit(&sme_mtx);
}
mutex_exit(&sme_list_mtx);
/*
@@ -336,7 +333,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (sme == NULL)
break;
- mutex_enter(&sme_mtx);
+ mutex_enter(&sme_list_mtx);
oidx = tred->sensor;
tred->sensor = SME_SENSOR_IDX(sme, tred->sensor);
@@ -352,7 +349,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (error) {
DPRINTF(("%s: sme_gtredata failed\n",
__func__));
- mutex_exit(&sme_mtx);
+ mutex_exit(&sme_list_mtx);
return error;
}
}
@@ -390,7 +387,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
tred->units, tred->sensor));
}
tred->sensor = oidx;
- mutex_exit(&sme_mtx);
+ mutex_exit(&sme_list_mtx);
break;
}
@@ -405,7 +402,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
if (sme == NULL)
break;
- mutex_enter(&sme_mtx);
+ mutex_enter(&sme_list_mtx);
oidx = binfo->sensor;
binfo->sensor = SME_SENSOR_IDX(sme, binfo->sensor);
@@ -425,7 +422,7 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
__func__, binfo->desc, binfo->sensor));
binfo->sensor = oidx;
- mutex_exit(&sme_mtx);
+ mutex_exit(&sme_list_mtx);
break;
}
@@ -447,25 +444,30 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
int
sysmon_envsys_register(struct sysmon_envsys *sme)
{
+ struct sme_dictionary {
+ SLIST_ENTRY(sme_dictionary) sme_dicts;
+ prop_dictionary_t dict;
+ size_t idx;
+ };
struct sysmon_envsys *lsme;
- int error = 0;
+ SLIST_HEAD(, sme_dictionary) sme_dict_list;
+ struct sme_dictionary *sd = NULL;
+ prop_array_t array;
+ envsys_data_t *edata = NULL;
+ int i, error = 0;
- /*
- * sanity check 1, make sure the driver has initialized
- * the sensors count or the value is not too high.
- */
- if (!sme->sme_nsensors || sme->sme_nsensors > ENVSYS_MAXSENSORS)
- return EINVAL;
+ KASSERT(sme != NULL);
+ KASSERT(sme->sme_name != NULL);
+ KASSERT(sme->sme_sensor_data != NULL);
- /*
- * sanity check 2, make sure that sme->sme_name and
- * sme->sme_data are not NULL.
+ /*
+ * sme_nsensors is mandatory...
*/
- if (sme->sme_name == NULL || sme->sme_sensor_data == NULL)
+ if (!sme->sme_nsensors)
return EINVAL;
-
+
/*
- * sanity check 3, if SME_DISABLE_GTREDATA is not set
+ * sanity check: if SME_DISABLE_GTREDATA is not set,
* the sme_gtredata function callback must be non NULL.
*/
if ((sme->sme_flags & SME_DISABLE_GTREDATA) == 0) {
@@ -473,35 +475,138 @@ sysmon_envsys_register(struct sysmon_envsys *sme)
return EINVAL;
}
+ /* create the sysmon envsys device array. */
+ array = prop_array_create();
+ if (array == NULL)
+ return ENOMEM;
+
/*
- * - check if requested sysmon_envsys device is valid
- * and does not exist already in the list.
- * - add device into the list.
- * - create the plist structure.
+ * Initialize the singly linked list to allocate N dictionaries.
+ */
+ SLIST_INIT(&sme_dict_list);
+ for (i = 0; i < sme->sme_nsensors; i++) {
+ sd = kmem_zalloc(sizeof(*sd), KM_SLEEP);
+ sd->dict = prop_dictionary_create();
+ if (sd->dict == NULL) {
+ kmem_free(sd, sizeof(*sd));
+ error = ENOMEM;
+ goto out2;
+ }
+ sd->idx = i;
+ SLIST_INSERT_HEAD(&sme_dict_list, sd, sme_dicts);
+ DPRINTF(("%s: creating dictionary [%d]\n", __func__, i));
+ }
+
+
+ /*
+ * Check if requested sysmon_envsys device is valid
+ * and does not exist already in the list.
*/
mutex_enter(&sme_list_mtx);
+ sme->sme_flags |= SME_FLAG_BUSY;
LIST_FOREACH(lsme, &sysmon_envsys_list, sme_list) {
if (strcmp(lsme->sme_name, sme->sme_name) == 0) {
error = EEXIST;
+ sme->sme_flags &= ~SME_FLAG_BUSY;
+ mutex_exit(&sme_list_mtx);
goto out;
}
}
-
- /* initialize the singly linked list for sensor descriptions */
+ /*
+ * Initialize the singly linked list for sensor descriptions.
+ */
SLIST_INIT(&sme_names_list);
+ /*
+ * Iterate over all sensors and create a dictionary per sensor,
+ * checking firstly if sensor description is unique.
+ */
+ for (i = 0; i < sme->sme_nsensors; i++) {
+ edata = &sme->sme_sensor_data[i];
+ /*
+ * Check if sensor description is unique.
+ */
+ if (sme_register_sensorname(edata))
+ continue;
+ /*
+ * XXX:
+ *
+ * workaround for LKMs. First sensor used in a LKM
+ * gets the index sensor from all edata structs
+ * allocated in kernel. It is unknown to me why this
+ * value is not 0 when using a LKM.
+ *
+ * For now overwrite its index to 0.
+ */
+ if (i == 0)
+ sme->sme_sensor_data[0].sensor = 0;
+
+ SLIST_FOREACH(sd, &sme_dict_list, sme_dicts) {
+ if (sd->idx != i)
+ continue;
+ /*
+ * Create all objects in sensor's dictionary.
+ */
+ sme_add_sensor_dictionary(sme, array, sd->dict, edata);
+ break;
+ }
+ }
+
+ /*
+ * If the array does not contain any object (sensor), there's
+ * no need to attach the driver.
+ */
+ if (prop_array_count(array) == 0) {
+ error = EINVAL;
+ DPRINTF(("%s: empty array for '%s'\n", __func__,
+ sme->sme_name));
+ goto out;
+ }
+
+ /*
+ * Add the array into the global dictionary for the driver.
+ *
+ * <dict>
+ * <key>foo0</key>
+ * <array>
+ * ...
+ */
+ if (!prop_dictionary_set(sme_propd, sme->sme_name, array)) {
+ DPRINTF(("%s: prop_dictionary_set for '%s'\n", __func__,
+ sme->sme_name));
+ error = EINVAL;
+ goto out;
+ }
+
+ /*
+ * Add the device into the list and initialize the counter
+ * for unique sensors.
+ */
#ifdef COMPAT_40
sme->sme_fsensor = sysmon_envsys_next_sensor_index;
sysmon_envsys_next_sensor_index += sme->sme_nsensors;
#endif
- error = sysmon_envsys_createplist(sme);
- if (!error) {
- LIST_INSERT_HEAD(&sysmon_envsys_list, sme, sme_list);
- sme_uniqsensors = 0;
- }
+ LIST_INSERT_HEAD(&sysmon_envsys_list, sme, sme_list);
+ sme_uniqsensors = 0;
out:
+ sme->sme_flags &= ~SME_FLAG_BUSY;
mutex_exit(&sme_list_mtx);
+ /*
+ * Remove all items from the singly linked list, we don't
+ * need them anymore.
+ */
+out2:
+ while ((sd = SLIST_FIRST(&sme_dict_list)) != NULL) {
+ SLIST_REMOVE_HEAD(&sme_dict_list, sme_dicts);
+ prop_object_release(sd->dict);
+ kmem_free(sd, sizeof(*sd));
+ }
+ if (error) {
+ DPRINTF(("%s: failed to register '%s' (%d)\n",
+ __func__, sme->sme_name, error));
+ prop_object_release(array);
+ }
return error;
}
@@ -524,26 +629,24 @@ sysmon_envsys_unregister(struct sysmon_envsys *sme)
sme->sme_flags |= SME_FLAG_WANTED;
cv_wait(&sme_list_cv, &sme_list_mtx);
}
- prop_dictionary_remove(sme_propd, sme->sme_name);
- /*
- * Unregister all events associated with this device.
- */
+ LIST_REMOVE(sme, sme_list);
mutex_exit(&sme_list_mtx);
- sme_event_unregister_all(sme);
- mutex_enter(&sme_list_mtx);
-
/*
- * Remove all elements from the sensor names singly linked list.
+ * Remove all sensor descriptions from the singly linked list.
*/
while (!SLIST_EMPTY(&sme_names_list)) {
snames = SLIST_FIRST(&sme_names_list);
SLIST_REMOVE_HEAD(&sme_names_list, sme_names);
- mutex_exit(&sme_list_mtx);
kmem_free(snames, sizeof(*snames));
- mutex_enter(&sme_list_mtx);
}
- LIST_REMOVE(sme, sme_list);
- mutex_exit(&sme_list_mtx);
+ /*
+ * Unregister all events associated with this device.
+ */
+ sme_event_unregister_all(sme);
+ /*
+ * Remove the device from the global dictionary.
+ */
+ prop_dictionary_remove(sme_propd, sme->sme_name);
}
/*
@@ -609,75 +712,6 @@ sysmon_envsys_find_40(u_int idx)
#endif
/*
- * sysmon_envsys_createplist:
- *
- * + Create the property list structure for a device.
- */
-int
-sysmon_envsys_createplist(struct sysmon_envsys *sme)
-{
- envsys_data_t *edata;
- prop_array_t array;
- int i, nsens, error;
-
- nsens = error = 0;
-
- KASSERT(mutex_owned(&sme_list_mtx));
- mutex_exit(&sme_list_mtx);
-
- /* create the sysmon envsys device array. */
- array = prop_array_create();
- if (array == NULL)
- return EINVAL;
-
- /*
- * Iterate over all sensors and create a dictionary with all
- * values specified by the sysmon envsys driver.
- */
- for (i = 0; i < sme->sme_nsensors; i++) {
- /*
- * XXX:
- *
- * workaround for LKMs. First sensor used in a LKM,
- * gets the index in sensor from all edata structures
- * allocated in kernel. It is unknown to me why this
- * value is not 0 when using a LKM.
- *
- * For now, overwrite its index to 0.
- */
- if (i == 0)
- sme->sme_sensor_data[0].sensor = 0;
-
- edata = &sme->sme_sensor_data[i];
- sme_make_dictionary(sme, array, edata);
- }
-
- if (prop_array_count(array) == 0) {
- error = EINVAL;
- prop_object_release(array);
- return error;
- }
-
- /*
- * <dict>
- * <key>foo0</key>
- * <array>
- * ...
- */
- mutex_enter(&sme_mtx);
- if (!prop_dictionary_set(sme_propd, sme->sme_name, array)) {
- DPRINTF(("%s: prop_dictionary_set\n", __func__));
- error = EINVAL;
- }
- mutex_exit(&sme_mtx);
-
-
- prop_object_release(array);
- mutex_enter(&sme_list_mtx);
- return error;
-}
-
-/*
* sme_register_sensorname:
*
* + Registers a sensor name into the list maintained per device.
@@ -689,9 +723,6 @@ sme_register_sensorname(envsys_data_t *edata)
KASSERT(edata != NULL);
- snames = kmem_zalloc(sizeof(*snames), KM_SLEEP);
-
- mutex_enter(&sme_list_mtx);
SLIST_FOREACH(snames2, &sme_names_list, sme_names) {
/*
* Match sensors with empty and duplicate description.
@@ -700,20 +731,21 @@ sme_register_sensorname(envsys_data_t *edata)
strcmp(snames2->desc, edata->desc) == 0)
if (snames2->assigned) {
edata->flags |= ENVSYS_FNOTVALID;
- mutex_exit(&sme_list_mtx);
DPRINTF(("%s: duplicate name "
"(%s)\n", __func__, edata->desc));
- kmem_free(snames, sizeof(*snames));
return EEXIST;
}
}
+ snames = kmem_zalloc(sizeof(*snames), KM_NOSLEEP);
+ if (snames == NULL)
+ return ENOMEM;
+
snames->assigned = true;
(void)strlcpy(snames->desc, edata->desc, sizeof(snames->desc));
DPRINTF(("%s: registering sensor name=%s\n", __func__, edata->desc));
SLIST_INSERT_HEAD(&sme_names_list, snames, sme_names);
sme_uniqsensors++;
- mutex_exit(&sme_list_mtx);
return 0;
}
@@ -724,30 +756,17 @@ sme_register_sensorname(envsys_data_t *edata)
* + Create sensor's dictionary in device's array.
*/
void
-sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
- envsys_data_t *edata)
+sme_add_sensor_dictionary(struct sysmon_envsys *sme, prop_array_t array,
+ prop_dictionary_t dict, envsys_data_t *edata)
{
const struct sme_sensor_type *est = sme_sensor_type;
const struct sme_sensor_state *ess = sme_sensor_state;
const struct sme_sensor_state *esds = sme_sensor_drive_state;
sme_event_drv_t *sme_evdrv_t = NULL;
- prop_dictionary_t dict;
int i, j;
i = j = 0;
-
- /*
- * <array>
- * <dict>
- * ...
- */
- dict = prop_dictionary_create();
- if (dict == NULL) {
- DPRINTF(("%s: couldn't allocate a dictionary\n", __func__));
- goto invalidate_sensor;
- }
-
/* find the correct unit for this sensor. */
for (i = 0; est[i].type != -1; i++)
if (est[i].type == edata->units)
@@ -776,12 +795,6 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
goto invalidate_sensor;
}
- /*
- * Check if description was already assigned in other sensor.
- */
- if (sme_register_sensorname(edata))
- goto out;
-
if (sme_sensor_upstring(dict, "description", edata->desc))
goto invalidate_sensor;
@@ -819,7 +832,7 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
*/
if (edata->flags & ENVSYS_FPERCENT)
if (sme_sensor_upbool(dict, "want-percentage", true))
- goto out;
+ return;
/*
* Add the monitoring boolean object:
@@ -837,10 +850,10 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
(edata->units == ENVSYS_INDICATOR) ||
(edata->units == ENVSYS_DRIVE)) {
if (sme_sensor_upbool(dict, "monitoring-supported", false))
- goto out;
+ return;
} else {
if (sme_sensor_upbool(dict, "monitoring-supported", true))
- goto out;
+ return;
}
/*
@@ -857,7 +870,7 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
break;
if (sme_sensor_upstring(dict, "drive-state", esds[j].desc))
- goto out;
+ return;
}
/* if sensor is enabled, add the following properties... */
@@ -880,56 +893,60 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
*/
if (edata->units == ENVSYS_SFANRPM)
if (sme_sensor_upuint32(dict, "rpms", edata->rpms))
- goto out;
+ return;
if (edata->units == ENVSYS_SVOLTS_AC ||
edata->units == ENVSYS_SVOLTS_DC)
if (sme_sensor_upint32(dict, "rfact", edata->rfact))
- goto out;
+ return;
if (sme_sensor_upint32(dict, "cur-value", edata->value_cur))
- goto out;
+ return;
if (edata->flags & ENVSYS_FVALID_MIN) {
if (sme_sensor_upint32(dict,
"min-value",
edata->value_min))
- goto out;
+ return;
}
if (edata->flags & ENVSYS_FVALID_MAX) {
if (sme_sensor_upint32(dict,
"max-value",
edata->value_max))
- goto out;
+ return;
}
if (edata->flags & ENVSYS_FVALID_AVG) {
if (sme_sensor_upint32(dict,
"avg-value",
edata->value_avg))
- goto out;
+ return;
}
}
/*
* ...
* </array>
+ *
+ * Add the dictionary into the array.
+ *
*/
- mutex_enter(&sme_mtx);
if (!prop_array_set(array, sme_uniqsensors - 1, dict)) {
- mutex_exit(&sme_mtx);
DPRINTF(("%s: prop_array_add\n", __func__));
goto invalidate_sensor;
}
- mutex_exit(&sme_mtx);
/*
* Add a new event if a monitoring flag was set.
*/
if (edata->monitor) {
- sme_evdrv_t = kmem_zalloc(sizeof(*sme_evdrv_t), KM_SLEEP);
+ sme_evdrv_t = kmem_zalloc(sizeof(*sme_evdrv_t), KM_NOSLEEP);
+ if (sme_evdrv_t == NULL) {
+ DPRINTF(("%s: edata->monitor failed\n", __func__));
+ return;
+ }
sme_evdrv_t->sdict = dict;
sme_evdrv_t->edata = edata;
@@ -940,15 +957,10 @@ sme_make_dictionary(struct sysmon_envsys *sme, prop_array_t array,
sysmon_task_queue_sched(0, sme_event_drvadd, sme_evdrv_t);
}
-out:
- prop_object_release(dict);
return;
invalidate_sensor:
- mutex_enter(&sme_mtx);
edata->flags |= ENVSYS_FNOTVALID;
- mutex_exit(&sme_mtx);
- prop_object_release(dict);
}
/*
diff --git a/sys/dev/sysmon/sysmon_envsys_events.c b/sys/dev/sysmon/sysmon_envsys_events.c
index 95e564603d8..d9a8748eee0 100644
--- a/sys/dev/sysmon/sysmon_envsys_events.c
+++ b/sys/dev/sysmon/sysmon_envsys_events.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsys_events.c,v 1.19 2007/07/23 17:51:17 xtraeme Exp $ */
+/* $NetBSD: sysmon_envsys_events.c,v 1.20 2007/08/30 18:01:26 xtraeme Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.19 2007/07/23 17:51:17 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys_events.c,v 1.20 2007/08/30 18:01:26 xtraeme Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -95,7 +95,7 @@ static const struct sme_sensor_event sme_sensor_event[] = {
static struct workqueue *seewq;
static struct callout seeco;
static bool sme_events_initialized = false;
-kmutex_t sme_mtx, sme_list_mtx, sme_event_mtx, sme_event_init_mtx;
+kmutex_t sme_list_mtx, sme_event_mtx, sme_event_init_mtx;
kcondvar_t sme_event_cv;
/* 10 seconds of timeout for the callout */
@@ -242,15 +242,16 @@ sme_event_unregister_all(struct sysmon_envsys *sme)
cv_wait(&sme_event_cv, &sme_event_mtx);
LIST_REMOVE(see, see_list);
- mutex_exit(&sme_event_mtx);
kmem_free(see, sizeof(*see));
- mutex_enter(&sme_event_mtx);
evcounter--;
}
}
- if (LIST_EMPTY(&sme_events_list))
+ if (LIST_EMPTY(&sme_events_list)) {
+ mutex_exit(&sme_event_mtx);
sme_events_destroy();
+ return;
+ }
mutex_exit(&sme_event_mtx);
}
@@ -289,20 +290,21 @@ sme_event_unregister(const char *sensor, int type)
DPRINTF(("%s: removing dev=%s sensor=%s type=%d\n",
__func__, see->pes.pes_dvname, sensor, type));
LIST_REMOVE(see, see_list);
- mutex_exit(&sme_event_mtx);
- kmem_free(see, sizeof(*see));
-
/*
* So the events list is empty, we'll do the following:
*
* - stop and destroy the callout.
* - destroy the workqueue.
*/
- mutex_enter(&sme_event_mtx);
- if (LIST_EMPTY(&sme_events_list))
+ if (LIST_EMPTY(&sme_events_list)) {
+ mutex_exit(&sme_event_mtx);
sme_events_destroy();
+ goto out;
+ }
mutex_exit(&sme_event_mtx);
+out:
+ kmem_free(see, sizeof(*see));
return 0;
}
@@ -337,12 +339,12 @@ do { \
"error=%d sensor=%s event=%s\n", \
__func__, error, sed_t->edata->desc, (c)); \
else { \
- mutex_enter(&sme_mtx); \
+ mutex_enter(&sme_list_mtx); \
(void)strlcat(str, (c), sizeof(str)); \
prop_dictionary_set_bool(sed_t->sdict, \
str, \
true); \
- mutex_exit(&sme_mtx); \
+ mutex_exit(&sme_list_mtx); \
} \
} \
} while (/* CONSTCOND */ 0)
@@ -406,43 +408,39 @@ sme_event_add(prop_dictionary_t sdict, envsys_data_t *edata,
if (crittype == see->type)
break;
}
-
if (see->critval != critval) {
see->critval = critval;
DPRINTF(("%s: sensor=%s type=%d "
"(critval updated)\n", __func__,
edata->desc, see->type));
}
-
- mutex_exit(&sme_event_mtx);
goto out;
}
}
- if (LIST_EMPTY(&sme_events_list)) {
- mutex_exit(&sme_event_mtx);
+ if (LIST_EMPTY(&sme_events_list))
goto register_event;
- }
/* check if the event is already on the list */
LIST_FOREACH(see, &sme_events_list, see_list) {
if (strcmp(edata->desc, see->pes.pes_sensname) == 0)
if (crittype == see->type) {
mutex_exit(&sme_event_mtx);
- error = EEXIST;
- goto out;
+ return EEXIST;
}
}
- mutex_exit(&sme_event_mtx);
/*
* object is not in dictionary, create a new
* sme event and assign required members.
*/
register_event:
- see = kmem_zalloc(sizeof(*see), KM_SLEEP);
+ see = kmem_zalloc(sizeof(*see), KM_NOSLEEP);
+ if (see == NULL) {
+ mutex_exit(&sme_event_mtx);
+ return ENOMEM;
+ }
- mutex_enter(&sme_event_mtx);
see->critval = critval;
see->type = crittype;
(void)strlcpy(see->pes.pes_dvname, drvn,
@@ -451,20 +449,19 @@ register_event:
(void)strlcpy(see->pes.pes_sensname, edata->desc,
sizeof(see->pes.pes_sensname));
see->snum = edata->sensor;
- mutex_exit(&sme_event_mtx);
-
- error = sme_event_register(see);
- if (error)
- kmem_free(see, sizeof(*see));
-
out:
/* update the object in the dictionary */
if (objkey && critval) {
- mutex_enter(&sme_event_mtx);
error = sme_sensor_upint32(sdict, objkey, critval);
- mutex_exit(&sme_event_mtx);
+ if (error) {
+ mutex_exit(&sme_event_mtx);
+ return error;
+ }
}
-
+ mutex_exit(&sme_event_mtx);
+ error = sme_event_register(see);
+ if (error)
+ kmem_free(see, sizeof(*see));
return error;
}
@@ -479,7 +476,7 @@ sme_events_init(void)
int error;
error = workqueue_create(&seewq, "envsysev",
- sme_events_worker, NULL, 0, IPL_SOFTCLOCK, 0);
+ sme_events_worker, NULL, 0, IPL_SOFTCLOCK, WQ_MPSAFE);
if (error)
goto out;
@@ -505,11 +502,11 @@ sme_events_destroy(void)
{
mutex_enter(&sme_event_init_mtx);
callout_stop(&seeco);
- callout_destroy(&seeco);
- workqueue_destroy(seewq);
sme_events_initialized = false;
DPRINTF(("%s: events framework destroyed\n", __func__));
mutex_exit(&sme_event_init_mtx);
+ callout_destroy(&seeco);
+ workqueue_destroy(seewq);
}
/*
@@ -567,7 +564,6 @@ sme_events_worker(struct work *wk, void *arg)
KASSERT(sme != NULL);
- mutex_enter(&sme_mtx);
/* get the sensor with the index specified in see->snum */
edata = &sme->sme_sensor_data[see->snum];
@@ -577,13 +573,9 @@ sme_events_worker(struct work *wk, void *arg)
*/
if ((sme->sme_flags & SME_DISABLE_GTREDATA) == 0) {
error = (*sme->sme_gtredata)(sme, edata);
- if (error) {
- mutex_exit(&sme_mtx);
- mutex_exit(&sme_event_mtx);
+ if (error)
return;
- }
}
- mutex_exit(&sme_mtx);
DPRINTFOBJ(("%s: desc=%s sensor=%d units=%d value_cur=%d\n",
__func__, edata->desc, edata->sensor,
@@ -674,7 +666,6 @@ do { \
break;
}
-
see->see_flags &= ~SME_EVENT_WORKING;
cv_broadcast(&sme_event_cv);
mutex_exit(&sme_event_mtx);
diff --git a/sys/dev/sysmon/sysmon_envsysvar.h b/sys/dev/sysmon/sysmon_envsysvar.h
index d50b7815790..dc0496559e9 100644
--- a/sys/dev/sysmon/sysmon_envsysvar.h
+++ b/sys/dev/sysmon/sysmon_envsysvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_envsysvar.h,v 1.12 2007/07/23 17:51:17 xtraeme Exp $ */
+/* $NetBSD: sysmon_envsysvar.h,v 1.13 2007/08/30 18:01:26 xtraeme Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -92,7 +92,6 @@ typedef struct sme_event_drv {
} sme_event_drv_t;
/* common */
-extern kmutex_t sme_mtx; /* mutex to protect the sysmon envsys data */
extern kmutex_t sme_list_mtx; /* mutex to protect the sysmon envsys list */
extern kmutex_t sme_event_mtx; /* mutex to protect the sme event data */
@@ -109,9 +108,8 @@ LIST_HEAD(, sysmon_envsys) sysmon_envsys_list;
LIST_HEAD(, sme_event) sme_events_list;
/* functions to handle sysmon envsys devices */
-int sysmon_envsys_createplist(struct sysmon_envsys *);
-void sme_make_dictionary(struct sysmon_envsys *, prop_array_t,
- envsys_data_t *);
+void sme_add_sensor_dictionary(struct sysmon_envsys *, prop_array_t,
+ prop_dictionary_t, envsys_data_t *);
int sme_update_dictionary(struct sysmon_envsys *);
int sme_userset_dictionary(struct sysmon_envsys *,
prop_dictionary_t, prop_array_t);