diff options
| author | xtraeme <xtraeme@NetBSD.org> | 2007-08-30 18:01:26 +0000 |
|---|---|---|
| committer | xtraeme <xtraeme@NetBSD.org> | 2007-08-30 18:01:26 +0000 |
| commit | cac66f76dd9fe8677c0a3514d585f32e692ef20f (patch) | |
| tree | c02a5670912b4a8d5b0fc40d32e61822e265e5fa /sys/dev/sysmon | |
| parent | 36188e72963e54c64994576766a54da151d7736b (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.c | 338 | ||||
| -rw-r--r-- | sys/dev/sysmon/sysmon_envsys_events.c | 77 | ||||
| -rw-r--r-- | sys/dev/sysmon/sysmon_envsysvar.h | 8 |
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); |
