|
25 | 25 | #include <linux/mutex.h> |
26 | 26 | #include <linux/pm_runtime.h> |
27 | 27 | #include <linux/netdevice.h> |
| 28 | +#include <linux/rcupdate.h> |
28 | 29 | #include <linux/sched/signal.h> |
29 | 30 | #include <linux/sched/mm.h> |
30 | 31 | #include <linux/string_helpers.h> |
@@ -2640,6 +2641,7 @@ static const char *dev_uevent_name(const struct kobject *kobj) |
2640 | 2641 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
2641 | 2642 | { |
2642 | 2643 | const struct device *dev = kobj_to_dev(kobj); |
| 2644 | + struct device_driver *driver; |
2643 | 2645 | int retval = 0; |
2644 | 2646 |
|
2645 | 2647 | /* add device node properties if present */ |
@@ -2668,8 +2670,12 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
2668 | 2670 | if (dev->type && dev->type->name) |
2669 | 2671 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
2670 | 2672 |
|
2671 | | - if (dev->driver) |
2672 | | - add_uevent_var(env, "DRIVER=%s", dev->driver->name); |
| 2673 | + /* Synchronize with module_remove_driver() */ |
| 2674 | + rcu_read_lock(); |
| 2675 | + driver = READ_ONCE(dev->driver); |
| 2676 | + if (driver) |
| 2677 | + add_uevent_var(env, "DRIVER=%s", driver->name); |
| 2678 | + rcu_read_unlock(); |
2673 | 2679 |
|
2674 | 2680 | /* Add common DT information about the device */ |
2675 | 2681 | of_device_uevent(dev, env); |
@@ -2739,11 +2745,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, |
2739 | 2745 | if (!env) |
2740 | 2746 | return -ENOMEM; |
2741 | 2747 |
|
2742 | | - /* Synchronize with really_probe() */ |
2743 | | - device_lock(dev); |
2744 | 2748 | /* let the kset specific function add its keys */ |
2745 | 2749 | retval = kset->uevent_ops->uevent(&dev->kobj, env); |
2746 | | - device_unlock(dev); |
2747 | 2750 | if (retval) |
2748 | 2751 | goto out; |
2749 | 2752 |
|
|
0 commit comments