Skip to content

Commit

Permalink
Driver core: implement uevent suppress in kobject
Browse files Browse the repository at this point in the history
This patch implements uevent suppress in kobject and removes it
from struct device, based on the following ideas:

1,Uevent sending should be one attribute of kobject, so suppressing it
in kobject layer is more natural than in device layer. By this way,
we can do it for other objects embedded with kobject.

2,It may save several bytes for each instance of struct device.(On my
omap3(32bit ARM) based box, can save 8bytes per device object)

This patch also introduces dev_set|get_uevent_suppress() helpers to
set and query uevent_suppress attribute in case to help kobject
as private part of struct device in future.

[This version is against the latest driver-core patch set of Greg,please
ignore the last version.]

Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
ming1 authored and gregkh committed Mar 24, 2009
1 parent 4995f8e commit f67f129
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 18 deletions.
2 changes: 1 addition & 1 deletion drivers/acpi/dock.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle)
sizeof(struct dock_station *));

/* we want the dock device to send uevents */
dock_device->dev.uevent_suppress = 0;
dev_set_uevent_suppress(&dock_device->dev, 0);

if (is_dock(handle))
dock_station->flags |= DOCK_IS_DOCK;
Expand Down
2 changes: 0 additions & 2 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)

if (ktype == &device_ktype) {
struct device *dev = to_dev(kobj);
if (dev->uevent_suppress)
return 0;
if (dev->bus)
return 1;
if (dev->class)
Expand Down
4 changes: 2 additions & 2 deletions drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->parent = device;
f_dev->class = &firmware_class;
dev_set_drvdata(f_dev, fw_priv);
f_dev->uevent_suppress = 1;
dev_set_uevent_suppress(f_dev, 1);
retval = device_register(f_dev);
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
Expand Down Expand Up @@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
}

if (uevent)
f_dev->uevent_suppress = 0;
dev_set_uevent_suppress(f_dev, 0);
*dev_p = f_dev;
goto out;

Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/i2c-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,7 @@ int i2c_attach_client(struct i2c_client *client)

if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
client->dev.uevent_suppress = 1;
dev_set_uevent_suppress(&client->dev, 1);
} else
client->dev.release = i2c_client_dev_release;

Expand Down
4 changes: 2 additions & 2 deletions drivers/s390/cio/chsc_sch.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct subchannel *sch)
kfree(private);
} else {
sch->private = private;
if (sch->dev.uevent_suppress) {
sch->dev.uevent_suppress = 0;
if (dev_get_uevent_suppress(&sch->dev)) {
dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/s390/cio/css.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ static int css_register_subchannel(struct subchannel *sch)
* the subchannel driver can decide itself when it wants to inform
* userspace of its existence.
*/
sch->dev.uevent_suppress = 1;
dev_set_uevent_suppress(&sch->dev, 1);
css_update_ssd_info(sch);
/* make it known to the system */
ret = css_sch_device_register(sch);
Expand All @@ -287,7 +287,7 @@ static int css_register_subchannel(struct subchannel *sch)
* a fitting driver module may be loaded based on the
* modalias.
*/
sch->dev.uevent_suppress = 0;
dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
return ret;
Expand Down
4 changes: 2 additions & 2 deletions drivers/s390/cio/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ io_subchannel_register(struct work_struct *work)
* Now we know this subchannel will stay, we can throw
* our delayed uevent.
*/
sch->dev.uevent_suppress = 0;
dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
/* make it known to the system */
ret = ccw_device_register(cdev);
Expand Down Expand Up @@ -1243,7 +1243,7 @@ static int io_subchannel_probe(struct subchannel *sch)
* the ccw_device and exit. This happens for all early
* devices, e.g. the console.
*/
sch->dev.uevent_suppress = 0;
dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
cdev->dev.groups = ccwdev_attr_groups;
device_initialize(&cdev->dev);
Expand Down
10 changes: 5 additions & 5 deletions fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
pdev->devt = devt;

/* delay uevent until 'holders' subdir is created */
pdev->uevent_suppress = 1;
dev_set_uevent_suppress(pdev, 1);
err = device_add(pdev);
if (err)
goto out_put;
Expand All @@ -410,7 +410,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
if (!p->holder_dir)
goto out_del;

pdev->uevent_suppress = 0;
dev_set_uevent_suppress(pdev, 0);
if (flags & ADDPART_FLAG_WHOLEDISK) {
err = device_create_file(pdev, &dev_attr_whole_disk);
if (err)
Expand All @@ -422,7 +422,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
rcu_assign_pointer(ptbl->part[partno], p);

/* suppress uevent if the disk supresses it */
if (!ddev->uevent_suppress)
if (!dev_get_uevent_suppress(pdev))
kobject_uevent(&pdev->kobj, KOBJ_ADD);

return p;
Expand Down Expand Up @@ -455,7 +455,7 @@ void register_disk(struct gendisk *disk)
dev_set_name(ddev, disk->disk_name);

/* delay uevents, until we scanned partition table */
ddev->uevent_suppress = 1;
dev_set_uevent_suppress(ddev, 1);

if (device_add(ddev))
return;
Expand Down Expand Up @@ -490,7 +490,7 @@ void register_disk(struct gendisk *disk)

exit:
/* announce disk after possible partitions are created */
ddev->uevent_suppress = 0;
dev_set_uevent_suppress(ddev, 0);
kobject_uevent(&ddev->kobj, KOBJ_ADD);

/* announce possible partitions */
Expand Down
11 changes: 10 additions & 1 deletion include/linux/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ struct device {
struct device_private *p;

struct kobject kobj;
unsigned uevent_suppress:1;
const char *init_name; /* initial name of the device */
struct device_type *type;

Expand Down Expand Up @@ -465,6 +464,16 @@ static inline void dev_set_drvdata(struct device *dev, void *data)
dev->driver_data = data;
}

static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
{
return dev->kobj.uevent_suppress;
}

static inline void dev_set_uevent_suppress(struct device *dev, int val)
{
dev->kobj.uevent_suppress = val;
}

static inline int device_is_registered(struct device *dev)
{
return dev->kobj.state_in_sysfs;
Expand Down
1 change: 1 addition & 0 deletions include/linux/kobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct kobject {
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};

extern int kobject_set_name(struct kobject *kobj, const char *name, ...)
Expand Down
7 changes: 7 additions & 0 deletions lib/kobject_uevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
kset = top_kobj->kset;
uevent_ops = kset->uevent_ops;

/* skip the event, if uevent_suppress is set*/
if (kobj->uevent_suppress) {
pr_debug("kobject: '%s' (%p): %s: uevent_suppress "
"caused the event to drop!\n",
kobject_name(kobj), kobj, __func__);
return 0;
}
/* skip the event, if the filter returns zero. */
if (uevent_ops && uevent_ops->filter)
if (!uevent_ops->filter(kset, kobj)) {
Expand Down

0 comments on commit f67f129

Please sign in to comment.