Driver core: implement uevent suppress in kobject
authorMing Lei <tom.leiming@gmail.com>
Sun, 1 Mar 2009 13:10:49 +0000 (21:10 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Mar 2009 23:38:26 +0000 (16:38 -0700)
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 <tom.leiming@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/acpi/dock.c
drivers/base/core.c
drivers/base/firmware_class.c
drivers/i2c/i2c-core.c
drivers/s390/cio/chsc_sch.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
fs/partitions/check.c
include/linux/device.h
include/linux/kobject.h
lib/kobject_uevent.c

index 35094f230b1e339d2d969ca27cb89816c7d3d9de..7af7db1ba8c452c05ef730ab432cabb8c7b59309 100644 (file)
@@ -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;
index a90f56f64d6f65dce40f8f0cdbfbbbc378b15b45..95c67ffd71da12484f90b137815908b93b3f6b4b 100644 (file)
@@ -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)
index 44699d9dd85c8de9c81d5aa1bc7807d69b370103..d3a59c688fe4fcaf0f7ebf514f44f59a08e90693 100644 (file)
@@ -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__);
@@ -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;
 
index e7d984866de0465f5846225c6b59a0072fec7fd1..fbb9030b68a5465bca036e1d441f2ef0fd97e090 100644 (file)
@@ -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;
 
index 0a2f2edafc03ea17bd54dcb7ef758002c021146c..93eca1731b81a56bb7d934a8c5e62119e8178eb9 100644 (file)
@@ -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);
                }
        }
index 8019288bc6dee0a730f79b6a4ed86228a3a052f3..427d11d88069c24cc4f2c77170aa36f6f6d95733 100644 (file)
@@ -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);
@@ -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;
index 23d5752349b59d0f85b3274c206eea556123e10e..611d2e001dd5f784a10e6b5bcd45224ce812c53f 100644 (file)
@@ -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);
@@ -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);
index 6d720243f5f4a29a43a7b50dd005bbff32a7b0aa..38e337d51ced527842a1b86c8193f7983be260b0 100644 (file)
@@ -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;
@@ -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)
@@ -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;
@@ -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;
@@ -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 */
index 4bea53fe8f4c0602d2db4efd15f247c2a8b3af3c..914c1016dd8f45941c07c763a34444ccc23afde2 100644 (file)
@@ -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;
 
@@ -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;
index c9c214d7bba2540fa0e83fb635396287c79a7310..58ae8e00fcddd067b9815b8831c5c92986187584 100644 (file)
@@ -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, ...)
index 318328ddbd1cf57b89cc84dc63b2818b480231d9..b2181cc8e4d8b6e84dfa6b4fa6c3d5991be0055c 100644 (file)
@@ -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)) {