svn commit: r223061 - head/sys/kern
Author: gibbs Date: Mon Jun 13 21:21:02 2011 New Revision: 223061 URL: http://svn.freebsd.org/changeset/base/223061 Log: 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. Modified: head/sys/kern/subr_devstat.c Modified: head/sys/kern/subr_devstat.c == --- head/sys/kern/subr_devstat.cMon Jun 13 21:03:27 2011 (r223060) +++ head/sys/kern/subr_devstat.cMon Jun 13 21:21:02 2011 (r223061) @@ -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); ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org
Re: svn commit: r223061 - head/sys/kern
On Mon, Jun 13, 2011 at 09:21:02PM +, Justin T. Gibbs wrote: Author: gibbs Date: Mon Jun 13 21:21:02 2011 New Revision: 223061 URL: http://svn.freebsd.org/changeset/base/223061 Log: 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. Devfs returns an error if MAKEDEV_CHECKNAME flag is supplied and attempt is made to create the existing node. The static guard is still useful, since make_dev() call is costly, but you can remove the atomic, since the race should be of limited scope. pgp7NTBL2jlKg.pgp Description: PGP signature
Re: svn commit: r223061 - head/sys/kern
On Tue, Jun 14, 2011 at 00:31:50 +0300, Kostik Belousov wrote: On Mon, Jun 13, 2011 at 09:21:02PM +, Justin T. Gibbs wrote: Author: gibbs Date: Mon Jun 13 21:21:02 2011 New Revision: 223061 URL: http://svn.freebsd.org/changeset/base/223061 Log: 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. Devfs returns an error if MAKEDEV_CHECKNAME flag is supplied and attempt is made to create the existing node. The static guard is still useful, since make_dev() call is costly, but you can remove the atomic, since the race should be of limited scope. Done, thanks for the suggestion! Ken -- Kenneth Merry k...@freebsd.org ___ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to svn-src-all-unsubscr...@freebsd.org