mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-23 11:18:54 +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_current_devnumber;
|
||||
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 void devstat_free(struct devstat *);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
ds = devstat_alloc();
|
||||
@ -475,10 +470,9 @@ devstat_alloc(void)
|
||||
static int once;
|
||||
|
||||
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,
|
||||
UID_ROOT, GID_WHEEL, 0400, DEVSTAT_DEVICE_NAME);
|
||||
once = 1;
|
||||
}
|
||||
spp2 = NULL;
|
||||
mtx_lock(&devstat_mutex);
|
||||
|
Loading…
Reference in New Issue
Block a user