tracing/ftrace: Introduce the big kernel lock tracer
Subsystems (2)
PATCH RESEND v2 1/1 tracing/ftrace: Introduce the big kernel lock tracer
Introduce the Big Kernel Lock tracer.
This new tracer lets one to observe the latencies caused by the lock_kernel() function.
It captures the time when the task request the spinlock, the time when the spinlock is hold and the time it is released. This way we can measure the latency for a task that wait for this spinlock and the latency caused by the time this lock is hold.
I will surely add some improvements like:
_ Adding a stack trace to know which function locked or unlocked the kernel. _ Adding a script to get some statistics about this: which functions hold it often, which hold it for a long time and some other things....
Changes in this V2:
_ Correction of comments
_ Make static inline the insertion functions when the tracer is not configured _ Remove FTRACE and HAVE_FTRACE as dependencies. Bkl Tracer only depends on TRACING and
STACKTRACE for further features.
_ Use trace_assign_type instead of unsure cast
_ Several cleanups...
--- kernel/trace/Kconfig | 10 ++++++++++ kernel/trace/Makefile | 1 + kernel/trace/trace.h | 18 ++++++++++++++++++ lib/kernel_lock.c | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 2 deletions(-)
kernel/trace/Kconfig +10 -0
@@ -144,6 +144,16 @@ config STACK_TRACER This tracer records the max stack of the kernel, and displays it in debugfs/tracing/stack_trace +config BKL_TRACER + bool "Trace Big Kernel Lock latencies" + depends on DEBUG_KERNEL + select TRACING + select STACKTRACE + help + This tracer records the latencies issued by the Big Kernel Lock. + It traces the time when a task requests the bkl, the time when it + acquires it and the time when it releases it. + config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" depends on FTRACE
kernel/trace/Makefile +1 -0
@@ -24,5 +24,6 @@ obj-$(CONFIG_NOP_TRACER) += trace_nop.o obj-$(CONFIG_STACK_TRACER) += trace_stack.o obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o obj-$(CONFIG_BOOT_TRACER) += trace_boot.o +obj-$(CONFIG_BKL_TRACER) += trace_bkl.o libftrace-y := ftrace.o
kernel/trace/trace.h +18 -0
@@ -8,6 +8,7 @@#include <linux/ring_buffer.h> #include <linux/mmiotrace.h> #include <linux/ftrace.h> +#include <trace/bkl.h> enum trace_type { __TRACE_FIRST_TYPE =0 ,
@@ -22,6 +23,8 @@ enum trace_type {TRACE_MMIO_RW ,TRACE_MMIO_MAP ,TRACE_BOOT , +TRACE_BKL_ACQ , +TRACE_BKL_REL , __TRACE_LAST_TYPE };
@@ -117,6 +120,17 @@ struct trace_boot {struct boot_trace initcall; }; +/* Trace bkl entries */ +struct trace_bkl_acq { +struct trace_entry ent; +struct bkl_trace_acquire bkl_acq; +}; + +struct trace_bkl_rel { +struct trace_entry ent; +struct bkl_trace_release bkl_rel; +}; +/* * trace_flag_type is an enumeration that holds different * states when a trace occurs. These are:
@@ -217,6 +231,10 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \TRACE_MMIO_MAP ); \ IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \ + IF_ASSIGN(var, ent, struct trace_bkl_acq, \ +TRACE_BKL_ACQ ); \ + IF_ASSIGN(var, ent, struct trace_bkl_rel, \ +TRACE_BKL_REL ); \__ftrace_bad_type (); \ }while (0 )
lib/kernel_lock.c +34 -2
@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock'
@@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ()); +trace_bkl_release (&trace); +__unlock_kernel (); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif +/* * Getting the big kernel lock. *
@@ -117,7 +149,7 @@ void __lockfunc lock_kernel(void) {int depth = current->lock_depth+1 ;if (likely (!depth)) -__lock_kernel (); +lock_kernel_trace (); current->lock_depth = depth; }
@@ -125,7 +157,7 @@ void __lockfunc unlock_kernel(void) {BUG_ON (current->lock_depth <0 );if (likely (--current->lock_depth <0 )) -__unlock_kernel (); +unlock_kernel_trace (); }EXPORT_SYMBOL (lock_kernel);
Quoted 183 lines · Frederic Weisbecker
Introduce the Big Kernel Lock tracer.
This new tracer lets one to observe the latencies caused by thelock_kernel()function.
It captures the time when the task request the spinlock, the time when the spinlock is hold and the time it is released. This way we can measure the latency for a task that wait for this spinlock and the latency caused by the time this lock is hold.I will surely add some improvements like:
_ Adding a stack trace to know which function locked or unlocked the kernel. _ Adding a script to get some statistics about this: which functions hold it often, which hold it for a long time and some other things....
Changes in this V2:
_ Correction of comments
_ Make static inline the insertion functions when the tracer is not configured _ Remove FTRACE andHAVE_FTRACEas dependencies. Bkl Tracer only depends on TRACING and
STACKTRACE for further features.
_ Usetrace_assign_typeinstead of unsure cast
_ Several cleanups...Signed-off-by Frederic Weisbecker <[email protected]>Cc Steven Rostedt <[email protected]>--- kernel/trace/Kconfig | 10 ++++++++++ kernel/trace/Makefile | 1 + kernel/trace/trace.h | 18 ++++++++++++++++++ lib/kernel_lock.c | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 2 deletions(-)kernel/trace/Kconfig +10
-0@@ -144,6 +144,16 @@ config STACK_TRACER This tracer records the max stack of the kernel, and displays it in debugfs/tracing/stack_trace +config BKL_TRACER + bool "Trace Big Kernel Lock latencies" + depends on DEBUG_KERNEL + select TRACING + select STACKTRACE + help + This tracer records the latencies issued by the Big Kernel Lock. + It traces the time when a task requests the bkl, the time when it + acquires it and the time when it releases it. + config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" depends on FTRACEkernel/trace/Makefile +1
-0@@ -24,5 +24,6 @@ obj-$(CONFIG_NOP_TRACER) += trace_nop.o obj-$(CONFIG_STACK_TRACER) += trace_stack.o obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o obj-$(CONFIG_BOOT_TRACER) += trace_boot.o +obj-$(CONFIG_BKL_TRACER) += trace_bkl.o libftrace-y := ftrace.okernel/trace/trace.h +18
-0@@ -8,6 +8,7 @@#include <linux/ring_buffer.h> #include <linux/mmiotrace.h> #include <linux/ftrace.h> +#include <trace/bkl.h> enum trace_type { __TRACE_FIRST_TYPE =0 ,@@ -22,6 +23,8 @@ enum trace_type {TRACE_MMIO_RW ,TRACE_MMIO_MAP ,TRACE_BOOT , +TRACE_BKL_ACQ , +TRACE_BKL_REL , __TRACE_LAST_TYPE };@@ -117,6 +120,17 @@ struct trace_boot {struct boot_trace initcall; }; +/* Trace bkl entries */ +struct trace_bkl_acq { +struct trace_entry ent; +struct bkl_trace_acquire bkl_acq; +}; + +struct trace_bkl_rel { +struct trace_entry ent; +struct bkl_trace_release bkl_rel; +}; +/* * trace_flag_type is an enumeration that holds different * states when a trace occurs. These are: @@ -217,6 +231,10 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \TRACE_MMIO_MAP ); \ IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \ + IF_ASSIGN(var, ent, struct trace_bkl_acq, \ +TRACE_BKL_ACQ ); \ + IF_ASSIGN(var, ent, struct trace_bkl_rel, \ +TRACE_BKL_REL ); \__ftrace_bad_type (); \ }while (0 )lib/kernel_lock.c +34
-2@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock' @@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ()); +trace_bkl_release (&trace); +__unlock_kernel (); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif +/* * Getting the big kernel lock. * @@ -117,7 +149,7 @@ void __lockfunc lock_kernel(void) {int depth = current->lock_depth+1 ;if (likely (!depth)) -__lock_kernel (); +lock_kernel_trace (); current->lock_depth = depth; }@@ -125,7 +157,7 @@ void __lockfunc unlock_kernel(void) {BUG_ON (current->lock_depth <0 );if (likely (--current->lock_depth <0 )) -__unlock_kernel (); +unlock_kernel_trace (); }EXPORT_SYMBOL (lock_kernel);
Quoted 175 lines · Frederic Weisbecker
Introduce the Big Kernel Lock tracer.
This new tracer lets one to observe the latencies caused by thelock_kernel()function.
It captures the time when the task request the spinlock, the time when the spinlock is hold and the time it is released. This way we can measure the latency for a task that wait for this spinlock and the latency caused by the time this lock is hold.I will surely add some improvements like:
_ Adding a stack trace to know which function locked or unlocked the kernel. _ Adding a script to get some statistics about this: which functions hold it often, which hold it for a long time and some other things....
Changes in this V2:
_ Correction of comments
_ Make static inline the insertion functions when the tracer is not configured _ Remove FTRACE andHAVE_FTRACEas dependencies. Bkl Tracer only depends on TRACING and
STACKTRACE for further features.
_ Usetrace_assign_typeinstead of unsure cast
_ Several cleanups...Signed-off-by Frederic Weisbecker <[email protected]>Cc Steven Rostedt <[email protected]>--- kernel/trace/Kconfig | 10 ++++++++++ kernel/trace/Makefile | 1 + kernel/trace/trace.h | 18 ++++++++++++++++++ lib/kernel_lock.c | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 63 insertions(+), 2 deletions(-)kernel/trace/Kconfig +10
-0@@ -144,6 +144,16 @@ config STACK_TRACER This tracer records the max stack of the kernel, and displays it in debugfs/tracing/stack_trace +config BKL_TRACER + bool "Trace Big Kernel Lock latencies" + depends on DEBUG_KERNEL + select TRACING + select STACKTRACE + help + This tracer records the latencies issued by the Big Kernel Lock. + It traces the time when a task requests the bkl, the time when it + acquires it and the time when it releases it. + config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" depends on FTRACEkernel/trace/Makefile +1
-0@@ -24,5 +24,6 @@ obj-$(CONFIG_NOP_TRACER) += trace_nop.o obj-$(CONFIG_STACK_TRACER) += trace_stack.o obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o obj-$(CONFIG_BOOT_TRACER) += trace_boot.o +obj-$(CONFIG_BKL_TRACER) += trace_bkl.o libftrace-y := ftrace.okernel/trace/trace.h +18
-0@@ -8,6 +8,7 @@#include <linux/ring_buffer.h> #include <linux/mmiotrace.h> #include <linux/ftrace.h> +#include <trace/bkl.h> enum trace_type { __TRACE_FIRST_TYPE =0 ,@@ -22,6 +23,8 @@ enum trace_type {TRACE_MMIO_RW ,TRACE_MMIO_MAP ,TRACE_BOOT , +TRACE_BKL_ACQ , +TRACE_BKL_REL , __TRACE_LAST_TYPE };@@ -117,6 +120,17 @@ struct trace_boot {struct boot_trace initcall; }; +/* Trace bkl entries */ +struct trace_bkl_acq { +struct trace_entry ent; +struct bkl_trace_acquire bkl_acq; +}; + +struct trace_bkl_rel { +struct trace_entry ent; +struct bkl_trace_release bkl_rel; +}; +/* * trace_flag_type is an enumeration that holds different * states when a trace occurs. These are: @@ -217,6 +231,10 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \TRACE_MMIO_MAP ); \ IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \ + IF_ASSIGN(var, ent, struct trace_bkl_acq, \ +TRACE_BKL_ACQ ); \ + IF_ASSIGN(var, ent, struct trace_bkl_rel, \ +TRACE_BKL_REL ); \__ftrace_bad_type (); \ }while (0 )lib/kernel_lock.c +33
-1@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock' @@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ()); +trace_bkl_release (&trace); +__unlock_kernel (); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif +/* * Getting the big kernel lock. * @@ -117,7 +149,7 @@ void __lockfunc lock_kernel(void) {int depth = current->lock_depth+1 ;if (likely (!depth)) -__lock_kernel (); +lock_kernel_trace (); current->lock_depth = depth; }
lib/kernel_lock.c void __lockfunc unlock_kernel(void) · line 163
Quoted 8 lines
lib/kernel_lock.c +1
-1@@ -125,7 +157,7 @@ void __lockfunc unlock_kernel(void) {BUG_ON (current->lock_depth <0 );if (likely (--current->lock_depth <0 )) -__unlock_kernel (); +unlock_kernel_trace (); }EXPORT_SYMBOL (lock_kernel);
Sorry one part of the patch was missing.
Here is the entire patch:
--- kernel/trace/Kconfig | 10 +++ kernel/trace/Makefile | 1 + kernel/trace/trace.h | 18 +++++ kernel/trace/trace_bkl.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++ lib/kernel_lock.c | 36 +++++++++- 5 files changed, 237 insertions(+), 2 deletions(-)
kernel/trace/Kconfig +10 -0
@@ -144,6 +144,16 @@ config STACK_TRACER This tracer records the max stack of the kernel, and displays it in debugfs/tracing/stack_trace +config BKL_TRACER + bool "Trace Big Kernel Lock latencies" + depends on DEBUG_KERNEL + select TRACING + select STACKTRACE + help + This tracer records the latencies issued by the Big Kernel Lock. + It traces the time when a task requests the bkl, the time when it + acquires it and the time when it releases it. + config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" depends on FTRACE
kernel/trace/Makefile +1 -0
@@ -24,5 +24,6 @@ obj-$(CONFIG_NOP_TRACER) += trace_nop.o obj-$(CONFIG_STACK_TRACER) += trace_stack.o obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o obj-$(CONFIG_BOOT_TRACER) += trace_boot.o +obj-$(CONFIG_BKL_TRACER) += trace_bkl.o libftrace-y := ftrace.o
kernel/trace/trace.h +18 -0
@@ -8,6 +8,7 @@#include <linux/ring_buffer.h> #include <linux/mmiotrace.h> #include <linux/ftrace.h> +#include <trace/bkl.h> enum trace_type { __TRACE_FIRST_TYPE =0 ,
@@ -22,6 +23,8 @@ enum trace_type {TRACE_MMIO_RW ,TRACE_MMIO_MAP ,TRACE_BOOT , +TRACE_BKL_ACQ , +TRACE_BKL_REL , __TRACE_LAST_TYPE };
@@ -117,6 +120,17 @@ struct trace_boot {struct boot_trace initcall; }; +/* Trace bkl entries */ +struct trace_bkl_acq { +struct trace_entry ent; +struct bkl_trace_acquire bkl_acq; +}; + +struct trace_bkl_rel { +struct trace_entry ent; +struct bkl_trace_release bkl_rel; +}; +/* * trace_flag_type is an enumeration that holds different * states when a trace occurs. These are:
@@ -217,6 +231,10 @@ extern void __ftrace_bad_type(void); IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \TRACE_MMIO_MAP ); \ IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \ + IF_ASSIGN(var, ent, struct trace_bkl_acq, \ +TRACE_BKL_ACQ ); \ + IF_ASSIGN(var, ent, struct trace_bkl_rel, \ +TRACE_BKL_REL ); \__ftrace_bad_type (); \ }while (0 )
kernel/trace/trace_bkl.c new file +174 -0
174 lines not on this page · raw message
lib/kernel_lock.c +34 -2
@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock'
@@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ()); +trace_bkl_release (&trace); +__unlock_kernel (); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif +/* * Getting the big kernel lock. *
@@ -117,7 +149,7 @@ void __lockfunc lock_kernel(void) {int depth = current->lock_depth+1 ;if (likely (!depth)) -__lock_kernel (); +lock_kernel_trace (); current->lock_depth = depth; }
@@ -125,7 +157,7 @@ void __lockfunc unlock_kernel(void) {BUG_ON (current->lock_depth <0 );if (likely (--current->lock_depth <0 )) -__unlock_kernel (); +unlock_kernel_trace (); }EXPORT_SYMBOL (lock_kernel);
Quoted 36 lines · Frederic Weisbecker
lib/kernel_lock.c +21
-0@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock' @@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ());
lib/kernel_lock.c static inline void __unlock_kernel(void) · line 140
Quoted 10 lines
lib/kernel_lock.c +10
-0+trace_bkl_release (&trace); + __unlock_kernel(); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif
hm, this looks a bit ugly.
are you aware of the tip/kill-the-BKL branch? It's an old-ish but otherwise sane branch that needs some refreshing (hence it's not part of tip/master).
Once we have that "kill the BKL by turning it into a mutex" feature alive, and have fixed the places that rely on odd properties of the BKL, the BKL becomes just an ordinary mutex and we could trace its latencies via the existing lockdep/lockstat callbacks.
and we could trace all the other mutexes as well.
Ingo
2008/10/27 Ingo Molnar <[email protected]>:
Quoted 56 lines · Frederic Weisbecker
Quoted 37 lines
lib/kernel_lock.c +21
-0@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock' @@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ());lib/kernel_lock.c static inline void __unlock_kernel(void) · line 140
Quoted 10 lines
lib/kernel_lock.c +10
-0+trace_bkl_release (&trace); + __unlock_kernel(); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif hm, this looks a bit ugly.
are you aware of the tip/kill-the-BKL branch? It's an old-ish but otherwise sane branch that needs some refreshing (hence it's not part of tip/master).
Quoted 6 lines
Once we have that "kill the BKL by turning it into a mutex" feature alive, and have fixed the places that rely on odd properties of the BKL, the BKL becomes just an ordinary mutex and we could trace its latencies via the existing lockdep/lockstat callbacks.
and we could trace all the other mutexes as well.
No problem, we can forget about it. My goal was to produce some statistics to locate the points that
most often hold the bkl. That would help to define some priorities on which bkl holding is to remove first.
But if that would be better to rather invest the time on the kill-the-bkl tree (which I thought was dead), so I would be pleased to help.
Quoted 65 lines · Frédéric Weisbecker
2008/10/27 Ingo Molnar <[email protected]>:
Quoted 56 lines · Frederic Weisbecker
Quoted 37 lines
lib/kernel_lock.c +21
-0@@ -9,6 +9,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/semaphore.h> +#include <trace/bkl.h> /* * The 'big kernel lock' @@ -107,6 +108,37 @@ static inline void __unlock_kernel(void)preempt_enable (); } +#ifdef CONFIG_BKL_TRACER +static void lock_kernel_trace (void ) +{ +int cpu; +struct bkl_trace_acquire trace; + +preempt_disable (); + cpu =raw_smp_processor_id (); +preempt_enable (); + + trace.acquire_req_time =cpu_clock (cpu); +__lock_kernel (); + trace.acquire_time =cpu_clock (cpu); +trace_bkl_acquire (&trace); +} + +static void unlock_kernel_trace (void ) +{ +struct bkl_trace_release trace; + trace.release_time =cpu_clock (raw_smp_processor_id ());lib/kernel_lock.c static inline void __unlock_kernel(void) · line 140
Quoted 10 lines
lib/kernel_lock.c +10
-0+trace_bkl_release (&trace); + __unlock_kernel(); +} + +#else + +#define lock_kernel_trace () __lock_kernel() +#define unlock_kernel_trace () __unlock_kernel() + +#endif hm, this looks a bit ugly.
are you aware of the tip/kill-the-BKL branch? It's an old-ish but otherwise sane branch that needs some refreshing (hence it's not part of tip/master).
Quoted 6 lines
Once we have that "kill the BKL by turning it into a mutex" feature alive, and have fixed the places that rely on odd properties of the BKL, the BKL becomes just an ordinary mutex and we could trace its latencies via the existing lockdep/lockstat callbacks.
and we could trace all the other mutexes as well.
Quoted 8 lines
No problem, we can forget about it. My goal was to produce some statistics to locate the points that most often hold the bkl. That would help to define some priorities on which bkl holding is to remove first.
But if that would be better to rather invest the time on the kill-the-bkl tree (which I thought was dead), so I would be pleased to help.
the kill-the-BKL tree is not dead, just inactive. Looking for a brave volunteer to merge it up to latest, to boot it with CONFIG_PROVE_LOCKING=y and to have a good look at all the BKL locking output that lockdep might disable.
Ingo