diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:07:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 18:07:37 -0400 |
commit | 8d7804a2f03dbd34940fcb426450c730adf29dae (patch) | |
tree | 749f33776e38f734b81c2a93275b6bf76e96f74e | |
parent | d87823813fe498fdd47894bd28e460a9dee8d771 (diff) | |
parent | 0e6c861f73ec42ab5c89fda9892f2173c7aaf6cf (diff) |
Merge tag 'driver-core-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH:
"Here is the driver core / firmware changes for 4.2-rc1.
A number of small changes all over the place in the driver core, and
in the firmware subsystem. Nothing really major, full details in the
shortlog. Some of it is a bit of churn, given that the platform
driver probing changes was found to not work well, so they were
reverted.
All of these have been in linux-next for a while with no reported
issues"
* tag 'driver-core-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (31 commits)
Revert "base/platform: Only insert MEM and IO resources"
Revert "base/platform: Continue on insert_resource() error"
Revert "of/platform: Use platform_device interface"
Revert "base/platform: Remove code duplication"
firmware: add missing kfree for work on async call
fs: sysfs: don't pass count == 0 to bin file readers
base:dd - Fix for typo in comment to function driver_deferred_probe_trigger().
base/platform: Remove code duplication
of/platform: Use platform_device interface
base/platform: Continue on insert_resource() error
base/platform: Only insert MEM and IO resources
firmware: use const for remaining firmware names
firmware: fix possible use after free on name on asynchronous request
firmware: check for file truncation on direct firmware loading
firmware: fix __getname() missing failure check
drivers: of/base: move of_init to driver_init
drivers/base: cacheinfo: fix annoying typo when DT nodes are absent
sysfs: disambiguate between "error code" and "failure" in comments
driver-core: fix build for !CONFIG_MODULES
driver-core: make __device_attach() static
...
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 2 | ||||
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | arch/powerpc/mm/hugetlbpage.c | 4 | ||||
-rw-r--r-- | drivers/base/base.h | 1 | ||||
-rw-r--r-- | drivers/base/bus.c | 31 | ||||
-rw-r--r-- | drivers/base/cacheinfo.c | 4 | ||||
-rw-r--r-- | drivers/base/cpu.c | 29 | ||||
-rw-r--r-- | drivers/base/dd.c | 163 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 63 | ||||
-rw-r--r-- | drivers/base/platform.c | 13 | ||||
-rw-r--r-- | drivers/edac/amd64_edac.c | 1 | ||||
-rw-r--r-- | fs/kernfs/file.c | 1 | ||||
-rw-r--r-- | fs/sysfs/file.c | 2 | ||||
-rw-r--r-- | fs/sysfs/group.c | 6 | ||||
-rw-r--r-- | include/linux/cacheinfo.h | 2 | ||||
-rw-r--r-- | include/linux/device.h | 31 | ||||
-rw-r--r-- | include/linux/module.h | 13 | ||||
-rw-r--r-- | include/linux/moduleparam.h | 12 | ||||
-rw-r--r-- | init/main.c | 25 | ||||
-rw-r--r-- | kernel/module.c | 18 | ||||
-rw-r--r-- | kernel/params.c | 11 | ||||
-rw-r--r-- | lib/dynamic_debug.c | 4 |
23 files changed, 367 insertions, 79 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index da95513571ea..b683e8ee69ec 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
@@ -243,7 +243,7 @@ Description: Parameters for the CPU cache attributes | |||
243 | coherency_line_size: the minimum amount of data in bytes that gets | 243 | coherency_line_size: the minimum amount of data in bytes that gets |
244 | transferred from memory to cache | 244 | transferred from memory to cache |
245 | 245 | ||
246 | level: the cache hierarcy in the multi-level cache configuration | 246 | level: the cache hierarchy in the multi-level cache configuration |
247 | 247 | ||
248 | number_of_sets: total number of sets in the cache, a set is a | 248 | number_of_sets: total number of sets in the cache, a set is a |
249 | collection of cache lines with the same cache index | 249 | collection of cache lines with the same cache index |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c84d078a6376..1e18efe3a4ed 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -953,6 +953,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
953 | auto selects the default scheme, which automatically | 953 | auto selects the default scheme, which automatically |
954 | enables eagerfpu restore for xsaveopt. | 954 | enables eagerfpu restore for xsaveopt. |
955 | 955 | ||
956 | module.async_probe [KNL] | ||
957 | Enable asynchronous probe on this module. | ||
958 | |||
956 | early_ioremap_debug [KNL] | 959 | early_ioremap_debug [KNL] |
957 | Enable debug messages in early_ioremap support. This | 960 | Enable debug messages in early_ioremap support. This |
958 | is useful for tracking down temporary early mappings | 961 | is useful for tracking down temporary early mappings |
diff --git a/MAINTAINERS b/MAINTAINERS index 161747bdecf3..e4b32dcc2494 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3450,16 +3450,17 @@ F: drivers/block/drbd/ | |||
3450 | F: lib/lru_cache.c | 3450 | F: lib/lru_cache.c |
3451 | F: Documentation/blockdev/drbd/ | 3451 | F: Documentation/blockdev/drbd/ |
3452 | 3452 | ||
3453 | DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS | 3453 | DRIVER CORE, KOBJECTS, DEBUGFS, KERNFS AND SYSFS |
3454 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 3454 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
3455 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git | 3455 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git |
3456 | S: Supported | 3456 | S: Supported |
3457 | F: Documentation/kobject.txt | 3457 | F: Documentation/kobject.txt |
3458 | F: drivers/base/ | 3458 | F: drivers/base/ |
3459 | F: fs/sysfs/ | ||
3460 | F: fs/debugfs/ | 3459 | F: fs/debugfs/ |
3461 | F: include/linux/kobj* | 3460 | F: fs/kernfs/ |
3461 | F: fs/sysfs/ | ||
3462 | F: include/linux/debugfs.h | 3462 | F: include/linux/debugfs.h |
3463 | F: include/linux/kobj* | ||
3463 | F: lib/kobj* | 3464 | F: lib/kobj* |
3464 | 3465 | ||
3465 | DRM DRIVERS | 3466 | DRM DRIVERS |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 38bd5d998c81..1f614d778a8b 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -336,7 +336,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate) | |||
336 | unsigned long gpage_npages[MMU_PAGE_COUNT]; | 336 | unsigned long gpage_npages[MMU_PAGE_COUNT]; |
337 | 337 | ||
338 | static int __init do_gpage_early_setup(char *param, char *val, | 338 | static int __init do_gpage_early_setup(char *param, char *val, |
339 | const char *unused) | 339 | const char *unused, void *arg) |
340 | { | 340 | { |
341 | static phys_addr_t size; | 341 | static phys_addr_t size; |
342 | unsigned long npages; | 342 | unsigned long npages; |
@@ -385,7 +385,7 @@ void __init reserve_hugetlb_gpages(void) | |||
385 | 385 | ||
386 | strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); | 386 | strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); |
387 | parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, | 387 | parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, |
388 | &do_gpage_early_setup); | 388 | NULL, &do_gpage_early_setup); |
389 | 389 | ||
390 | /* | 390 | /* |
391 | * Walk gpage list in reverse, allocating larger page sizes first. | 391 | * Walk gpage list in reverse, allocating larger page sizes first. |
diff --git a/drivers/base/base.h b/drivers/base/base.h index 251c5d30f963..fd3347d9f153 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -116,6 +116,7 @@ static inline int driver_match_device(struct device_driver *drv, | |||
116 | { | 116 | { |
117 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; | 117 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; |
118 | } | 118 | } |
119 | extern bool driver_allows_async_probing(struct device_driver *drv); | ||
119 | 120 | ||
120 | extern int driver_add_groups(struct device_driver *drv, | 121 | extern int driver_add_groups(struct device_driver *drv, |
121 | const struct attribute_group **groups); | 122 | const struct attribute_group **groups); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 79bc203f51ef..500592486e88 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/async.h> | ||
13 | #include <linux/device.h> | 14 | #include <linux/device.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
@@ -549,15 +550,12 @@ void bus_probe_device(struct device *dev) | |||
549 | { | 550 | { |
550 | struct bus_type *bus = dev->bus; | 551 | struct bus_type *bus = dev->bus; |
551 | struct subsys_interface *sif; | 552 | struct subsys_interface *sif; |
552 | int ret; | ||
553 | 553 | ||
554 | if (!bus) | 554 | if (!bus) |
555 | return; | 555 | return; |
556 | 556 | ||
557 | if (bus->p->drivers_autoprobe) { | 557 | if (bus->p->drivers_autoprobe) |
558 | ret = device_attach(dev); | 558 | device_initial_probe(dev); |
559 | WARN_ON(ret < 0); | ||
560 | } | ||
561 | 559 | ||
562 | mutex_lock(&bus->p->mutex); | 560 | mutex_lock(&bus->p->mutex); |
563 | list_for_each_entry(sif, &bus->p->interfaces, node) | 561 | list_for_each_entry(sif, &bus->p->interfaces, node) |
@@ -659,6 +657,17 @@ static ssize_t uevent_store(struct device_driver *drv, const char *buf, | |||
659 | } | 657 | } |
660 | static DRIVER_ATTR_WO(uevent); | 658 | static DRIVER_ATTR_WO(uevent); |
661 | 659 | ||
660 | static void driver_attach_async(void *_drv, async_cookie_t cookie) | ||
661 | { | ||
662 | struct device_driver *drv = _drv; | ||
663 | int ret; | ||
664 | |||
665 | ret = driver_attach(drv); | ||
666 | |||
667 | pr_debug("bus: '%s': driver %s async attach completed: %d\n", | ||
668 | drv->bus->name, drv->name, ret); | ||
669 | } | ||
670 | |||
662 | /** | 671 | /** |
663 | * bus_add_driver - Add a driver to the bus. | 672 | * bus_add_driver - Add a driver to the bus. |
664 | * @drv: driver. | 673 | * @drv: driver. |
@@ -691,9 +700,15 @@ int bus_add_driver(struct device_driver *drv) | |||
691 | 700 | ||
692 | klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); | 701 | klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); |
693 | if (drv->bus->p->drivers_autoprobe) { | 702 | if (drv->bus->p->drivers_autoprobe) { |
694 | error = driver_attach(drv); | 703 | if (driver_allows_async_probing(drv)) { |
695 | if (error) | 704 | pr_debug("bus: '%s': probing driver %s asynchronously\n", |
696 | goto out_unregister; | 705 | drv->bus->name, drv->name); |
706 | async_schedule(driver_attach_async, drv); | ||
707 | } else { | ||
708 | error = driver_attach(drv); | ||
709 | if (error) | ||
710 | goto out_unregister; | ||
711 | } | ||
697 | } | 712 | } |
698 | module_add_driver(drv->owner, drv); | 713 | module_add_driver(drv->owner, drv); |
699 | 714 | ||
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index df0c66cb7ad3..764280a91776 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c | |||
@@ -191,12 +191,12 @@ static int detect_cache_attributes(unsigned int cpu) | |||
191 | if (ret) | 191 | if (ret) |
192 | goto free_ci; | 192 | goto free_ci; |
193 | /* | 193 | /* |
194 | * For systems using DT for cache hierarcy, of_node and shared_cpu_map | 194 | * For systems using DT for cache hierarchy, of_node and shared_cpu_map |
195 | * will be set up here only if they are not populated already | 195 | * will be set up here only if they are not populated already |
196 | */ | 196 | */ |
197 | ret = cache_shared_cpu_map_setup(cpu); | 197 | ret = cache_shared_cpu_map_setup(cpu); |
198 | if (ret) { | 198 | if (ret) { |
199 | pr_warn("Unable to detect cache hierarcy from DT for CPU %d\n", | 199 | pr_warn("Unable to detect cache hierarchy from DT for CPU %d\n", |
200 | cpu); | 200 | cpu); |
201 | goto free_ci; | 201 | goto free_ci; |
202 | } | 202 | } |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index f160ea44a86d..78720e706176 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/cpufeature.h> | 18 | #include <linux/cpufeature.h> |
19 | #include <linux/tick.h> | ||
19 | 20 | ||
20 | #include "base.h" | 21 | #include "base.h" |
21 | 22 | ||
@@ -265,6 +266,30 @@ static ssize_t print_cpus_offline(struct device *dev, | |||
265 | } | 266 | } |
266 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); | 267 | static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); |
267 | 268 | ||
269 | static ssize_t print_cpus_isolated(struct device *dev, | ||
270 | struct device_attribute *attr, char *buf) | ||
271 | { | ||
272 | int n = 0, len = PAGE_SIZE-2; | ||
273 | |||
274 | n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(cpu_isolated_map)); | ||
275 | |||
276 | return n; | ||
277 | } | ||
278 | static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL); | ||
279 | |||
280 | #ifdef CONFIG_NO_HZ_FULL | ||
281 | static ssize_t print_cpus_nohz_full(struct device *dev, | ||
282 | struct device_attribute *attr, char *buf) | ||
283 | { | ||
284 | int n = 0, len = PAGE_SIZE-2; | ||
285 | |||
286 | n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); | ||
287 | |||
288 | return n; | ||
289 | } | ||
290 | static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL); | ||
291 | #endif | ||
292 | |||
268 | static void cpu_device_release(struct device *dev) | 293 | static void cpu_device_release(struct device *dev) |
269 | { | 294 | { |
270 | /* | 295 | /* |
@@ -431,6 +456,10 @@ static struct attribute *cpu_root_attrs[] = { | |||
431 | &cpu_attrs[2].attr.attr, | 456 | &cpu_attrs[2].attr.attr, |
432 | &dev_attr_kernel_max.attr, | 457 | &dev_attr_kernel_max.attr, |
433 | &dev_attr_offline.attr, | 458 | &dev_attr_offline.attr, |
459 | &dev_attr_isolated.attr, | ||
460 | #ifdef CONFIG_NO_HZ_FULL | ||
461 | &dev_attr_nohz_full.attr, | ||
462 | #endif | ||
434 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE | 463 | #ifdef CONFIG_GENERIC_CPU_AUTOPROBE |
435 | &dev_attr_modalias.attr, | 464 | &dev_attr_modalias.attr, |
436 | #endif | 465 | #endif |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e843fdbe4925..a638bbb1a27a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -141,7 +141,7 @@ static bool driver_deferred_probe_enable = false; | |||
141 | * more than one device is probing at the same time, it is possible for one | 141 | * more than one device is probing at the same time, it is possible for one |
142 | * probe to complete successfully while another is about to defer. If the second | 142 | * probe to complete successfully while another is about to defer. If the second |
143 | * depends on the first, then it will get put on the pending list after the | 143 | * depends on the first, then it will get put on the pending list after the |
144 | * trigger event has already occured and will be stuck there. | 144 | * trigger event has already occurred and will be stuck there. |
145 | * | 145 | * |
146 | * The atomic 'deferred_trigger_count' is used to determine if a successful | 146 | * The atomic 'deferred_trigger_count' is used to determine if a successful |
147 | * trigger has occurred in the midst of probing a driver. If the trigger count | 147 | * trigger has occurred in the midst of probing a driver. If the trigger count |
@@ -417,31 +417,107 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
417 | return ret; | 417 | return ret; |
418 | } | 418 | } |
419 | 419 | ||
420 | static int __device_attach(struct device_driver *drv, void *data) | 420 | bool driver_allows_async_probing(struct device_driver *drv) |
421 | { | 421 | { |
422 | struct device *dev = data; | 422 | switch (drv->probe_type) { |
423 | case PROBE_PREFER_ASYNCHRONOUS: | ||
424 | return true; | ||
425 | |||
426 | case PROBE_FORCE_SYNCHRONOUS: | ||
427 | return false; | ||
428 | |||
429 | default: | ||
430 | if (module_requested_async_probing(drv->owner)) | ||
431 | return true; | ||
432 | |||
433 | return false; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | struct device_attach_data { | ||
438 | struct device *dev; | ||
439 | |||
440 | /* | ||
441 | * Indicates whether we are are considering asynchronous probing or | ||
442 | * not. Only initial binding after device or driver registration | ||
443 | * (including deferral processing) may be done asynchronously, the | ||
444 | * rest is always synchronous, as we expect it is being done by | ||
445 | * request from userspace. | ||
446 | */ | ||
447 | bool check_async; | ||
448 | |||
449 | /* | ||
450 | * Indicates if we are binding synchronous or asynchronous drivers. | ||
451 | * When asynchronous probing is enabled we'll execute 2 passes | ||
452 | * over drivers: first pass doing synchronous probing and second | ||
453 | * doing asynchronous probing (if synchronous did not succeed - | ||
454 | * most likely because there was no driver requiring synchronous | ||
455 | * probing - and we found asynchronous driver during first pass). | ||
456 | * The 2 passes are done because we can't shoot asynchronous | ||
457 | * probe for given device and driver from bus_for_each_drv() since | ||
458 | * driver pointer is not guaranteed to stay valid once | ||
459 | * bus_for_each_drv() iterates to the next driver on the bus. | ||
460 | */ | ||
461 | bool want_async; | ||
462 | |||
463 | /* | ||
464 | * We'll set have_async to 'true' if, while scanning for matching | ||
465 | * driver, we'll encounter one that requests asynchronous probing. | ||
466 | */ | ||
467 | bool have_async; | ||
468 | }; | ||
469 | |||
470 | static int __device_attach_driver(struct device_driver *drv, void *_data) | ||
471 | { | ||
472 | struct device_attach_data *data = _data; | ||
473 | struct device *dev = data->dev; | ||
474 | bool async_allowed; | ||
475 | |||
476 | /* | ||
477 | * Check if device has already been claimed. This may | ||
478 | * happen with driver loading, device discovery/registration, | ||
479 | * and deferred probe processing happens all at once with | ||
480 | * multiple threads. | ||
481 | */ | ||
482 | if (dev->driver) | ||
483 | return -EBUSY; | ||
423 | 484 | ||
424 | if (!driver_match_device(drv, dev)) | 485 | if (!driver_match_device(drv, dev)) |
425 | return 0; | 486 | return 0; |
426 | 487 | ||
488 | async_allowed = driver_allows_async_probing(drv); | ||
489 | |||
490 | if (async_allowed) | ||
491 | data->have_async = true; | ||
492 | |||
493 | if (data->check_async && async_allowed != data->want_async) | ||
494 | return 0; | ||
495 | |||
427 | return driver_probe_device(drv, dev); | 496 | return driver_probe_device(drv, dev); |
428 | } | 497 | } |
429 | 498 | ||
430 | /** | 499 | static void __device_attach_async_helper(void *_dev, async_cookie_t cookie) |
431 | * device_attach - try to attach device to a driver. | 500 | { |
432 | * @dev: device. | 501 | struct device *dev = _dev; |
433 | * | 502 | struct device_attach_data data = { |
434 | * Walk the list of drivers that the bus has and call | 503 | .dev = dev, |
435 | * driver_probe_device() for each pair. If a compatible | 504 | .check_async = true, |
436 | * pair is found, break out and return. | 505 | .want_async = true, |
437 | * | 506 | }; |
438 | * Returns 1 if the device was bound to a driver; | 507 | |
439 | * 0 if no matching driver was found; | 508 | device_lock(dev); |
440 | * -ENODEV if the device is not registered. | 509 | |
441 | * | 510 | bus_for_each_drv(dev->bus, NULL, &data, __device_attach_driver); |
442 | * When called for a USB interface, @dev->parent lock must be held. | 511 | dev_dbg(dev, "async probe completed\n"); |
443 | */ | 512 | |
444 | int device_attach(struct device *dev) | 513 | pm_request_idle(dev); |
514 | |||
515 | device_unlock(dev); | ||
516 | |||
517 | put_device(dev); | ||
518 | } | ||
519 | |||
520 | static int __device_attach(struct device *dev, bool allow_async) | ||
445 | { | 521 | { |
446 | int ret = 0; | 522 | int ret = 0; |
447 | 523 | ||
@@ -459,15 +535,59 @@ int device_attach(struct device *dev) | |||
459 | ret = 0; | 535 | ret = 0; |
460 | } | 536 | } |
461 | } else { | 537 | } else { |
462 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 538 | struct device_attach_data data = { |
463 | pm_request_idle(dev); | 539 | .dev = dev, |
540 | .check_async = allow_async, | ||
541 | .want_async = false, | ||
542 | }; | ||
543 | |||
544 | ret = bus_for_each_drv(dev->bus, NULL, &data, | ||
545 | __device_attach_driver); | ||
546 | if (!ret && allow_async && data.have_async) { | ||
547 | /* | ||
548 | * If we could not find appropriate driver | ||
549 | * synchronously and we are allowed to do | ||
550 | * async probes and there are drivers that | ||
551 | * want to probe asynchronously, we'll | ||
552 | * try them. | ||
553 | */ | ||
554 | dev_dbg(dev, "scheduling asynchronous probe\n"); | ||
555 | get_device(dev); | ||
556 | async_schedule(__device_attach_async_helper, dev); | ||
557 | } else { | ||
558 | pm_request_idle(dev); | ||
559 | } | ||
464 | } | 560 | } |
465 | out_unlock: | 561 | out_unlock: |
466 | device_unlock(dev); | 562 | device_unlock(dev); |
467 | return ret; | 563 | return ret; |
468 | } | 564 | } |
565 | |||
566 | /** | ||
567 | * device_attach - try to attach device to a driver. | ||
568 | * @dev: device. | ||
569 | * | ||
570 | * Walk the list of drivers that the bus has and call | ||
571 | * driver_probe_device() for each pair. If a compatible | ||
572 | * pair is found, break out and return. | ||
573 | * | ||
574 | * Returns 1 if the device was bound to a driver; | ||
575 | * 0 if no matching driver was found; | ||
576 | * -ENODEV if the device is not registered. | ||
577 | * | ||
578 | * When called for a USB interface, @dev->parent lock must be held. | ||
579 | */ | ||
580 | int device_attach(struct device *dev) | ||
581 | { | ||
582 | return __device_attach(dev, false); | ||
583 | } | ||
469 | EXPORT_SYMBOL_GPL(device_attach); | 584 | EXPORT_SYMBOL_GPL(device_attach); |
470 | 585 | ||
586 | void device_initial_probe(struct device *dev) | ||
587 | { | ||
588 | __device_attach(dev, true); | ||
589 | } | ||
590 | |||
471 | static int __driver_attach(struct device *dev, void *data) | 591 | static int __driver_attach(struct device *dev, void *data) |
472 | { | 592 | { |
473 | struct device_driver *drv = data; | 593 | struct device_driver *drv = data; |
@@ -522,6 +642,9 @@ static void __device_release_driver(struct device *dev) | |||
522 | 642 | ||
523 | drv = dev->driver; | 643 | drv = dev->driver; |
524 | if (drv) { | 644 | if (drv) { |
645 | if (driver_allows_async_probing(drv)) | ||
646 | async_synchronize_full(); | ||
647 | |||
525 | pm_runtime_get_sync(dev); | 648 | pm_runtime_get_sync(dev); |
526 | 649 | ||
527 | driver_sysfs_remove(dev); | 650 | driver_sysfs_remove(dev); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 171841ad1008..9c4288362a8e 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -150,17 +150,17 @@ struct firmware_buf { | |||
150 | int page_array_size; | 150 | int page_array_size; |
151 | struct list_head pending_list; | 151 | struct list_head pending_list; |
152 | #endif | 152 | #endif |
153 | char fw_id[]; | 153 | const char *fw_id; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | struct fw_cache_entry { | 156 | struct fw_cache_entry { |
157 | struct list_head list; | 157 | struct list_head list; |
158 | char name[]; | 158 | const char *name; |
159 | }; | 159 | }; |
160 | 160 | ||
161 | struct fw_name_devm { | 161 | struct fw_name_devm { |
162 | unsigned long magic; | 162 | unsigned long magic; |
163 | char name[]; | 163 | const char *name; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | #define to_fwbuf(d) container_of(d, struct firmware_buf, ref) | 166 | #define to_fwbuf(d) container_of(d, struct firmware_buf, ref) |
@@ -181,13 +181,17 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, | |||
181 | { | 181 | { |
182 | struct firmware_buf *buf; | 182 | struct firmware_buf *buf; |
183 | 183 | ||
184 | buf = kzalloc(sizeof(*buf) + strlen(fw_name) + 1, GFP_ATOMIC); | 184 | buf = kzalloc(sizeof(*buf), GFP_ATOMIC); |
185 | |||
186 | if (!buf) | 185 | if (!buf) |
187 | return buf; | 186 | return NULL; |
187 | |||
188 | buf->fw_id = kstrdup_const(fw_name, GFP_ATOMIC); | ||
189 | if (!buf->fw_id) { | ||
190 | kfree(buf); | ||
191 | return NULL; | ||
192 | } | ||
188 | 193 | ||
189 | kref_init(&buf->ref); | 194 | kref_init(&buf->ref); |
190 | strcpy(buf->fw_id, fw_name); | ||
191 | buf->fwc = fwc; | 195 | buf->fwc = fwc; |
192 | init_completion(&buf->completion); | 196 | init_completion(&buf->completion); |
193 | #ifdef CONFIG_FW_LOADER_USER_HELPER | 197 | #ifdef CONFIG_FW_LOADER_USER_HELPER |
@@ -257,6 +261,7 @@ static void __fw_free_buf(struct kref *ref) | |||
257 | } else | 261 | } else |
258 | #endif | 262 | #endif |
259 | vfree(buf->data); | 263 | vfree(buf->data); |
264 | kfree_const(buf->fw_id); | ||
260 | kfree(buf); | 265 | kfree(buf); |
261 | } | 266 | } |
262 | 267 | ||
@@ -320,9 +325,13 @@ fail: | |||
320 | static int fw_get_filesystem_firmware(struct device *device, | 325 | static int fw_get_filesystem_firmware(struct device *device, |
321 | struct firmware_buf *buf) | 326 | struct firmware_buf *buf) |
322 | { | 327 | { |
323 | int i; | 328 | int i, len; |
324 | int rc = -ENOENT; | 329 | int rc = -ENOENT; |
325 | char *path = __getname(); | 330 | char *path; |
331 | |||
332 | path = __getname(); | ||
333 | if (!path) | ||
334 | return -ENOMEM; | ||
326 | 335 | ||
327 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | 336 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { |
328 | struct file *file; | 337 | struct file *file; |
@@ -331,7 +340,12 @@ static int fw_get_filesystem_firmware(struct device *device, | |||
331 | if (!fw_path[i][0]) | 340 | if (!fw_path[i][0]) |
332 | continue; | 341 | continue; |
333 | 342 | ||
334 | snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); | 343 | len = snprintf(path, PATH_MAX, "%s/%s", |
344 | fw_path[i], buf->fw_id); | ||
345 | if (len >= PATH_MAX) { | ||
346 | rc = -ENAMETOOLONG; | ||
347 | break; | ||
348 | } | ||
335 | 349 | ||
336 | file = filp_open(path, O_RDONLY, 0); | 350 | file = filp_open(path, O_RDONLY, 0); |
337 | if (IS_ERR(file)) | 351 | if (IS_ERR(file)) |
@@ -392,6 +406,7 @@ static void fw_name_devm_release(struct device *dev, void *res) | |||
392 | if (fwn->magic == (unsigned long)&fw_cache) | 406 | if (fwn->magic == (unsigned long)&fw_cache) |
393 | pr_debug("%s: fw_name-%s devm-%p released\n", | 407 | pr_debug("%s: fw_name-%s devm-%p released\n", |
394 | __func__, fwn->name, res); | 408 | __func__, fwn->name, res); |
409 | kfree_const(fwn->name); | ||
395 | } | 410 | } |
396 | 411 | ||
397 | static int fw_devm_match(struct device *dev, void *res, | 412 | static int fw_devm_match(struct device *dev, void *res, |
@@ -422,13 +437,17 @@ static int fw_add_devm_name(struct device *dev, const char *name) | |||
422 | if (fwn) | 437 | if (fwn) |
423 | return 1; | 438 | return 1; |
424 | 439 | ||
425 | fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + | 440 | fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm), |
426 | strlen(name) + 1, GFP_KERNEL); | 441 | GFP_KERNEL); |
427 | if (!fwn) | 442 | if (!fwn) |
428 | return -ENOMEM; | 443 | return -ENOMEM; |
444 | fwn->name = kstrdup_const(name, GFP_KERNEL); | ||
445 | if (!fwn->name) { | ||
446 | kfree(fwn); | ||
447 | return -ENOMEM; | ||
448 | } | ||
429 | 449 | ||
430 | fwn->magic = (unsigned long)&fw_cache; | 450 | fwn->magic = (unsigned long)&fw_cache; |
431 | strcpy(fwn->name, name); | ||
432 | devres_add(dev, fwn); | 451 | devres_add(dev, fwn); |
433 | 452 | ||
434 | return 0; | 453 | return 0; |
@@ -1247,6 +1266,7 @@ static void request_firmware_work_func(struct work_struct *work) | |||
1247 | put_device(fw_work->device); /* taken in request_firmware_nowait() */ | 1266 | put_device(fw_work->device); /* taken in request_firmware_nowait() */ |
1248 | 1267 | ||
1249 | module_put(fw_work->module); | 1268 | module_put(fw_work->module); |
1269 | kfree_const(fw_work->name); | ||
1250 | kfree(fw_work); | 1270 | kfree(fw_work); |
1251 | } | 1271 | } |
1252 | 1272 | ||
@@ -1286,7 +1306,11 @@ request_firmware_nowait( | |||
1286 | return -ENOMEM; | 1306 | return -ENOMEM; |
1287 | 1307 | ||
1288 | fw_work->module = module; | 1308 | fw_work->module = module; |
1289 | fw_work->name = name; | 1309 | fw_work->name = kstrdup_const(name, gfp); |
1310 | if (!fw_work->name) { | ||
1311 | kfree(fw_work); | ||
1312 | return -ENOMEM; | ||
1313 | } | ||
1290 | fw_work->device = device; | 1314 | fw_work->device = device; |
1291 | fw_work->context = context; | 1315 | fw_work->context = context; |
1292 | fw_work->cont = cont; | 1316 | fw_work->cont = cont; |
@@ -1294,6 +1318,7 @@ request_firmware_nowait( | |||
1294 | (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); | 1318 | (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); |
1295 | 1319 | ||
1296 | if (!try_module_get(module)) { | 1320 | if (!try_module_get(module)) { |
1321 | kfree_const(fw_work->name); | ||
1297 | kfree(fw_work); | 1322 | kfree(fw_work); |
1298 | return -EFAULT; | 1323 | return -EFAULT; |
1299 | } | 1324 | } |
@@ -1384,11 +1409,16 @@ static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) | |||
1384 | { | 1409 | { |
1385 | struct fw_cache_entry *fce; | 1410 | struct fw_cache_entry *fce; |
1386 | 1411 | ||
1387 | fce = kzalloc(sizeof(*fce) + strlen(name) + 1, GFP_ATOMIC); | 1412 | fce = kzalloc(sizeof(*fce), GFP_ATOMIC); |
1388 | if (!fce) | 1413 | if (!fce) |
1389 | goto exit; | 1414 | goto exit; |
1390 | 1415 | ||
1391 | strcpy(fce->name, name); | 1416 | fce->name = kstrdup_const(name, GFP_ATOMIC); |
1417 | if (!fce->name) { | ||
1418 | kfree(fce); | ||
1419 | fce = NULL; | ||
1420 | goto exit; | ||
1421 | } | ||
1392 | exit: | 1422 | exit: |
1393 | return fce; | 1423 | return fce; |
1394 | } | 1424 | } |
@@ -1428,6 +1458,7 @@ found: | |||
1428 | 1458 | ||
1429 | static void free_fw_cache_entry(struct fw_cache_entry *fce) | 1459 | static void free_fw_cache_entry(struct fw_cache_entry *fce) |
1430 | { | 1460 | { |
1461 | kfree_const(fce->name); | ||
1431 | kfree(fce); | 1462 | kfree(fce); |
1432 | } | 1463 | } |
1433 | 1464 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index ebf034b97278..063f0ab15259 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -613,6 +613,19 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv, | |||
613 | { | 613 | { |
614 | int retval, code; | 614 | int retval, code; |
615 | 615 | ||
616 | if (drv->driver.probe_type == PROBE_PREFER_ASYNCHRONOUS) { | ||
617 | pr_err("%s: drivers registered with %s can not be probed asynchronously\n", | ||
618 | drv->driver.name, __func__); | ||
619 | return -EINVAL; | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * We have to run our probes synchronously because we check if | ||
624 | * we find any devices to bind to and exit with error if there | ||
625 | * are any. | ||
626 | */ | ||
627 | drv->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | ||
628 | |||
616 | /* | 629 | /* |
617 | * Prevent driver from requesting probe deferral to avoid further | 630 | * Prevent driver from requesting probe deferral to avoid further |
618 | * futile probe attempts. | 631 | * futile probe attempts. |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 92772fffc52f..73aea40a9c89 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -2964,6 +2964,7 @@ static struct pci_driver amd64_pci_driver = { | |||
2964 | .probe = probe_one_instance, | 2964 | .probe = probe_one_instance, |
2965 | .remove = remove_one_instance, | 2965 | .remove = remove_one_instance, |
2966 | .id_table = amd64_pci_table, | 2966 | .id_table = amd64_pci_table, |
2967 | .driver.probe_type = PROBE_FORCE_SYNCHRONOUS, | ||
2967 | }; | 2968 | }; |
2968 | 2969 | ||
2969 | static void setup_pci_device(void) | 2970 | static void setup_pci_device(void) |
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 2bacb9988566..7247252ee9b1 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
@@ -785,7 +785,6 @@ static unsigned int kernfs_fop_poll(struct file *filp, poll_table *wait) | |||
785 | struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; | 785 | struct kernfs_node *kn = filp->f_path.dentry->d_fsdata; |
786 | struct kernfs_open_node *on = kn->attr.open; | 786 | struct kernfs_open_node *on = kn->attr.open; |
787 | 787 | ||
788 | /* need parent for the kobj, grab both */ | ||
789 | if (!kernfs_get_active(kn)) | 788 | if (!kernfs_get_active(kn)) |
790 | goto trigger; | 789 | goto trigger; |
791 | 790 | ||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 7c2867b44141..6c95628ea377 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -90,7 +90,7 @@ static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, | |||
90 | return 0; | 90 | return 0; |
91 | 91 | ||
92 | if (size) { | 92 | if (size) { |
93 | if (pos > size) | 93 | if (pos >= size) |
94 | return 0; | 94 | return 0; |
95 | if (pos + count > size) | 95 | if (pos + count > size) |
96 | count = size - pos; | 96 | count = size - pos; |
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index b400c04371f0..39a019936768 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -135,7 +135,7 @@ static int internal_create_group(struct kobject *kobj, int update, | |||
135 | * This function creates a group for the first time. It will explicitly | 135 | * This function creates a group for the first time. It will explicitly |
136 | * warn and error if any of the attribute files being created already exist. | 136 | * warn and error if any of the attribute files being created already exist. |
137 | * | 137 | * |
138 | * Returns 0 on success or error. | 138 | * Returns 0 on success or error code on failure. |
139 | */ | 139 | */ |
140 | int sysfs_create_group(struct kobject *kobj, | 140 | int sysfs_create_group(struct kobject *kobj, |
141 | const struct attribute_group *grp) | 141 | const struct attribute_group *grp) |
@@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(sysfs_create_group); | |||
155 | * It will explicitly warn and error if any of the attribute files being | 155 | * It will explicitly warn and error if any of the attribute files being |
156 | * created already exist. | 156 | * created already exist. |
157 | * | 157 | * |
158 | * Returns 0 on success or error code from sysfs_create_group on error. | 158 | * Returns 0 on success or error code from sysfs_create_group on failure. |
159 | */ | 159 | */ |
160 | int sysfs_create_groups(struct kobject *kobj, | 160 | int sysfs_create_groups(struct kobject *kobj, |
161 | const struct attribute_group **groups) | 161 | const struct attribute_group **groups) |
@@ -193,7 +193,7 @@ EXPORT_SYMBOL_GPL(sysfs_create_groups); | |||
193 | * The primary use for this function is to call it after making a change | 193 | * The primary use for this function is to call it after making a change |
194 | * that affects group visibility. | 194 | * that affects group visibility. |
195 | * | 195 | * |
196 | * Returns 0 on success or error. | 196 | * Returns 0 on success or error code on failure. |
197 | */ | 197 | */ |
198 | int sysfs_update_group(struct kobject *kobj, | 198 | int sysfs_update_group(struct kobject *kobj, |
199 | const struct attribute_group *grp) | 199 | const struct attribute_group *grp) |
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h index 3daf5ed392c9..2189935075b4 100644 --- a/include/linux/cacheinfo.h +++ b/include/linux/cacheinfo.h | |||
@@ -19,7 +19,7 @@ enum cache_type { | |||
19 | /** | 19 | /** |
20 | * struct cacheinfo - represent a cache leaf node | 20 | * struct cacheinfo - represent a cache leaf node |
21 | * @type: type of the cache - data, inst or unified | 21 | * @type: type of the cache - data, inst or unified |
22 | * @level: represents the hierarcy in the multi-level cache | 22 | * @level: represents the hierarchy in the multi-level cache |
23 | * @coherency_line_size: size of each cache line usually representing | 23 | * @coherency_line_size: size of each cache line usually representing |
24 | * the minimum amount of data that gets transferred from memory | 24 | * the minimum amount of data that gets transferred from memory |
25 | * @number_of_sets: total number of sets, a set is a collection of cache | 25 | * @number_of_sets: total number of sets, a set is a collection of cache |
diff --git a/include/linux/device.h b/include/linux/device.h index 6558af90c8fe..00ac57c26615 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -196,12 +196,41 @@ extern struct kset *bus_get_kset(struct bus_type *bus); | |||
196 | extern struct klist *bus_get_device_klist(struct bus_type *bus); | 196 | extern struct klist *bus_get_device_klist(struct bus_type *bus); |
197 | 197 | ||
198 | /** | 198 | /** |
199 | * enum probe_type - device driver probe type to try | ||
200 | * Device drivers may opt in for special handling of their | ||
201 | * respective probe routines. This tells the core what to | ||
202 | * expect and prefer. | ||
203 | * | ||
204 | * @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well | ||
205 | * whether probed synchronously or asynchronously. | ||
206 | * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which | ||
207 | * probing order is not essential for booting the system may | ||
208 | * opt into executing their probes asynchronously. | ||
209 | * @PROBE_FORCE_SYNCHRONOUS: Use this to annotate drivers that need | ||
210 | * their probe routines to run synchronously with driver and | ||
211 | * device registration (with the exception of -EPROBE_DEFER | ||
212 | * handling - re-probing always ends up being done asynchronously). | ||
213 | * | ||
214 | * Note that the end goal is to switch the kernel to use asynchronous | ||
215 | * probing by default, so annotating drivers with | ||
216 | * %PROBE_PREFER_ASYNCHRONOUS is a temporary measure that allows us | ||
217 | * to speed up boot process while we are validating the rest of the | ||
218 | * drivers. | ||
219 | */ | ||
220 | enum probe_type { | ||
221 | PROBE_DEFAULT_STRATEGY, | ||
222 | PROBE_PREFER_ASYNCHRONOUS, | ||
223 | PROBE_FORCE_SYNCHRONOUS, | ||
224 | }; | ||
225 | |||
226 | /** | ||
199 | * struct device_driver - The basic device driver structure | 227 | * struct device_driver - The basic device driver structure |
200 | * @name: Name of the device driver. | 228 | * @name: Name of the device driver. |
201 | * @bus: The bus which the device of this driver belongs to. | 229 | * @bus: The bus which the device of this driver belongs to. |
202 | * @owner: The module owner. | 230 | * @owner: The module owner. |
203 | * @mod_name: Used for built-in modules. | 231 | * @mod_name: Used for built-in modules. |
204 | * @suppress_bind_attrs: Disables bind/unbind via sysfs. | 232 | * @suppress_bind_attrs: Disables bind/unbind via sysfs. |
233 | * @probe_type: Type of the probe (synchronous or asynchronous) to use. | ||
205 | * @of_match_table: The open firmware table. | 234 | * @of_match_table: The open firmware table. |
206 | * @acpi_match_table: The ACPI match table. | 235 | * @acpi_match_table: The ACPI match table. |
207 | * @probe: Called to query the existence of a specific device, | 236 | * @probe: Called to query the existence of a specific device, |
@@ -235,6 +264,7 @@ struct device_driver { | |||
235 | const char *mod_name; /* used for built-in modules */ | 264 | const char *mod_name; /* used for built-in modules */ |
236 | 265 | ||
237 | bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ | 266 | bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ |
267 | enum probe_type probe_type; | ||
238 | 268 | ||
239 | const struct of_device_id *of_match_table; | 269 | const struct of_device_id *of_match_table; |
240 | const struct acpi_device_id *acpi_match_table; | 270 | const struct acpi_device_id *acpi_match_table; |
@@ -975,6 +1005,7 @@ extern int __must_check device_bind_driver(struct device *dev); | |||
975 | extern void device_release_driver(struct device *dev); | 1005 | extern void device_release_driver(struct device *dev); |
976 | extern int __must_check device_attach(struct device *dev); | 1006 | extern int __must_check device_attach(struct device *dev); |
977 | extern int __must_check driver_attach(struct device_driver *drv); | 1007 | extern int __must_check driver_attach(struct device_driver *drv); |
1008 | extern void device_initial_probe(struct device *dev); | ||
978 | extern int __must_check device_reprobe(struct device *dev); | 1009 | extern int __must_check device_reprobe(struct device *dev); |
979 | 1010 | ||
980 | /* | 1011 | /* |
diff --git a/include/linux/module.h b/include/linux/module.h index 255fca74de7d..7ffe0851d244 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -257,6 +257,8 @@ struct module { | |||
257 | bool sig_ok; | 257 | bool sig_ok; |
258 | #endif | 258 | #endif |
259 | 259 | ||
260 | bool async_probe_requested; | ||
261 | |||
260 | /* symbols that will be GPL-only in the near future. */ | 262 | /* symbols that will be GPL-only in the near future. */ |
261 | const struct kernel_symbol *gpl_future_syms; | 263 | const struct kernel_symbol *gpl_future_syms; |
262 | const unsigned long *gpl_future_crcs; | 264 | const unsigned long *gpl_future_crcs; |
@@ -508,6 +510,11 @@ int unregister_module_notifier(struct notifier_block *nb); | |||
508 | 510 | ||
509 | extern void print_modules(void); | 511 | extern void print_modules(void); |
510 | 512 | ||
513 | static inline bool module_requested_async_probing(struct module *module) | ||
514 | { | ||
515 | return module && module->async_probe_requested; | ||
516 | } | ||
517 | |||
511 | #else /* !CONFIG_MODULES... */ | 518 | #else /* !CONFIG_MODULES... */ |
512 | 519 | ||
513 | /* Given an address, look for it in the exception tables. */ | 520 | /* Given an address, look for it in the exception tables. */ |
@@ -618,6 +625,12 @@ static inline int unregister_module_notifier(struct notifier_block *nb) | |||
618 | static inline void print_modules(void) | 625 | static inline void print_modules(void) |
619 | { | 626 | { |
620 | } | 627 | } |
628 | |||
629 | static inline bool module_requested_async_probing(struct module *module) | ||
630 | { | ||
631 | return false; | ||
632 | } | ||
633 | |||
621 | #endif /* CONFIG_MODULES */ | 634 | #endif /* CONFIG_MODULES */ |
622 | 635 | ||
623 | #ifdef CONFIG_SYSFS | 636 | #ifdef CONFIG_SYSFS |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 1c9effa25e26..6480dcaca275 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
@@ -310,6 +310,15 @@ static inline void __kernel_param_unlock(void) | |||
310 | #define core_param(name, var, type, perm) \ | 310 | #define core_param(name, var, type, perm) \ |
311 | param_check_##type(name, &(var)); \ | 311 | param_check_##type(name, &(var)); \ |
312 | __module_param_call("", name, ¶m_ops_##type, &var, perm, -1, 0) | 312 | __module_param_call("", name, ¶m_ops_##type, &var, perm, -1, 0) |
313 | |||
314 | /** | ||
315 | * core_param_unsafe - same as core_param but taints kernel | ||
316 | */ | ||
317 | #define core_param_unsafe(name, var, type, perm) \ | ||
318 | param_check_##type(name, &(var)); \ | ||
319 | __module_param_call("", name, ¶m_ops_##type, &var, perm, \ | ||
320 | -1, KERNEL_PARAM_FL_UNSAFE) | ||
321 | |||
313 | #endif /* !MODULE */ | 322 | #endif /* !MODULE */ |
314 | 323 | ||
315 | /** | 324 | /** |
@@ -357,8 +366,9 @@ extern char *parse_args(const char *name, | |||
357 | unsigned num, | 366 | unsigned num, |
358 | s16 level_min, | 367 | s16 level_min, |
359 | s16 level_max, | 368 | s16 level_max, |
369 | void *arg, | ||
360 | int (*unknown)(char *param, char *val, | 370 | int (*unknown)(char *param, char *val, |
361 | const char *doing)); | 371 | const char *doing, void *arg)); |
362 | 372 | ||
363 | /* Called by module remove. */ | 373 | /* Called by module remove. */ |
364 | #ifdef CONFIG_SYSFS | 374 | #ifdef CONFIG_SYSFS |
diff --git a/init/main.c b/init/main.c index 2a89545e0a5d..c599aea23bb1 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -235,7 +235,8 @@ static int __init loglevel(char *str) | |||
235 | early_param("loglevel", loglevel); | 235 | early_param("loglevel", loglevel); |
236 | 236 | ||
237 | /* Change NUL term back to "=", to make "param" the whole string. */ | 237 | /* Change NUL term back to "=", to make "param" the whole string. */ |
238 | static int __init repair_env_string(char *param, char *val, const char *unused) | 238 | static int __init repair_env_string(char *param, char *val, |
239 | const char *unused, void *arg) | ||
239 | { | 240 | { |
240 | if (val) { | 241 | if (val) { |
241 | /* param=val or param="val"? */ | 242 | /* param=val or param="val"? */ |
@@ -252,14 +253,15 @@ static int __init repair_env_string(char *param, char *val, const char *unused) | |||
252 | } | 253 | } |
253 | 254 | ||
254 | /* Anything after -- gets handed straight to init. */ | 255 | /* Anything after -- gets handed straight to init. */ |
255 | static int __init set_init_arg(char *param, char *val, const char *unused) | 256 | static int __init set_init_arg(char *param, char *val, |
257 | const char *unused, void *arg) | ||
256 | { | 258 | { |
257 | unsigned int i; | 259 | unsigned int i; |
258 | 260 | ||
259 | if (panic_later) | 261 | if (panic_later) |
260 | return 0; | 262 | return 0; |
261 | 263 | ||
262 | repair_env_string(param, val, unused); | 264 | repair_env_string(param, val, unused, NULL); |
263 | 265 | ||
264 | for (i = 0; argv_init[i]; i++) { | 266 | for (i = 0; argv_init[i]; i++) { |
265 | if (i == MAX_INIT_ARGS) { | 267 | if (i == MAX_INIT_ARGS) { |
@@ -276,9 +278,10 @@ static int __init set_init_arg(char *param, char *val, const char *unused) | |||
276 | * Unknown boot options get handed to init, unless they look like | 278 | * Unknown boot options get handed to init, unless they look like |
277 | * unused parameters (modprobe will find them in /proc/cmdline). | 279 | * unused parameters (modprobe will find them in /proc/cmdline). |
278 | */ | 280 | */ |
279 | static int __init unknown_bootoption(char *param, char *val, const char *unused) | 281 | static int __init unknown_bootoption(char *param, char *val, |
282 | const char *unused, void *arg) | ||
280 | { | 283 | { |
281 | repair_env_string(param, val, unused); | 284 | repair_env_string(param, val, unused, NULL); |
282 | 285 | ||
283 | /* Handle obsolete-style parameters */ | 286 | /* Handle obsolete-style parameters */ |
284 | if (obsolete_checksetup(param)) | 287 | if (obsolete_checksetup(param)) |
@@ -410,7 +413,8 @@ static noinline void __init_refok rest_init(void) | |||
410 | } | 413 | } |
411 | 414 | ||
412 | /* Check for early params. */ | 415 | /* Check for early params. */ |
413 | static int __init do_early_param(char *param, char *val, const char *unused) | 416 | static int __init do_early_param(char *param, char *val, |
417 | const char *unused, void *arg) | ||
414 | { | 418 | { |
415 | const struct obs_kernel_param *p; | 419 | const struct obs_kernel_param *p; |
416 | 420 | ||
@@ -429,7 +433,8 @@ static int __init do_early_param(char *param, char *val, const char *unused) | |||
429 | 433 | ||
430 | void __init parse_early_options(char *cmdline) | 434 | void __init parse_early_options(char *cmdline) |
431 | { | 435 | { |
432 | parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param); | 436 | parse_args("early options", cmdline, NULL, 0, 0, 0, NULL, |
437 | do_early_param); | ||
433 | } | 438 | } |
434 | 439 | ||
435 | /* Arch code calls this early on, or if not, just before other parsing. */ | 440 | /* Arch code calls this early on, or if not, just before other parsing. */ |
@@ -535,10 +540,10 @@ asmlinkage __visible void __init start_kernel(void) | |||
535 | after_dashes = parse_args("Booting kernel", | 540 | after_dashes = parse_args("Booting kernel", |
536 | static_command_line, __start___param, | 541 | static_command_line, __start___param, |
537 | __stop___param - __start___param, | 542 | __stop___param - __start___param, |
538 | -1, -1, &unknown_bootoption); | 543 | -1, -1, NULL, &unknown_bootoption); |
539 | if (!IS_ERR_OR_NULL(after_dashes)) | 544 | if (!IS_ERR_OR_NULL(after_dashes)) |
540 | parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, | 545 | parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, |
541 | set_init_arg); | 546 | NULL, set_init_arg); |
542 | 547 | ||
543 | jump_label_init(); | 548 | jump_label_init(); |
544 | 549 | ||
@@ -848,7 +853,7 @@ static void __init do_initcall_level(int level) | |||
848 | initcall_command_line, __start___param, | 853 | initcall_command_line, __start___param, |
849 | __stop___param - __start___param, | 854 | __stop___param - __start___param, |
850 | level, level, | 855 | level, level, |
851 | &repair_env_string); | 856 | NULL, &repair_env_string); |
852 | 857 | ||
853 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) | 858 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) |
854 | do_one_initcall(*fn); | 859 | do_one_initcall(*fn); |
diff --git a/kernel/module.c b/kernel/module.c index b38f96a183b5..f80a97f7da1f 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -3107,7 +3107,7 @@ static noinline int do_init_module(struct module *mod) | |||
3107 | * | 3107 | * |
3108 | * http://thread.gmane.org/gmane.linux.kernel/1420814 | 3108 | * http://thread.gmane.org/gmane.linux.kernel/1420814 |
3109 | */ | 3109 | */ |
3110 | if (current->flags & PF_USED_ASYNC) | 3110 | if (!mod->async_probe_requested && (current->flags & PF_USED_ASYNC)) |
3111 | async_synchronize_full(); | 3111 | async_synchronize_full(); |
3112 | 3112 | ||
3113 | mutex_lock(&module_mutex); | 3113 | mutex_lock(&module_mutex); |
@@ -3237,10 +3237,19 @@ out: | |||
3237 | return err; | 3237 | return err; |
3238 | } | 3238 | } |
3239 | 3239 | ||
3240 | static int unknown_module_param_cb(char *param, char *val, const char *modname) | 3240 | static int unknown_module_param_cb(char *param, char *val, const char *modname, |
3241 | void *arg) | ||
3241 | { | 3242 | { |
3243 | struct module *mod = arg; | ||
3244 | int ret; | ||
3245 | |||
3246 | if (strcmp(param, "async_probe") == 0) { | ||
3247 | mod->async_probe_requested = true; | ||
3248 | return 0; | ||
3249 | } | ||
3250 | |||
3242 | /* Check for magic 'dyndbg' arg */ | 3251 | /* Check for magic 'dyndbg' arg */ |
3243 | int ret = ddebug_dyndbg_module_param_cb(param, val, modname); | 3252 | ret = ddebug_dyndbg_module_param_cb(param, val, modname); |
3244 | if (ret != 0) | 3253 | if (ret != 0) |
3245 | pr_warn("%s: unknown parameter '%s' ignored\n", modname, param); | 3254 | pr_warn("%s: unknown parameter '%s' ignored\n", modname, param); |
3246 | return 0; | 3255 | return 0; |
@@ -3342,7 +3351,8 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
3342 | 3351 | ||
3343 | /* Module is ready to execute: parsing args may do that. */ | 3352 | /* Module is ready to execute: parsing args may do that. */ |
3344 | after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, | 3353 | after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, |
3345 | -32768, 32767, unknown_module_param_cb); | 3354 | -32768, 32767, NULL, |
3355 | unknown_module_param_cb); | ||
3346 | if (IS_ERR(after_dashes)) { | 3356 | if (IS_ERR(after_dashes)) { |
3347 | err = PTR_ERR(after_dashes); | 3357 | err = PTR_ERR(after_dashes); |
3348 | goto bug_cleanup; | 3358 | goto bug_cleanup; |
diff --git a/kernel/params.c b/kernel/params.c index a22d6a759b1a..30288c1e15dd 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -100,8 +100,9 @@ static int parse_one(char *param, | |||
100 | unsigned num_params, | 100 | unsigned num_params, |
101 | s16 min_level, | 101 | s16 min_level, |
102 | s16 max_level, | 102 | s16 max_level, |
103 | void *arg, | ||
103 | int (*handle_unknown)(char *param, char *val, | 104 | int (*handle_unknown)(char *param, char *val, |
104 | const char *doing)) | 105 | const char *doing, void *arg)) |
105 | { | 106 | { |
106 | unsigned int i; | 107 | unsigned int i; |
107 | int err; | 108 | int err; |
@@ -128,7 +129,7 @@ static int parse_one(char *param, | |||
128 | 129 | ||
129 | if (handle_unknown) { | 130 | if (handle_unknown) { |
130 | pr_debug("doing %s: %s='%s'\n", doing, param, val); | 131 | pr_debug("doing %s: %s='%s'\n", doing, param, val); |
131 | return handle_unknown(param, val, doing); | 132 | return handle_unknown(param, val, doing, arg); |
132 | } | 133 | } |
133 | 134 | ||
134 | pr_debug("Unknown argument '%s'\n", param); | 135 | pr_debug("Unknown argument '%s'\n", param); |
@@ -194,7 +195,9 @@ char *parse_args(const char *doing, | |||
194 | unsigned num, | 195 | unsigned num, |
195 | s16 min_level, | 196 | s16 min_level, |
196 | s16 max_level, | 197 | s16 max_level, |
197 | int (*unknown)(char *param, char *val, const char *doing)) | 198 | void *arg, |
199 | int (*unknown)(char *param, char *val, | ||
200 | const char *doing, void *arg)) | ||
198 | { | 201 | { |
199 | char *param, *val; | 202 | char *param, *val; |
200 | 203 | ||
@@ -214,7 +217,7 @@ char *parse_args(const char *doing, | |||
214 | return args; | 217 | return args; |
215 | irq_was_disabled = irqs_disabled(); | 218 | irq_was_disabled = irqs_disabled(); |
216 | ret = parse_one(param, val, doing, params, num, | 219 | ret = parse_one(param, val, doing, params, num, |
217 | min_level, max_level, unknown); | 220 | min_level, max_level, arg, unknown); |
218 | if (irq_was_disabled && !irqs_disabled()) | 221 | if (irq_was_disabled && !irqs_disabled()) |
219 | pr_warn("%s: option '%s' enabled irq's!\n", | 222 | pr_warn("%s: option '%s' enabled irq's!\n", |
220 | doing, param); | 223 | doing, param); |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index d8f3d3150603..e491e02eff54 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -887,7 +887,7 @@ static int ddebug_dyndbg_param_cb(char *param, char *val, | |||
887 | 887 | ||
888 | /* handle both dyndbg and $module.dyndbg params at boot */ | 888 | /* handle both dyndbg and $module.dyndbg params at boot */ |
889 | static int ddebug_dyndbg_boot_param_cb(char *param, char *val, | 889 | static int ddebug_dyndbg_boot_param_cb(char *param, char *val, |
890 | const char *unused) | 890 | const char *unused, void *arg) |
891 | { | 891 | { |
892 | vpr_info("%s=\"%s\"\n", param, val); | 892 | vpr_info("%s=\"%s\"\n", param, val); |
893 | return ddebug_dyndbg_param_cb(param, val, NULL, 0); | 893 | return ddebug_dyndbg_param_cb(param, val, NULL, 0); |
@@ -1028,7 +1028,7 @@ static int __init dynamic_debug_init(void) | |||
1028 | */ | 1028 | */ |
1029 | cmdline = kstrdup(saved_command_line, GFP_KERNEL); | 1029 | cmdline = kstrdup(saved_command_line, GFP_KERNEL); |
1030 | parse_args("dyndbg params", cmdline, NULL, | 1030 | parse_args("dyndbg params", cmdline, NULL, |
1031 | 0, 0, 0, &ddebug_dyndbg_boot_param_cb); | 1031 | 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb); |
1032 | kfree(cmdline); | 1032 | kfree(cmdline); |
1033 | return 0; | 1033 | return 0; |
1034 | 1034 | ||