mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +00:00
Fix a couple of race conditions in devstat(9) initialization.
In devstat_new_entry(), there is no need to initialize the queue and the mutex in this function. There are ways to do static initialization on both, so use STAILQ_HEAD_INITIALIZER and MTX_SYSINIT to initialize the queue and the mutex. In devstat_alloc(), use an atomic test and set routine to guard making our entry in /dev. Using just a plain static variable creates a race condition on multiprocessor machines. If you attempt to create a second entry in devfs, the kernel will panic. Submitted by: kdm Reviewed by: gibbs Sponsored by: Spectra Logic Corporation MFC after: 1 week.
This commit is contained in:
parent
454a02b372
commit
27c959cf05
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=223061
@ -49,8 +49,9 @@ static long devstat_generation = 1;
|
|||||||
static int devstat_version = DEVSTAT_VERSION;
|
static int devstat_version = DEVSTAT_VERSION;
|
||||||
static int devstat_current_devnumber;
|
static int devstat_current_devnumber;
|
||||||
static struct mtx devstat_mutex;
|
static struct mtx devstat_mutex;
|
||||||
|
MTX_SYSINIT(devstat_mutex, &devstat_mutex, "devstat", MTX_DEF);
|
||||||
|
|
||||||
static struct devstatlist device_statq;
|
static struct devstatlist device_statq = STAILQ_HEAD_INITIALIZER(device_statq);
|
||||||
static struct devstat *devstat_alloc(void);
|
static struct devstat *devstat_alloc(void);
|
||||||
static void devstat_free(struct devstat *);
|
static void devstat_free(struct devstat *);
|
||||||
static void devstat_add_entry(struct devstat *ds, const void *dev_name,
|
static void devstat_add_entry(struct devstat *ds, const void *dev_name,
|
||||||
@ -70,13 +71,7 @@ devstat_new_entry(const void *dev_name,
|
|||||||
devstat_priority priority)
|
devstat_priority priority)
|
||||||
{
|
{
|
||||||
struct devstat *ds;
|
struct devstat *ds;
|
||||||
static int once;
|
|
||||||
|
|
||||||
if (!once) {
|
|
||||||
STAILQ_INIT(&device_statq);
|
|
||||||
mtx_init(&devstat_mutex, "devstat", NULL, MTX_DEF);
|
|
||||||
once = 1;
|
|
||||||
}
|
|
||||||
mtx_assert(&devstat_mutex, MA_NOTOWNED);
|
mtx_assert(&devstat_mutex, MA_NOTOWNED);
|
||||||
|
|
||||||
ds = devstat_alloc();
|
ds = devstat_alloc();
|
||||||
@ -475,10 +470,9 @@ devstat_alloc(void)
|
|||||||
static int once;
|
static int once;
|
||||||
|
|
||||||
mtx_assert(&devstat_mutex, MA_NOTOWNED);
|
mtx_assert(&devstat_mutex, MA_NOTOWNED);
|
||||||
if (!once) {
|
if (!once && atomic_cmpset_int(&once, 0, 1)) {
|
||||||
make_dev_credf(MAKEDEV_ETERNAL, &devstat_cdevsw, 0, NULL,
|
make_dev_credf(MAKEDEV_ETERNAL, &devstat_cdevsw, 0, NULL,
|
||||||
UID_ROOT, GID_WHEEL, 0400, DEVSTAT_DEVICE_NAME);
|
UID_ROOT, GID_WHEEL, 0400, DEVSTAT_DEVICE_NAME);
|
||||||
once = 1;
|
|
||||||
}
|
}
|
||||||
spp2 = NULL;
|
spp2 = NULL;
|
||||||
mtx_lock(&devstat_mutex);
|
mtx_lock(&devstat_mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user