login
Login
/
Register
Search
Search this site:
Forums
News
Blogs
Features
Site
Home
»
Mailing list archives
»
linux-kernel
»
2008
»
May
»
15
Re: [BUG] mm: bdi: export BDI attributes in sysfs
view
thread
Previous message: [
thread
] [
date
] [
author
]
Next message: [
thread
] [
date
] [
author
]
[view in full thread]
From: Arthur Jones
Subject:
Re: [BUG] mm: bdi: export BDI attributes in sysfs
Date: Thursday, May 15, 2008 - 3:05 pm
Hi Greg, ... On Thu, May 15, 2008 at 02:02:54PM -0700, Greg KH wrote:
quoted text
> On Thu, May 15, 2008 at 12:54:57PM -0700, Linus Torvalds wrote: > > > > > > On Thu, 15 May 2008, Miklos Szeredi wrote: > > > > > > Actually nothing should need protection. The only problem AFAICS is > > > that the device_create()/dev_set_drvdata() interface is racy: somebody > > > can come in after the device has been created but before drvdata has > > > been set, and then we are in trouble. > > > > Well, I'm not sure that the locking should be at that level. Maybe the > > locking *should* be in the driver that does this. It may need to do other > > setup too, after all. > > > > Of course, doing a device_create_drvdata() thing might be the right > > solution, at least part of the time. Greg? > > Here's a patch that is build tested only. > > Can someone who can reproduce this let me know if it solves the problem?
Yes, this patch survives many power cycles without hitting the BUG... Thanks for looking into this... Arthur
quoted text
> -------------------- > > Subject: Driver core: add device_create_vargs and device_create_drvdata > > We want to have the drvdata field set properly when creating the device > as sysfs callbacks can assume it is present and it can race the later > setting of this field. > > So, create two new functions, deviec_create_vargs() and > device_create_drvdata() that take this new field. > > Also move the mm/backing-dev.c code to use it as it is showing this > problem today. > > device_create_drvdata() will go away in 2.6.27 as the drvdata field will > just be moved to the device_create() call as it should be. > > Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> > > --- > drivers/base/core.c | 85 +++++++++++++++++++++++++++++++++++++++++++++---- > include/linux/device.h | 12 ++++++ > mm/backing-dev.c | 12 +----- > 3 files changed, 93 insertions(+), 16 deletions(-) > > --- a/drivers/base/core.c > +++ b/drivers/base/core.c > @@ -1163,11 +1163,13 @@ static void device_create_release(struct > } > > /** > - * device_create - creates a device and registers it with sysfs > + * device_create_vargs - creates a device and registers it with sysfs > * @class: pointer to the struct class that this device should be registered to > * @parent: pointer to the parent struct device of this new device, if any > * @devt: the dev_t for the char device to be added > + * @drvdata: the data to be added to the device for callbacks > * @fmt: string for the device's name > + * @args: va_list for the device's name > * > * This function can be used by char device classes. A struct device > * will be created in sysfs, registered to the specified class. > @@ -1183,10 +1185,10 @@ static void device_create_release(struct > * Note: the struct class passed to this function must have previously > * been created with a call to class_create(). > */ > -struct device *device_create(struct class *class, struct device *parent, > - dev_t devt, const char *fmt, ...) > +struct device *device_create_vargs(struct class *class, struct device *parent, > + dev_t devt, void *drvdata, const char *fmt, > + va_list args) > { > - va_list args; > struct device *dev = NULL; > int retval = -ENODEV; > > @@ -1203,10 +1205,9 @@ struct device *device_create(struct clas > dev->class = class; > dev->parent = parent; > dev->release = device_create_release; > + dev_set_drvdata(dev, drvdata); > > - va_start(args, fmt); > vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); > - va_end(args); > retval = device_register(dev); > if (retval) > goto error; > @@ -1217,6 +1218,78 @@ error: > kfree(dev); > return ERR_PTR(retval); > } > +EXPORT_SYMBOL_GPL(device_create_vargs); > + > +/** > + * device_create_drvdata - creates a device and registers it with sysfs > + * @class: pointer to the struct class that this device should be registered to > + * @parent: pointer to the parent struct device of this new device, if any > + * @devt: the dev_t for the char device to be added > + * @drvdata: the data to be added to the device for callbacks > + * @fmt: string for the device's name > + * > + * This function can be used by char device classes. A struct device > + * will be created in sysfs, registered to the specified class. > + * > + * A "dev" file will be created, showing the dev_t for the device, if > + * the dev_t is not 0,0. > + * If a pointer to a parent struct device is passed in, the newly created > + * struct device will be a child of that device in sysfs. > + * The pointer to the struct device will be returned from the call. > + * Any further sysfs files that might be required can be created using this > + * pointer. > + * > + * Note: the struct class passed to this function must have previously > + * been created with a call to class_create(). > + */ > +struct device *device_create_drvdata(struct class *class, > + struct device *parent, > + dev_t devt, > + void *drvdata, > + const char *fmt, ...) > +{ > + va_list vargs; > + struct device *dev; > + > + va_start(vargs, fmt); > + dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); > + va_end(vargs); > + return dev; > +} > +EXPORT_SYMBOL_GPL(device_create_drvdata); > + > +/** > + * device_create - creates a device and registers it with sysfs > + * @class: pointer to the struct class that this device should be registered to > + * @parent: pointer to the parent struct device of this new device, if any > + * @devt: the dev_t for the char device to be added > + * @fmt: string for the device's name > + * > + * This function can be used by char device classes. A struct device > + * will be created in sysfs, registered to the specified class. > + * > + * A "dev" file will be created, showing the dev_t for the device, if > + * the dev_t is not 0,0. > + * If a pointer to a parent struct device is passed in, the newly created > + * struct device will be a child of that device in sysfs. > + * The pointer to the struct device will be returned from the call. > + * Any further sysfs files that might be required can be created using this > + * pointer. > + * > + * Note: the struct class passed to this function must have previously > + * been created with a call to class_create(). > + */ > +struct device *device_create(struct class *class, struct device *parent, > + dev_t devt, const char *fmt, ...) > +{ > + va_list vargs; > + struct device *dev; > + > + va_start(vargs, fmt); > + dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs); > + va_end(vargs); > + return dev; > +} > EXPORT_SYMBOL_GPL(device_create); > > static int __match_devt(struct device *dev, void *data) > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -456,9 +456,21 @@ extern int __must_check device_reprobe(s > /* > * Easy functions for dynamically creating devices on the fly > */ > +extern struct device *device_create_vargs(struct class *cls, > + struct device *parent, > + dev_t devt, > + void *drvdata, > + const char *fmt, > + va_list vargs); > extern struct device *device_create(struct class *cls, struct device *parent, > dev_t devt, const char *fmt, ...) > __attribute__((format(printf, 4, 5))); > +extern struct device *device_create_drvdata(struct class *cls, > + struct device *parent, > + dev_t devt, > + void *drvdata, > + const char *fmt, ...) > + __attribute__((format(printf, 5, 6))); > extern void device_destroy(struct class *cls, dev_t devt); > > /* > --- a/mm/backing-dev.c > +++ b/mm/backing-dev.c > @@ -172,30 +172,22 @@ postcore_initcall(bdi_class_init); > int bdi_register(struct backing_dev_info *bdi, struct device *parent, > const char *fmt, ...) > { > - char *name; > va_list args; > int ret = 0; > struct device *dev; > > va_start(args, fmt); > - name = kvasprintf(GFP_KERNEL, fmt, args); > + dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args); > va_end(args); > - > - if (!name) > - return -ENOMEM; > - > - dev = device_create(bdi_class, parent, MKDEV(0, 0), name); > if (IS_ERR(dev)) { > ret = PTR_ERR(dev); > goto exit; > } > > bdi->dev = dev; > - dev_set_drvdata(bdi->dev, bdi); > - bdi_debug_register(bdi, name); > + bdi_debug_register(bdi, dev_name(dev)); > > exit: > - kfree(name); > return ret; > } > EXPORT_SYMBOL(bdi_register);
--
unsubscribe notice
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to
majordomo@vger.kernel.org
More majordomo info at
http://vger.kernel.org/majordomo-info.html
Please read the FAQ at
http://www.tux.org/lkml/
Previous message: [
thread
] [
date
] [
author
]
Next message: [
thread
] [
date
] [
author
]
Messages in current thread:
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Arthur Jones
, (Wed May 14, 7:40 am)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Miklos Szeredi
, (Thu May 15, 11:53 am)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Linus Torvalds
, (Thu May 15, 12:18 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Miklos Szeredi
, (Thu May 15, 12:27 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Linus Torvalds
, (Thu May 15, 12:54 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 1:37 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 1:40 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 1:40 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Arthur Jones
, (Thu May 15, 1:44 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 2:02 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Arthur Jones
, (Thu May 15, 3:05 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 4:20 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs
, Greg KH
, (Thu May 15, 9:59 pm)
Navigation
Mailing list archives
Recent posts
Popular discussions
linux-kernel
:
Ken Chen
[patch] sched: fix inconsistency when redistribute per-cpu tg->cfs_rq shares.
Hugh Dickins
Re: Linux 2.6.26-rc1 - pgtable_32.c:178 pmd_bad
Bernhard Beck
[PATCH 001/001] usb-serial: Add ThinkOptics WavIT
Oleg Nesterov
Re: [PATCH 4/5] don't panic if /sbin/init exits or killed
Greg KH
[patch 07/21] rtc-pcf8563: detect polarity of century bit automatically
git
:
Jonathan del Strother
Re: [PATCH] Fixing path quoting issues
Gerrit Pape
[PATCH] fix skipping merge-order test with NO_OPENSSL=1.
Linus Torvalds
Re: Implementing branch attributes in git config
Johannes Schindelin
Re: Trying to use git-filter-branch to compress history by removing large, obsolet...
Gerrit Pape
[PATCH] hooks--update: fix test for properly set up project description file
linux-netdev
:
David Miller
Re: [PATCH 04/15] tg3: Preserve LAA when device control is released
Jean-Louis Dupond
Re: tg3 driver not advertising 1000mbit
Sven Wegener
[PATCH] ipvs: Add missing locking during connection table hashing and unhashing
David Miller
Re: [PATCH] qlcnic: dont assume NET_IP_ALIGN is 2
Stephen Hemminger
[PATCH 2/2] sky2: fix transmit state on resume
git-commits-head
:
Linux Kernel Mailing List
[SCSI] scsi ioctl: fix kernel-doc warning
Linux Kernel Mailing List
ALSA: HDA - Correct trivial typos in comments.
Linux Kernel Mailing List
i2c-viapro: Add support for SMBus Process Call transactions
Linux Kernel Mailing List
i2c: Documentation: upgrading clients HOWTO
Linux Kernel Mailing List
[PATCH] fix sysctl_nr_open bugs
openbsd-misc
:
Die Gestalt
Re: How to re-build openssl with SHA1 support?
Edwin Eyan Moragas
Re: managing routes for multiple PPPoE connections
Brian Candler
Re: OBSD's perspective on SELinux
Jonathan Schleifer
Why is getaddrinfo breaking POSIX?
Predrag Punosevac
Re: Kernel developers guide/tutorial
Colocation donated by:
Syndicate