Skip to content

Commit

Permalink
Merge tag 'driver-core-4.21-rc1' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/gregkh/driver-core

Pull driver core updates from Greg KH:
 "Here is the "big" set of driver core patches for 4.21-rc1.

  It's not really big, just a number of small changes for some reported
  issues, some documentation updates to hopefully make it harder for
  people to abuse the driver model, and some other minor cleanups.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'driver-core-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  mm, memory_hotplug: update a comment in unregister_memory()
  component: convert to DEFINE_SHOW_ATTRIBUTE
  sysfs: Disable lockdep for driver bind/unbind files
  driver core: Add missing dev->bus->need_parent_lock checks
  kobject: return error code if writing /sys/.../uevent fails
  driver core: Move async_synchronize_full call
  driver core: platform: Respect return code of platform_device_register_full()
  kref/kobject: Improve documentation
  drivers/base/memory.c: Use DEVICE_ATTR_RO and friends
  driver core: Replace simple_strto{l,ul} by kstrtou{l,ul}
  kernfs: Improve kernfs_notify() poll notification latency
  kobject: Fix warnings in lib/kobject_uevent.c
  kobject: drop unnecessary cast "%llu" for u64
  driver core: fix comments for device_block_probing()
  driver core: Replace simple_strtol by kstrtoint
  • Loading branch information
torvalds committed Dec 29, 2018
2 parents 0206118 + 16df145 commit b07039b
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 104 deletions.
10 changes: 7 additions & 3 deletions Documentation/kobject.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,14 @@ such a method has a form like::
One important point cannot be overstated: every kobject must have a
release() method, and the kobject must persist (in a consistent state)
until that method is called. If these constraints are not met, the code is
flawed. Note that the kernel will warn you if you forget to provide a
flawed. Note that the kernel will warn you if you forget to provide a
release() method. Do not try to get rid of this warning by providing an
"empty" release function; you will be mocked mercilessly by the kobject
maintainer if you attempt this.
"empty" release function.

If all your cleanup function needs to do is call kfree(), then you must
create a wrapper function which uses container_of() to upcast to the correct
type (as shown in the example above) and then calls kfree() on the overall
structure.

Note, the name of the kobject is available in the release function, but it
must NOT be changed within this callback. Otherwise there will be a memory
Expand Down
19 changes: 13 additions & 6 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ static struct kset *system_kset;

#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)

#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
struct driver_attribute driver_attr_##_name = \
__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)

static int __must_check bus_rescan_devices_helper(struct device *dev,
void *data);
Expand Down Expand Up @@ -195,7 +198,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf,
bus_put(bus);
return err;
}
static DRIVER_ATTR_WO(unbind);
static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store);

