aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2017-07-25 19:31:59 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-08-03 20:48:49 -0400
commit1f5000bd8afab0ceed58c67f673250b864e5a9c9 (patch)
tree97453ce50ef72db30f080237cd6c77035d34adbe
parent1af824f085e813e06548212b18bbc788b16f60e6 (diff)
initcall_debug: add deferred probe times
initcall_debug attributes all deferred device probe retries for the late_initcall level to function deferred_probe_initcall. Add logs of the individual device probe routines called, to identify which drivers are executing for how long during the initcall path. Deferred probes that occur after initcall processing are not shown. Example log messages added: [ 0.505119] deferred probe my-sound-device @ 6 [ 0.517656] deferred probe my-sound-device returned after 1227 usecs Signed-off-by: Todd Poynor <toddpoynor@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/base/dd.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index c17fefc77345..ad44b40fe284 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
23#include <linux/init.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/kthread.h> 25#include <linux/kthread.h>
25#include <linux/wait.h> 26#include <linux/wait.h>
@@ -53,6 +54,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
53static LIST_HEAD(deferred_probe_pending_list); 54static LIST_HEAD(deferred_probe_pending_list);
54static LIST_HEAD(deferred_probe_active_list); 55static LIST_HEAD(deferred_probe_active_list);
55static atomic_t deferred_trigger_count = ATOMIC_INIT(0); 56static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
57static bool initcalls_done;
56 58
57/* 59/*
58 * In some cases, like suspend to RAM or hibernation, It might be reasonable 60 * In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -62,6 +64,26 @@ static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
62static bool defer_all_probes; 64static bool defer_all_probes;
63 65
64/* 66/*
67 * For initcall_debug, show the deferred probes executed in late_initcall
68 * processing.
69 */
70static void deferred_probe_debug(struct device *dev)
71{
72 ktime_t calltime, delta, rettime;
73 unsigned long long duration;
74
75 printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev),
76 task_pid_nr(current));
77 calltime = ktime_get();
78 bus_probe_device(dev);
79 rettime = ktime_get();
80 delta = ktime_sub(rettime, calltime);
81 duration = (unsigned long long) ktime_to_ns(delta) >> 10;
82 printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n",
83 dev_name(dev), duration);
84}
85
86/*
65 * deferred_probe_work_func() - Retry probing devices in the active list. 87 * deferred_probe_work_func() - Retry probing devices in the active list.
66 */ 88 */
67static void deferred_probe_work_func(struct work_struct *work) 89static void deferred_probe_work_func(struct work_struct *work)
@@ -106,7 +128,10 @@ static void deferred_probe_work_func(struct work_struct *work)
106 device_pm_unlock(); 128 device_pm_unlock();
107 129
108 dev_dbg(dev, "Retrying from deferred list\n"); 130 dev_dbg(dev, "Retrying from deferred list\n");
109 bus_probe_device(dev); 131 if (initcall_debug && !initcalls_done)
132 deferred_probe_debug(dev);
133 else
134 bus_probe_device(dev);
110 135
111 mutex_lock(&deferred_probe_mutex); 136 mutex_lock(&deferred_probe_mutex);
112 137
@@ -215,6 +240,7 @@ static int deferred_probe_initcall(void)
215 driver_deferred_probe_trigger(); 240 driver_deferred_probe_trigger();
216 /* Sort as many dependencies as possible before exiting initcalls */ 241 /* Sort as many dependencies as possible before exiting initcalls */
217 flush_work(&deferred_probe_work); 242 flush_work(&deferred_probe_work);
243 initcalls_done = true;
218 return 0; 244 return 0;
219} 245}
220late_initcall(deferred_probe_initcall); 246late_initcall(deferred_probe_initcall);