The device close routine is called when _last_ descriptor to the
device file is closed, rather on every descriptor close. Instead of getting the exclusive lock on open and releasing on close, get the lock only when needed in sysmonioctl_envsys(). Fixes kern/14368 by Anthony Mallet. Okayed by Jason Thorpe. While here, also inline sysmon_envsys_init() to sysmonopen_envsys(), and g/c sysmonioctl_wdog() prototype.
This commit is contained in:
parent
f854b2521f
commit
57b53bc9a8
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon_envsys.c,v 1.2 2001/11/13 06:28:55 lukem Exp $ */
|
||||
/* $NetBSD: sysmon_envsys.c,v 1.3 2002/01/03 22:35:53 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.2 2001/11/13 06:28:55 lukem Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.3 2002/01/03 22:35:53 jdolecek Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -69,27 +69,17 @@ u_int sysmon_envsys_next_sensor_index;
|
||||
int sysmon_envsys_initialized;
|
||||
struct simplelock sysmon_envsys_initialized_slock = SIMPLELOCK_INITIALIZER;
|
||||
|
||||
void sysmon_envsys_init(void);
|
||||
#define SYSMON_ENVSYS_LOCK() \
|
||||
lockmgr(&sysmon_envsys_lock, LK_EXCLUSIVE, NULL)
|
||||
|
||||
#define SYSMON_ENVSYS_UNLOCK() \
|
||||
lockmgr(&sysmon_envsys_lock, LK_RELEASE, NULL)
|
||||
|
||||
int sysmonioctl_envsys(dev_t, u_long, caddr_t, int, struct proc *);
|
||||
int sysmonioctl_wdog(dev_t, u_long, caddr_t, int, struct proc *);
|
||||
|
||||
struct sysmon_envsys *sysmon_envsys_find(u_int);
|
||||
void sysmon_envsys_release(struct sysmon_envsys *);
|
||||
|
||||
/*
|
||||
* sysmon_envsys_init:
|
||||
*
|
||||
* Initialize the system monitor.
|
||||
*/
|
||||
void
|
||||
sysmon_envsys_init(void)
|
||||
{
|
||||
|
||||
lockinit(&sysmon_envsys_lock, PWAIT|PCATCH, "smenv", 0, 0);
|
||||
sysmon_envsys_initialized = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sysmonopen_envsys:
|
||||
*
|
||||
@ -98,18 +88,14 @@ sysmon_envsys_init(void)
|
||||
int
|
||||
sysmonopen_envsys(dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
simple_lock(&sysmon_envsys_initialized_slock);
|
||||
if (sysmon_envsys_initialized == 0)
|
||||
sysmon_envsys_init();
|
||||
if (sysmon_envsys_initialized == 0) {
|
||||
lockinit(&sysmon_envsys_lock, PWAIT|PCATCH, "smenv", 0, 0);
|
||||
sysmon_envsys_initialized = 1;
|
||||
}
|
||||
simple_unlock(&sysmon_envsys_initialized_slock);
|
||||
|
||||
error = lockmgr(&sysmon_envsys_lock,
|
||||
LK_EXCLUSIVE | LK_INTERLOCK |
|
||||
((flag & O_NONBLOCK) ? LK_NOWAIT : 0),
|
||||
&sysmon_envsys_initialized_slock);
|
||||
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -121,7 +107,7 @@ int
|
||||
sysmonclose_envsys(dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
|
||||
(void) lockmgr(&sysmon_envsys_lock, LK_RELEASE, NULL);
|
||||
/* Nothing to do */
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -181,8 +167,11 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, caddr_t data, int flag,
|
||||
break;
|
||||
oidx = tred->sensor;
|
||||
tred->sensor = SME_SENSOR_IDX(sme, tred->sensor);
|
||||
if (tred->sensor < sme->sme_nsensors)
|
||||
if (tred->sensor < sme->sme_nsensors) {
|
||||
SYSMON_ENVSYS_LOCK();
|
||||
error = (*sme->sme_gtredata)(sme, tred);
|
||||
SYSMON_ENVSYS_UNLOCK();
|
||||
}
|
||||
tred->sensor = oidx;
|
||||
sysmon_envsys_release(sme);
|
||||
break;
|
||||
@ -199,9 +188,11 @@ sysmonioctl_envsys(dev_t dev, u_long cmd, caddr_t data, int flag,
|
||||
}
|
||||
oidx = binfo->sensor;
|
||||
binfo->sensor = SME_SENSOR_IDX(sme, binfo->sensor);
|
||||
if (binfo->sensor < sme->sme_nsensors)
|
||||
if (binfo->sensor < sme->sme_nsensors) {
|
||||
SYSMON_ENVSYS_LOCK();
|
||||
error = (*sme->sme_streinfo)(sme, binfo);
|
||||
else
|
||||
SYSMON_ENVSYS_UNLOCK();
|
||||
} else
|
||||
binfo->validflags = 0;
|
||||
binfo->sensor = oidx;
|
||||
sysmon_envsys_release(sme);
|
||||
|
Loading…
Reference in New Issue
Block a user