diff options
author | Todd Poynor <toddpoynor@google.com> | 2018-06-20 20:35:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-06 10:53:17 -0400 |
commit | 0a50f61c4fbd7840cdaf783c312e42b8ccde9ab3 (patch) | |
tree | 41ae1227add777e055d09133c12ac1bfaf74bde4 /drivers/base/dd.c | |
parent | 7daf201d7fe8334e2d2364d4e8ed3394ec9af819 (diff) |
drivers: base: initcall_debug logs for driver probe times
Add initcall_debug logs for each driver device probe call, for example:
probe of a3800000.ramoops returned 1 after 3007 usecs
This replaces the previous code added to report times for deferred
probes. It also reports OF platform bus device creates that were
formerly lumped together in a single entry for function
of_platform_default_populate_init, as well as helping to annotate other
initcalls that involve device probing.
Remove restriction on printing probe times only during initcalls, since
initcall_debug now continues to show driver timing info past the boot
phase.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r-- | drivers/base/dd.c | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1435d7281c66..6ea9c5cece71 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -53,7 +53,6 @@ static DEFINE_MUTEX(deferred_probe_mutex); | |||
53 | static LIST_HEAD(deferred_probe_pending_list); | 53 | static LIST_HEAD(deferred_probe_pending_list); |
54 | static LIST_HEAD(deferred_probe_active_list); | 54 | static LIST_HEAD(deferred_probe_active_list); |
55 | static atomic_t deferred_trigger_count = ATOMIC_INIT(0); | 55 | static atomic_t deferred_trigger_count = ATOMIC_INIT(0); |
56 | static bool initcalls_done; | ||
57 | 56 | ||
58 | /* | 57 | /* |
59 | * In some cases, like suspend to RAM or hibernation, It might be reasonable | 58 | * In some cases, like suspend to RAM or hibernation, It might be reasonable |
@@ -63,26 +62,6 @@ static bool initcalls_done; | |||
63 | static bool defer_all_probes; | 62 | static bool defer_all_probes; |
64 | 63 | ||
65 | /* | 64 | /* |
66 | * For initcall_debug, show the deferred probes executed in late_initcall | ||
67 | * processing. | ||
68 | */ | ||
69 | static void deferred_probe_debug(struct device *dev) | ||
70 | { | ||
71 | ktime_t calltime, delta, rettime; | ||
72 | unsigned long long duration; | ||
73 | |||
74 | printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev), | ||
75 | task_pid_nr(current)); | ||
76 | calltime = ktime_get(); | ||
77 | bus_probe_device(dev); | ||
78 | rettime = ktime_get(); | ||
79 | delta = ktime_sub(rettime, calltime); | ||
80 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | ||
81 | printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n", | ||
82 | dev_name(dev), duration); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * deferred_probe_work_func() - Retry probing devices in the active list. | 65 | * deferred_probe_work_func() - Retry probing devices in the active list. |
87 | */ | 66 | */ |
88 | static void deferred_probe_work_func(struct work_struct *work) | 67 | static void deferred_probe_work_func(struct work_struct *work) |
@@ -125,11 +104,7 @@ static void deferred_probe_work_func(struct work_struct *work) | |||
125 | device_pm_move_to_tail(dev); | 104 | device_pm_move_to_tail(dev); |
126 | 105 | ||
127 | dev_dbg(dev, "Retrying from deferred list\n"); | 106 | dev_dbg(dev, "Retrying from deferred list\n"); |
128 | if (initcall_debug && !initcalls_done) | 107 | bus_probe_device(dev); |
129 | deferred_probe_debug(dev); | ||
130 | else | ||
131 | bus_probe_device(dev); | ||
132 | |||
133 | mutex_lock(&deferred_probe_mutex); | 108 | mutex_lock(&deferred_probe_mutex); |
134 | 109 | ||
135 | put_device(dev); | 110 | put_device(dev); |
@@ -237,7 +212,6 @@ static int deferred_probe_initcall(void) | |||
237 | driver_deferred_probe_trigger(); | 212 | driver_deferred_probe_trigger(); |
238 | /* Sort as many dependencies as possible before exiting initcalls */ | 213 | /* Sort as many dependencies as possible before exiting initcalls */ |
239 | flush_work(&deferred_probe_work); | 214 | flush_work(&deferred_probe_work); |
240 | initcalls_done = true; | ||
241 | return 0; | 215 | return 0; |
242 | } | 216 | } |
243 | late_initcall(deferred_probe_initcall); | 217 | late_initcall(deferred_probe_initcall); |
@@ -527,6 +501,23 @@ done: | |||
527 | return ret; | 501 | return ret; |
528 | } | 502 | } |
529 | 503 | ||
504 | /* | ||
505 | * For initcall_debug, show the driver probe time. | ||
506 | */ | ||
507 | static int really_probe_debug(struct device *dev, struct device_driver *drv) | ||
508 | { | ||
509 | ktime_t calltime, delta, rettime; | ||
510 | int ret; | ||
511 | |||
512 | calltime = ktime_get(); | ||
513 | ret = really_probe(dev, drv); | ||
514 | rettime = ktime_get(); | ||
515 | delta = ktime_sub(rettime, calltime); | ||
516 | printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n", | ||
517 | dev_name(dev), ret, (s64) ktime_to_us(delta)); | ||
518 | return ret; | ||
519 | } | ||
520 | |||
530 | /** | 521 | /** |
531 | * driver_probe_done | 522 | * driver_probe_done |
532 | * Determine if the probe sequence is finished or not. | 523 | * Determine if the probe sequence is finished or not. |
@@ -585,7 +576,10 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) | |||
585 | pm_runtime_get_sync(dev->parent); | 576 | pm_runtime_get_sync(dev->parent); |
586 | 577 | ||
587 | pm_runtime_barrier(dev); | 578 | pm_runtime_barrier(dev); |
588 | ret = really_probe(dev, drv); | 579 | if (initcall_debug) |
580 | ret = really_probe_debug(dev, drv); | ||
581 | else | ||
582 | ret = really_probe(dev, drv); | ||
589 | pm_request_idle(dev); | 583 | pm_request_idle(dev); |
590 | 584 | ||
591 | if (dev->parent) | 585 | if (dev->parent) |