/*
* Manually attach a device to a driver.
Expand Down Expand Up @@ -231,7 +234,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
bus_put(bus);
return err;
}
static DRIVER_ATTR_WO(bind);
static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store);

static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
{
Expand Down Expand Up @@ -611,8 +614,10 @@ static void remove_probe_files(struct bus_type *bus)
static ssize_t uevent_store(struct device_driver *drv, const char *buf,
size_t count)
{
kobject_synth_uevent(&drv->p->kobj, buf, count);
return count;
int rc;

rc = kobject_synth_uevent(&drv->p->kobj, buf, count);
return rc ? rc : count;
}
static DRIVER_ATTR_WO(uevent);

Expand Down Expand Up @@ -828,8 +833,10 @@ static void klist_devices_put(struct klist_node *n)
static ssize_t bus_uevent_store(struct bus_type *bus,
const char *buf, size_t count)
{
kobject_synth_uevent(&bus->p->subsys.kobj, buf, count);
return count;
int rc;

rc = kobject_synth_uevent(&bus->p->subsys.kobj, buf, count);
return rc ? rc : count;
}
static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);

Expand Down
12 changes: 1 addition & 11 deletions drivers/base/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,7 @@ static int component_devices_show(struct seq_file *s, void *data)
return 0;
}

static int component_devices_open(struct inode *inode, struct file *file)
{
return single_open(file, component_devices_show, inode->i_private);
}

static const struct file_operations component_devices_fops = {
.open = component_devices_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_SHOW_ATTRIBUTE(component_devices);

static int __init component_debug_init(void)
{
Expand Down
32 changes: 22 additions & 10 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,10 +815,12 @@ ssize_t device_store_ulong(struct device *dev,
const char *buf, size_t size)
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
char *end;
unsigned long new = simple_strtoul(buf, &end, 0);
if (end == buf)
return -EINVAL;
int ret;
unsigned long new;

ret = kstrtoul(buf, 0, &new);
if (ret)
return ret;
*(unsigned long *)(ea->var) = new;
/* Always return full write size even if we didn't consume all */
return size;
Expand All @@ -839,9 +841,14 @@ ssize_t device_store_int(struct device *dev,
const char *buf, size_t size)
{
struct dev_ext_attribute *ea = to_ext_attr(attr);
char *end;
long new = simple_strtol(buf, &end, 0);
if (end == buf || new > INT_MAX || new < INT_MIN)
int ret;
long new;

ret = kstrtol(buf, 0, &new);
if (ret)
return ret;

if (new > INT_MAX || new < INT_MIN)
return -EINVAL;
*(int *)(ea->var) = new;
/* Always return full write size even if we didn't consume all */
Expand Down Expand Up @@ -911,8 +918,7 @@ static void device_release(struct kobject *kobj)
else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev);
else
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
WARN(1, KERN_ERR "Device '%s' does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
dev_name(dev));
kfree(p);
}
Expand Down Expand Up @@ -1088,8 +1094,14 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
if (kobject_synth_uevent(&dev->kobj, buf, count))
int rc;

rc = kobject_synth_uevent(&dev->kobj, buf, count);

if (rc) {
dev_err(dev, "uevent: failed to send synthetic uevent\n");
return rc;
}

return count;
}
Expand Down
19 changes: 11 additions & 8 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static void driver_deferred_probe_trigger(void)
}

/**
* device_block_probing() - Block/defere device's probes
* device_block_probing() - Block/defer device's probes
*
* It will disable probing of devices and defer their probes instead.
*/
Expand Down Expand Up @@ -223,7 +223,10 @@ DEFINE_SHOW_ATTRIBUTE(deferred_devs);
static int deferred_probe_timeout = -1;
static int __init deferred_probe_timeout_setup(char *str)
{
deferred_probe_timeout = simple_strtol(str, NULL, 10);
int timeout;

if (!kstrtoint(str, 10, &timeout))
deferred_probe_timeout = timeout;
return 1;
}
__setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
Expand Down Expand Up @@ -453,7 +456,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
if (defer_all_probes) {
/*
* Value of defer_all_probes can be set only by
* device_defer_all_probes_enable() which, in turn, will call
* device_block_probing() which, in turn, will call
* wait_for_device_probe() right after that to avoid any races.
*/
dev_dbg(dev, "Driver %s force probe deferral\n", drv->name);
Expand Down Expand Up @@ -928,16 +931,13 @@ static void __device_release_driver(struct device *dev, struct device *parent)

drv = dev->driver;
if (drv) {
if (driver_allows_async_probing(drv))
async_synchronize_full();

while (device_links_busy(dev)) {
device_unlock(dev);
if (parent)
if (parent && dev->bus->need_parent_lock)
device_unlock(parent);

device_links_unbind_consumers(dev);
if (parent)
if (parent && dev->bus->need_parent_lock)
device_lock(parent);

device_lock(dev);
Expand Down Expand Up @@ -1036,6 +1036,9 @@ void driver_detach(struct device_driver *drv)
struct device_private *dev_prv;
struct device *dev;

if (driver_allows_async_probing(drv))
async_synchronize_full();

for (;;) {
spin_lock(&drv->p->klist_devices.k_lock);
if (list_empty(&drv->p->klist_devices.k_list)) {
Expand Down
Loading

0 comments on commit b07039b

Please sign in to comment.