summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2017-10-27 18:57:20 +0200
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2017-10-27 18:57:20 +0200
commitafcdea842e6a692d5bfcae155159b9453743f84a (patch)
tree4b16c43fb518f00d930a6b7f8df51990296ec11c
parent7e93d4bef01b7cb775cd9ec56668e5fb40be3eb8 (diff)
downloadlinux-rt-4.13.10-rt3-patches.tar.gz
[ANNOUNCE] v4.13.10-rt3v4.13.10-rt3-patches
Dear RT folks! I'm pleased to announce the v4.13.10-rt3 patch set. Changes since v4.13.10-rt2: - A dcache related live lock could occur. The writer could get preempted within the critical section and the reader would spin to see the update completed. This update would never complete if the writer was preempted by a reader with a higher priority. Reported by Oleg Karfich. - The tpm_tis driver can cause latency spikes (~400us) after multiple writes to the chip is followed by a read operation. This read causes a flush of all the cached writes to the chip and is blocking the CPU until the operation completes. Reported and patched by Haris Okanovic. - The upgrade to v4.13-RT broke the zram driver. Patched by Mike Galbraith. - Tom Zanussi's "tracing: Inter-event (e.g. latency) support" patchset has been update to v3. - The static SRCU notifier wasn't compiling with SRCU_TINY. Reported by kbuild test robot. The delta patch appended at the bottom of this email contains all the changes except tracing due to the size of the tracing delta. For complete diff please visit https://git.kernel.org/rt/linux-rt-devel/d/v4.13.10-rt3/v4.13.10-rt2 Known issues None The delta patch against v4.13.10-rt2 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.13/incr/patch-4.13.10-rt2-rt3.patch.xz You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.13.10-rt3 The RT patch against v4.13.10 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.13/older/patch-4.13.10-rt3.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.13/older/patches-4.13.10-rt3.tar.xz Sebastian Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/0001-tracing-Steve-s-unofficial-trace_recursive_lock-patc.patch (renamed from patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch)11
-rw-r--r--patches/0002-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch188
-rw-r--r--patches/0003-tracing-Exclude-generic-fields-from-histograms.patch (renamed from patches/0001-tracing-Exclude-generic-fields-from-histograms.patch)4
-rw-r--r--patches/0004-tracing-Remove-lookups-from-tracing_map-hitcount.patch (renamed from patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch)24
-rw-r--r--patches/0005-tracing-Increase-tracing-map-KEYS_MAX-size.patch (renamed from patches/0011-tracing-Increase-tracing-map-KEYS_MAX-size.patch)4
-rw-r--r--patches/0006-tracing-Make-traceprobe-parsing-code-reusable.patch (renamed from patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch)8
-rw-r--r--patches/0007-tracing-Clean-up-hist_field_flags-enum.patch43
-rw-r--r--patches/0008-tracing-Add-hist_field_name-accessor.patch (renamed from patches/0004-tracing-Add-hist_field_name-accessor.patch)22
-rw-r--r--patches/0009-tracing-Reimplement-log2.patch (renamed from patches/0005-tracing-Reimplement-log2.patch)12
-rw-r--r--patches/0010-tracing-Add-support-to-detect-and-avoid-duplicates.patch (renamed from patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch)33
-rw-r--r--patches/0011-tracing-Remove-code-which-merges-duplicates.patch (renamed from patches/0003-tracing-Remove-code-which-merges-duplicates.patch)14
-rw-r--r--patches/0012-ring-buffer-Add-interface-for-setting-absolute-time-.patch (renamed from patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch)7
-rw-r--r--patches/0013-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch (renamed from patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch)20
-rw-r--r--patches/0014-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch (renamed from patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch)4
-rw-r--r--patches/0015-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch (renamed from patches/0010-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch)4
-rw-r--r--patches/0016-tracing-Break-out-hist-trigger-assignment-parsing.patch (renamed from patches/0012-tracing-Break-out-hist-trigger-assignment-parsing.patch)41
-rw-r--r--patches/0017-tracing-Add-hist-trigger-timestamp-support.patch (renamed from patches/0014-tracing-Add-hist-trigger-timestamp-support.patch)41
-rw-r--r--patches/0018-tracing-Add-per-element-variable-support-to-tracing_.patch (renamed from patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch)4
-rw-r--r--patches/0019-tracing-Add-hist_data-member-to-hist_field.patch (renamed from patches/0016-tracing-Add-hist_data-member-to-hist_field.patch)16
-rw-r--r--patches/0020-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch (renamed from patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch)18
-rw-r--r--patches/0021-tracing-Add-variable-support-to-hist-triggers.patch (renamed from patches/0018-tracing-Add-variable-support-to-hist-triggers.patch)85
-rw-r--r--patches/0022-tracing-Account-for-variables-in-named-trigger-compa.patch (renamed from patches/0019-tracing-Account-for-variables-in-named-trigger-compa.patch)19
-rw-r--r--patches/0023-tracing-Move-get_hist_field_flags.patch73
-rw-r--r--patches/0024-tracing-Add-simple-expression-support-to-hist-trigge.patch (renamed from patches/0020-tracing-Add-simple-expression-support-to-hist-trigge.patch)91
-rw-r--r--patches/0025-tracing-Add-support-for-dynamic-tracepoints.patch78
-rw-r--r--patches/0025-tracing-Generalize-per-element-hist-trigger-data.patch (renamed from patches/0021-tracing-Generalize-per-element-hist-trigger-data.patch)40
-rw-r--r--patches/0026-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch (renamed from patches/0022-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch)12
-rw-r--r--patches/0027-tracing-Add-hist_field-type-field.patch (renamed from patches/0023-tracing-Add-hist_field-type-field.patch)18
-rw-r--r--patches/0028-tracing-Add-variable-reference-handling-to-hist-trig.patch (renamed from patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch)73
-rw-r--r--patches/0029-tracing-Add-hist-trigger-action-hook.patch (renamed from patches/0026-tracing-Add-hist-trigger-action-hook.patch)50
-rw-r--r--patches/0030-tracing-Add-support-for-synthetic-events.patch (renamed from patches/0027-tracing-Add-support-for-synthetic-events.patch)86
-rw-r--r--patches/0031-tracing-Add-support-for-field-variables.patch (renamed from patches/0028-tracing-Add-support-for-field-variables.patch)81
-rw-r--r--patches/0032-tracing-Add-onmatch-hist-trigger-action-support.patch (renamed from patches/0029-tracing-Add-onmatch-hist-trigger-action-support.patch)82
-rw-r--r--patches/0033-tracing-Add-onmax-hist-trigger-action-support.patch (renamed from patches/0030-tracing-Add-onmax-hist-trigger-action-support.patch)77
-rw-r--r--patches/0034-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch (renamed from patches/0031-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch)26
-rw-r--r--patches/0035-tracing-Add-cpu-field-for-hist-triggers.patch (renamed from patches/0032-tracing-Add-cpu-field-for-hist-triggers.patch)56
-rw-r--r--patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch95
-rw-r--r--patches/0036-tracing-Add-hist-trigger-support-for-variable-refere.patch (renamed from patches/0033-tracing-Add-hist-trigger-support-for-variable-refere.patch)38
-rw-r--r--patches/0037-tracing-Add-last-error-error-facility-for-hist-trigg.patch (renamed from patches/0034-tracing-Add-last-error-error-facility-for-hist-trigg.patch)124
-rw-r--r--patches/0038-tracing-Add-inter-event-hist-trigger-Documentation.patch (renamed from patches/0037-tracing-Add-inter-event-hist-trigger-Documentation.patch)4
-rw-r--r--patches/0039-tracing-Make-tracing_set_clock-non-static.patch (renamed from patches/0038-tracing-Make-tracing_set_clock-non-static.patch)4
-rw-r--r--patches/0040-tracing-Add-a-clock-attribute-for-hist-triggers.patch (renamed from patches/0039-tracing-Add-a-clock-attribute-for-hist-triggers.patch)39
-rw-r--r--patches/0041-tracing-Increase-trace_recursive_lock-limit-for-synt.patch43
-rw-r--r--patches/0042-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch27
-rw-r--r--patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch2
-rw-r--r--patches/fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch118
-rw-r--r--patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch4
-rw-r--r--patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch8
-rw-r--r--patches/genirq-update-irq_set_irqchip_state-documentation.patch2
-rw-r--r--patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch2
-rw-r--r--patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch4
-rw-r--r--patches/kernel-SRCU-provide-a-static-initializer.patch40
-rw-r--r--patches/localversion.patch2
-rw-r--r--patches/random-make-it-work-on-rt.patch6
-rw-r--r--patches/series86
-rw-r--r--patches/tpm_tis-fix-stall-after-iowrite-s.patch77
56 files changed, 1302 insertions, 888 deletions
diff --git a/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch b/patches/0001-tracing-Steve-s-unofficial-trace_recursive_lock-patc.patch
index 653a9a63ae59..842b41320028 100644
--- a/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch
+++ b/patches/0001-tracing-Steve-s-unofficial-trace_recursive_lock-patc.patch
@@ -1,7 +1,7 @@
From: Steven Rostedt <rostedt@goodmis.org>
-Date: Fri, 8 Sep 2017 16:27:56 -0400
-Subject: [PATCH] tracing: Add trace_event_buffer_reserve() variant that allows
- recursion
+Date: Fri, 22 Sep 2017 14:58:15 -0500
+Subject: [PATCH 01/42] tracing: Steve's unofficial trace_recursive_lock()
+ patch
On Tue, 5 Sep 2017 16:57:52 -0500
Tom Zanussi <tom.zanussi@linux.intel.com> wrote:
@@ -30,7 +30,6 @@ you can include it in your series.
-- Steve
-Link: https://lkml.kernel.org/r/20170908162756.74c6be8a@gandalf.local.home
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/trace/ring_buffer.c | 66 ++++++++++++---------------------------------
@@ -38,7 +37,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
-@@ -2582,61 +2582,29 @@ rb_wakeups(struct ring_buffer *buffer, s
+@@ -2538,61 +2538,29 @@ rb_wakeups(struct ring_buffer *buffer, s
* The lock and unlock are done within a preempt disable section.
* The current_context per_cpu variable can only be modified
* by the current task between lock and unlock. But it can
@@ -115,7 +114,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return 0;
}
-@@ -2644,7 +2612,9 @@ trace_recursive_lock(struct ring_buffer_
+@@ -2600,7 +2568,9 @@ trace_recursive_lock(struct ring_buffer_
static __always_inline void
trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer)
{
diff --git a/patches/0002-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch b/patches/0002-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch
new file mode 100644
index 000000000000..32fee49967ff
--- /dev/null
+++ b/patches/0002-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch
@@ -0,0 +1,188 @@
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Fri, 22 Sep 2017 14:58:16 -0500
+Subject: [PATCH 02/42] tracing: Reverse the order of trace_types_lock and
+ event_mutex
+
+In order to make future changes where we need to call
+tracing_set_clock() from within an event command, the order of
+trace_types_lock and event_mutex must be reversed, as the event command
+will hold event_mutex and the trace_types_lock is taken from within
+tracing_set_clock().
+
+Requested-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/trace/trace.c | 5 +++++
+ kernel/trace/trace_events.c | 31 +++++++++++++++----------------
+ 2 files changed, 20 insertions(+), 16 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -7677,6 +7677,7 @@ static int instance_mkdir(const char *na
+ struct trace_array *tr;
+ int ret;
+
++ mutex_lock(&event_mutex);
+ mutex_lock(&trace_types_lock);
+
+ ret = -EEXIST;
+@@ -7732,6 +7733,7 @@ static int instance_mkdir(const char *na
+ list_add(&tr->list, &ftrace_trace_arrays);
+
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ return 0;
+
+@@ -7743,6 +7745,7 @@ static int instance_mkdir(const char *na
+
+ out_unlock:
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ return ret;
+
+@@ -7755,6 +7758,7 @@ static int instance_rmdir(const char *na
+ int ret;
+ int i;
+
++ mutex_lock(&event_mutex);
+ mutex_lock(&trace_types_lock);
+
+ ret = -ENODEV;
+@@ -7800,6 +7804,7 @@ static int instance_rmdir(const char *na
+
+ out_unlock:
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ return ret;
+ }
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -1406,8 +1406,8 @@ static int subsystem_open(struct inode *
+ return -ENODEV;
+
+ /* Make sure the system still exists */
+- mutex_lock(&trace_types_lock);
+ mutex_lock(&event_mutex);
++ mutex_lock(&trace_types_lock);
+ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+ list_for_each_entry(dir, &tr->systems, list) {
+ if (dir == inode->i_private) {
+@@ -1421,8 +1421,8 @@ static int subsystem_open(struct inode *
+ }
+ }
+ exit_loop:
+- mutex_unlock(&event_mutex);
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ if (!system)
+ return -ENODEV;
+@@ -2290,15 +2290,15 @@ static void __add_event_to_tracers(struc
+ int trace_add_event_call(struct trace_event_call *call)
+ {
+ int ret;
+- mutex_lock(&trace_types_lock);
+ mutex_lock(&event_mutex);
++ mutex_lock(&trace_types_lock);
+
+ ret = __register_event(call, NULL);
+ if (ret >= 0)
+ __add_event_to_tracers(call);
+
+- mutex_unlock(&event_mutex);
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+ return ret;
+ }
+
+@@ -2352,13 +2352,13 @@ int trace_remove_event_call(struct trace
+ {
+ int ret;
+
+- mutex_lock(&trace_types_lock);
+ mutex_lock(&event_mutex);
++ mutex_lock(&trace_types_lock);
+ down_write(&trace_event_sem);
+ ret = probe_remove_event_call(call);
+ up_write(&trace_event_sem);
+- mutex_unlock(&event_mutex);
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ return ret;
+ }
+@@ -2425,8 +2425,8 @@ static int trace_module_notify(struct no
+ {
+ struct module *mod = data;
+
+- mutex_lock(&trace_types_lock);
+ mutex_lock(&event_mutex);
++ mutex_lock(&trace_types_lock);
+ switch (val) {
+ case MODULE_STATE_COMING:
+ trace_module_add_events(mod);
+@@ -2435,8 +2435,8 @@ static int trace_module_notify(struct no
+ trace_module_remove_events(mod);
+ break;
+ }
+- mutex_unlock(&event_mutex);
+ mutex_unlock(&trace_types_lock);
++ mutex_unlock(&event_mutex);
+
+ return 0;
+ }
+@@ -2951,24 +2951,24 @@ create_event_toplevel_files(struct dentr
+ * creates the event hierachry in the @parent/events directory.
+ *
+ * Returns 0 on success.
++ *
++ * Must be called with event_mutex held.
+ */
+ int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr)
+ {
+ int ret;
+
+- mutex_lock(&event_mutex);
++ lockdep_assert_held(&event_mutex);
+
+ ret = create_event_toplevel_files(parent, tr);
+ if (ret)
+- goto out_unlock;
++ goto out;
+
+ down_write(&trace_event_sem);
+ __trace_add_event_dirs(tr);
+ up_write(&trace_event_sem);
+
+- out_unlock:
+- mutex_unlock(&event_mutex);
+-
++ out:
+ return ret;
+ }
+
+@@ -2997,9 +2997,10 @@ early_event_add_tracer(struct dentry *pa
+ return ret;
+ }
+
++/* Must be called with event_mutex held */
+ int event_trace_del_tracer(struct trace_array *tr)
+ {
+- mutex_lock(&event_mutex);
++ lockdep_assert_held(&event_mutex);
+
+ /* Disable any event triggers and associated soft-disabled events */
+ clear_event_triggers(tr);
+@@ -3020,8 +3021,6 @@ int event_trace_del_tracer(struct trace_
+
+ tr->event_dir = NULL;
+
+- mutex_unlock(&event_mutex);
+-
+ return 0;
+ }
+
diff --git a/patches/0001-tracing-Exclude-generic-fields-from-histograms.patch b/patches/0003-tracing-Exclude-generic-fields-from-histograms.patch
index b0e806b3df2e..38949c3f8b56 100644
--- a/patches/0001-tracing-Exclude-generic-fields-from-histograms.patch
+++ b/patches/0003-tracing-Exclude-generic-fields-from-histograms.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:13 -0500
-Subject: [PATCH 01/40] tracing: Exclude 'generic fields' from histograms
+Date: Fri, 22 Sep 2017 14:58:17 -0500
+Subject: [PATCH 03/42] tracing: Exclude 'generic fields' from histograms
There are a small number of 'generic fields' (comm/COMM/cpu/CPU) that
are found by trace_find_event_field() but are only meant for
diff --git a/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch b/patches/0004-tracing-Remove-lookups-from-tracing_map-hitcount.patch
index 24e4c9eb2a1c..7e5e851f6e37 100644
--- a/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch
+++ b/patches/0004-tracing-Remove-lookups-from-tracing_map-hitcount.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:48 -0500
-Subject: [PATCH 36/40] tracing: Remove lookups from tracing_map hitcount
+Date: Fri, 22 Sep 2017 14:58:18 -0500
+Subject: [PATCH 04/42] tracing: Remove lookups from tracing_map hitcount
Lookups inflate the hitcount, making it essentially useless. Only
inserts and updates should really affect the hitcount anyway, so
@@ -14,13 +14,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/tracing_map.c
+++ b/kernel/trace/tracing_map.c
-@@ -538,7 +538,8 @@ static inline struct tracing_map_elt *
- if (test_key && test_key == key_hash) {
- if (entry->val &&
- keys_match(key, entry->val->key, map->key_size)) {
-- atomic64_inc(&map->hits);
-+ if (!lookup_only)
-+ atomic64_inc(&map->hits);
- return entry->val;
- } else if (unlikely(!entry->val)) {
- /*
+@@ -428,7 +428,8 @@ static inline struct tracing_map_elt *
+
+ if (test_key && test_key == key_hash && entry->val &&
+ keys_match(key, entry->val->key, map->key_size)) {
+- atomic64_inc(&map->hits);
++ if (!lookup_only)
++ atomic64_inc(&map->hits);
+ return entry->val;
+ }
+
diff --git a/patches/0011-tracing-Increase-tracing-map-KEYS_MAX-size.patch b/patches/0005-tracing-Increase-tracing-map-KEYS_MAX-size.patch
index 670eef00a2e4..a956e8bc8361 100644
--- a/patches/0011-tracing-Increase-tracing-map-KEYS_MAX-size.patch
+++ b/patches/0005-tracing-Increase-tracing-map-KEYS_MAX-size.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:23 -0500
-Subject: [PATCH 11/40] tracing: Increase tracing map KEYS_MAX size
+Date: Fri, 22 Sep 2017 14:58:19 -0500
+Subject: [PATCH 05/42] tracing: Increase tracing map KEYS_MAX size
The current default for the number of subkeys in a compound key is 2,
which is too restrictive. Increase it to a more realistic value of 3.
diff --git a/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch b/patches/0006-tracing-Make-traceprobe-parsing-code-reusable.patch
index 4c1702e3367d..0b0687f683a4 100644
--- a/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch
+++ b/patches/0006-tracing-Make-traceprobe-parsing-code-reusable.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:25 -0500
-Subject: [PATCH 13/40] tracing: Make traceprobe parsing code reusable
+Date: Fri, 22 Sep 2017 14:58:20 -0500
+Subject: [PATCH 06/42] tracing: Make traceprobe parsing code reusable
traceprobe_probes_write() and traceprobe_command() actually contain
nothing that ties them to kprobes - the code is generically useful for
@@ -24,7 +24,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
-@@ -8304,6 +8304,92 @@ void ftrace_dump(enum ftrace_dump_mode o
+@@ -8271,6 +8271,92 @@ void ftrace_dump(enum ftrace_dump_mode o
}
EXPORT_SYMBOL_GPL(ftrace_dump);
@@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
int ring_buf_size;
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
-@@ -1755,6 +1755,13 @@ void trace_printk_start_comm(void);
+@@ -1751,6 +1751,13 @@ void trace_printk_start_comm(void);
int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);
diff --git a/patches/0007-tracing-Clean-up-hist_field_flags-enum.patch b/patches/0007-tracing-Clean-up-hist_field_flags-enum.patch
new file mode 100644
index 000000000000..c7a61b36952f
--- /dev/null
+++ b/patches/0007-tracing-Clean-up-hist_field_flags-enum.patch
@@ -0,0 +1,43 @@
+From: Tom Zanussi <tom.zanussi@linux.intel.com>
+Date: Fri, 22 Sep 2017 14:58:21 -0500
+Subject: [PATCH 07/42] tracing: Clean up hist_field_flags enum
+
+As we add more flags, specifying explicit integers for the flag values
+becomes more unwieldy and error-prone - switch them over to left-shift
+values.
+
+Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/trace/trace_events_hist.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -110,16 +110,16 @@ DEFINE_HIST_FIELD_FN(u8);
+ #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
+
+ enum hist_field_flags {
+- HIST_FIELD_FL_HITCOUNT = 1,
+- HIST_FIELD_FL_KEY = 2,
+- HIST_FIELD_FL_STRING = 4,
+- HIST_FIELD_FL_HEX = 8,
+- HIST_FIELD_FL_SYM = 16,
+- HIST_FIELD_FL_SYM_OFFSET = 32,
+- HIST_FIELD_FL_EXECNAME = 64,
+- HIST_FIELD_FL_SYSCALL = 128,
+- HIST_FIELD_FL_STACKTRACE = 256,
+- HIST_FIELD_FL_LOG2 = 512,
++ HIST_FIELD_FL_HITCOUNT = 1 << 0,
++ HIST_FIELD_FL_KEY = 1 << 1,
++ HIST_FIELD_FL_STRING = 1 << 2,
++ HIST_FIELD_FL_HEX = 1 << 3,
++ HIST_FIELD_FL_SYM = 1 << 4,
++ HIST_FIELD_FL_SYM_OFFSET = 1 << 5,
++ HIST_FIELD_FL_EXECNAME = 1 << 6,
++ HIST_FIELD_FL_SYSCALL = 1 << 7,
++ HIST_FIELD_FL_STACKTRACE = 1 << 8,
++ HIST_FIELD_FL_LOG2 = 1 << 9,
+ };
+
+ struct hist_trigger_attrs {
diff --git a/patches/0004-tracing-Add-hist_field_name-accessor.patch b/patches/0008-tracing-Add-hist_field_name-accessor.patch
index 95d05b5d1e03..e3c77814d9f2 100644
--- a/patches/0004-tracing-Add-hist_field_name-accessor.patch
+++ b/patches/0008-tracing-Add-hist_field_name-accessor.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:16 -0500
-Subject: [PATCH 04/40] tracing: Add hist_field_name() accessor
+Date: Fri, 22 Sep 2017 14:58:22 -0500
+Subject: [PATCH 08/42] tracing: Add hist_field_name() accessor
In preparation for hist_fields that won't be strictly based on
trace_event_fields, add a new hist_field_name() accessor to allow that
@@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)
{
hist_field_fn_t fn = NULL;
-@@ -642,7 +659,6 @@ static int is_descending(const char *str
+@@ -653,7 +670,6 @@ static int is_descending(const char *str
static int create_sort_keys(struct hist_trigger_data *hist_data)
{
char *fields_str = hist_data->attrs->sort_key_str;
@@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct tracing_map_sort_key *sort_key;
int descending, ret = 0;
unsigned int i, j;
-@@ -659,7 +675,9 @@ static int create_sort_keys(struct hist_
+@@ -670,7 +686,9 @@ static int create_sort_keys(struct hist_
}
for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
@@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
sort_key = &hist_data->sort_keys[i];
-@@ -692,8 +710,10 @@ static int create_sort_keys(struct hist_
+@@ -703,8 +721,10 @@ static int create_sort_keys(struct hist_
}
for (j = 1; j < hist_data->n_fields; j++) {
@@ -69,7 +69,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
sort_key->field_idx = j;
descending = is_descending(field_str);
if (descending < 0) {
-@@ -941,6 +961,7 @@ hist_trigger_entry_print(struct seq_file
+@@ -952,6 +972,7 @@ hist_trigger_entry_print(struct seq_file
struct hist_field *key_field;
char str[KSYM_SYMBOL_LEN];
bool multiline = false;
@@ -77,7 +77,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
unsigned int i;
u64 uval;
-@@ -952,26 +973,27 @@ hist_trigger_entry_print(struct seq_file
+@@ -963,26 +984,27 @@ hist_trigger_entry_print(struct seq_file
if (i > hist_data->n_vals)
seq_puts(m, ", ");
@@ -113,7 +113,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
} else if (key_field->flags & HIST_FIELD_FL_SYSCALL) {
const char *syscall_name;
-@@ -980,8 +1002,8 @@ hist_trigger_entry_print(struct seq_file
+@@ -991,8 +1013,8 @@ hist_trigger_entry_print(struct seq_file
if (!syscall_name)
syscall_name = "unknown_syscall";
@@ -124,7 +124,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
} else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
seq_puts(m, "stacktrace:\n");
hist_trigger_stacktrace_print(m,
-@@ -989,15 +1011,14 @@ hist_trigger_entry_print(struct seq_file
+@@ -1000,15 +1022,14 @@ hist_trigger_entry_print(struct seq_file
HIST_STACKTRACE_DEPTH);
multiline = true;
} else if (key_field->flags & HIST_FIELD_FL_LOG2) {
@@ -143,7 +143,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
}
-@@ -1010,13 +1031,13 @@ hist_trigger_entry_print(struct seq_file
+@@ -1021,13 +1042,13 @@ hist_trigger_entry_print(struct seq_file
tracing_map_read_sum(elt, HITCOUNT_IDX));
for (i = 1; i < hist_data->n_vals; i++) {
@@ -161,7 +161,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
tracing_map_read_sum(elt, i));
}
}
-@@ -1131,7 +1152,9 @@ static const char *get_hist_field_flags(
+@@ -1142,7 +1163,9 @@ static const char *get_hist_field_flags(
static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
{
diff --git a/patches/0005-tracing-Reimplement-log2.patch b/patches/0009-tracing-Reimplement-log2.patch
index a0030142b794..e26c8d5dc532 100644
--- a/patches/0005-tracing-Reimplement-log2.patch
+++ b/patches/0009-tracing-Reimplement-log2.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:17 -0500
-Subject: [PATCH 05/40] tracing: Reimplement log2
+Date: Fri, 22 Sep 2017 14:58:23 -0500
+Subject: [PATCH 09/42] tracing: Reimplement log2
log2 as currently implemented applies only to u64 trace_event_field
derived fields, and assumes that anything it's applied to is a u64
@@ -61,7 +61,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (field_name == NULL)
field_name = "";
-@@ -346,8 +354,20 @@ static const struct tracing_map_ops hist
+@@ -357,8 +365,20 @@ static const struct tracing_map_ops hist
.elt_init = hist_trigger_elt_comm_init,
};
@@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_field);
}
-@@ -374,7 +394,10 @@ static struct hist_field *create_hist_fi
+@@ -385,7 +405,10 @@ static struct hist_field *create_hist_fi
}
if (flags & HIST_FIELD_FL_LOG2) {
@@ -94,7 +94,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
goto out;
}
-@@ -394,7 +417,7 @@ static struct hist_field *create_hist_fi
+@@ -405,7 +428,7 @@ static struct hist_field *create_hist_fi
hist_field->fn = select_value_fn(field->size,
field->is_signed);
if (!hist_field->fn) {
@@ -103,7 +103,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return NULL;
}
}
-@@ -411,7 +434,7 @@ static void destroy_hist_fields(struct h
+@@ -422,7 +445,7 @@ static void destroy_hist_fields(struct h
for (i = 0; i < TRACING_MAP_FIELDS_MAX; i++) {
if (hist_data->fields[i]) {
diff --git a/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch b/patches/0010-tracing-Add-support-to-detect-and-avoid-duplicates.patch
index 78c4112ee8d6..55ed7edb333f 100644
--- a/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch
+++ b/patches/0010-tracing-Add-support-to-detect-and-avoid-duplicates.patch
@@ -1,6 +1,6 @@
From: Vedang Patel <vedang.patel@intel.com>
-Date: Tue, 5 Sep 2017 16:57:14 -0500
-Subject: [PATCH 02/40] tracing: Add support to detect and avoid duplicates
+Date: Fri, 22 Sep 2017 14:59:41 -0500
+Subject: [PATCH 10/42] tracing: Add support to detect and avoid duplicates
A duplicate in the tracing_map hash table is when 2 different entries
have the same key and, as a result, the key_hash. This is possible due
@@ -38,38 +38,43 @@ cmpxchg() from incrementing idx. This way, they will loop
around and check if the thread which succeeded in executing cmpxchg()
had the same key.
-[1] - https://lkml.org/lkml/2017/6/26/751
+[1] http://lkml.kernel.org/r/cover.1498510759.git.tom.zanussi@linux.intel.com
Signed-off-by: Vedang Patel <vedang.patel@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/tracing_map.c | 37 +++++++++++++++++++++++++++++++++----
- 1 file changed, 33 insertions(+), 4 deletions(-)
+ kernel/trace/tracing_map.c | 41 ++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 36 insertions(+), 5 deletions(-)
--- a/kernel/trace/tracing_map.c
+++ b/kernel/trace/tracing_map.c
-@@ -414,6 +414,7 @@ static inline struct tracing_map_elt *
+@@ -414,7 +414,9 @@ static inline struct tracing_map_elt *
__tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only)
{
u32 idx, key_hash, test_key;
+ int dup_try = 0;
struct tracing_map_entry *entry;
++ struct tracing_map_elt *val;
key_hash = jhash(key, map->key_size, 0);
-@@ -426,10 +427,31 @@ static inline struct tracing_map_elt *
+ if (key_hash == 0)
+@@ -426,11 +428,33 @@ static inline struct tracing_map_elt *
entry = TRACING_MAP_ENTRY(map->map, idx);
test_key = entry->key;
- if (test_key && test_key == key_hash && entry->val &&
- keys_match(key, entry->val->key, map->key_size)) {
-- atomic64_inc(&map->hits);
+- if (!lookup_only)
+- atomic64_inc(&map->hits);
- return entry->val;
+ if (test_key && test_key == key_hash) {
-+ if (entry->val &&
-+ keys_match(key, entry->val->key, map->key_size)) {
-+ atomic64_inc(&map->hits);
-+ return entry->val;
-+ } else if (unlikely(!entry->val)) {
++ val = READ_ONCE(entry->val);
++ if (val &&
++ keys_match(key, val->key, map->key_size)) {
++ if (!lookup_only)
++ atomic64_inc(&map->hits);
++ return val;
++ } else if (unlikely(!val)) {
+ /*
+ * The key is present. But, val (pointer to elt
+ * struct) is still NULL. which means some other
@@ -92,7 +97,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
if (!test_key) {
-@@ -451,6 +473,13 @@ static inline struct tracing_map_elt *
+@@ -452,6 +476,13 @@ static inline struct tracing_map_elt *
atomic64_inc(&map->hits);
return entry->val;
diff --git a/patches/0003-tracing-Remove-code-which-merges-duplicates.patch b/patches/0011-tracing-Remove-code-which-merges-duplicates.patch
index 89a3a78188e9..f668553f0471 100644
--- a/patches/0003-tracing-Remove-code-which-merges-duplicates.patch
+++ b/patches/0011-tracing-Remove-code-which-merges-duplicates.patch
@@ -1,6 +1,6 @@
From: Vedang Patel <vedang.patel@intel.com>
-Date: Tue, 5 Sep 2017 16:57:15 -0500
-Subject: [PATCH 03/40] tracing: Remove code which merges duplicates
+Date: Fri, 22 Sep 2017 14:59:42 -0500
+Subject: [PATCH 11/42] tracing: Remove code which merges duplicates
We now have the logic to detect and remove duplicates in the
tracing_map hash table. The code which merges duplicates in the
@@ -19,7 +19,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
-@@ -315,16 +315,6 @@ static int hist_trigger_elt_comm_alloc(s
+@@ -340,16 +340,6 @@ static int hist_trigger_elt_comm_alloc(s
return 0;
}
@@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt)
{
char *comm = elt->private_data;
-@@ -335,7 +325,6 @@ static void hist_trigger_elt_comm_init(s
+@@ -360,7 +350,6 @@ static void hist_trigger_elt_comm_init(s
static const struct tracing_map_ops hist_trigger_elt_comm_ops = {
.elt_alloc = hist_trigger_elt_comm_alloc,
@@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
--- a/kernel/trace/tracing_map.c
+++ b/kernel/trace/tracing_map.c
-@@ -844,67 +844,15 @@ create_sort_entry(void *key, struct trac
+@@ -847,67 +847,15 @@ create_sort_entry(void *key, struct trac
return sort_entry;
}
@@ -117,7 +117,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *),
(int (*)(const void *, const void *))cmp_entries_dup, NULL);
-@@ -913,30 +861,14 @@ static int merge_dups(struct tracing_map
+@@ -916,30 +864,14 @@ static int merge_dups(struct tracing_map
for (i = 1; i < n_entries; i++) {
if (!memcmp(sort_entries[i]->key, key, key_size)) {
dups++; total_dups++;
@@ -150,7 +150,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static bool is_key(struct tracing_map *map, unsigned int field_idx)
-@@ -1062,10 +994,7 @@ int tracing_map_sort_entries(struct trac
+@@ -1065,10 +997,7 @@ int tracing_map_sort_entries(struct trac
return 1;
}
diff --git a/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch b/patches/0012-ring-buffer-Add-interface-for-setting-absolute-time-.patch
index 69b007605471..d8c4e03092db 100644
--- a/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch
+++ b/patches/0012-ring-buffer-Add-interface-for-setting-absolute-time-.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:18 -0500
-Subject: [PATCH 06/40] ring-buffer: Add interface for setting absolute time
+Date: Fri, 22 Sep 2017 14:59:43 -0500
+Subject: [PATCH 12/42] ring-buffer: Add interface for setting absolute time
stamps
Define a new function, tracing_set_time_stamp_abs(), which can be used
@@ -14,6 +14,7 @@ Only the interface is added here; a subsequent patch will add the
underlying implementation.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Baohong Liu <baohong.liu@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
include/linux/ring_buffer.h | 2 ++
@@ -104,7 +105,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ tracing_reset_online_cpus(&tr->trace_buffer);
+
+#ifdef CONFIG_TRACER_MAX_TRACE
-+ if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer)
++ if (tr->max_buffer.buffer)
+ ring_buffer_set_time_stamp_abs(tr->max_buffer.buffer, abs);
+ tracing_reset_online_cpus(&tr->max_buffer);
+#endif
diff --git a/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch b/patches/0013-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch
index 7d334b4f3726..8c4281b3bec6 100644
--- a/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch
+++ b/patches/0013-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:20 -0500
-Subject: [PATCH 08/40] ring-buffer: Redefine the unimplemented
+Date: Fri, 22 Sep 2017 14:59:44 -0500
+Subject: [PATCH 13/42] ring-buffer: Redefine the unimplemented
RINGBUF_TIME_TIME_STAMP
RINGBUF_TYPE_TIME_STAMP is defined but not used, and from what I can
@@ -207,7 +207,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
cpu_buffer->write_stamp += delta;
} else
cpu_buffer->write_stamp += event->time_delta;
-@@ -2687,7 +2720,7 @@ static struct ring_buffer_event *
+@@ -2657,7 +2690,7 @@ static struct ring_buffer_event *
* If this is the first commit on the page, then it has the same
* timestamp as the page itself.
*/
@@ -216,7 +216,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
info->delta = 0;
/* See if we shot pass the end of this buffer page */
-@@ -2765,8 +2798,11 @@ rb_reserve_next_event(struct ring_buffer
+@@ -2735,8 +2768,11 @@ rb_reserve_next_event(struct ring_buffer
/* make sure this diff is calculated here */
barrier();
@@ -230,7 +230,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
info.delta = diff;
if (unlikely(test_time_stamp(info.delta)))
rb_handle_timestamp(cpu_buffer, &info);
-@@ -3448,14 +3484,12 @@ rb_update_read_stamp(struct ring_buffer_
+@@ -3418,14 +3454,12 @@ rb_update_read_stamp(struct ring_buffer_
return;
case RINGBUF_TYPE_TIME_EXTEND:
@@ -247,7 +247,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return;
case RINGBUF_TYPE_DATA:
-@@ -3479,14 +3513,12 @@ rb_update_iter_read_stamp(struct ring_bu
+@@ -3449,14 +3483,12 @@ rb_update_iter_read_stamp(struct ring_bu
return;
case RINGBUF_TYPE_TIME_EXTEND:
@@ -264,7 +264,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return;
case RINGBUF_TYPE_DATA:
-@@ -3710,6 +3742,8 @@ rb_buffer_peek(struct ring_buffer_per_cp
+@@ -3680,6 +3712,8 @@ rb_buffer_peek(struct ring_buffer_per_cp
struct buffer_page *reader;
int nr_loops = 0;
@@ -273,7 +273,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
again:
/*
* We repeat when a time extend is encountered.
-@@ -3746,12 +3780,17 @@ rb_buffer_peek(struct ring_buffer_per_cp
+@@ -3716,12 +3750,17 @@ rb_buffer_peek(struct ring_buffer_per_cp
goto again;
case RINGBUF_TYPE_TIME_STAMP:
@@ -293,7 +293,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
*ts = cpu_buffer->read_stamp + event->time_delta;
ring_buffer_normalize_time_stamp(cpu_buffer->buffer,
cpu_buffer->cpu, ts);
-@@ -3776,6 +3815,9 @@ rb_iter_peek(struct ring_buffer_iter *it
+@@ -3746,6 +3785,9 @@ rb_iter_peek(struct ring_buffer_iter *it
struct ring_buffer_event *event;
int nr_loops = 0;
@@ -303,7 +303,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
cpu_buffer = iter->cpu_buffer;
buffer = cpu_buffer->buffer;
-@@ -3828,12 +3870,17 @@ rb_iter_peek(struct ring_buffer_iter *it
+@@ -3798,12 +3840,17 @@ rb_iter_peek(struct ring_buffer_iter *it
goto again;
case RINGBUF_TYPE_TIME_STAMP:
diff --git a/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch b/patches/0014-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch
index d384e8e31ece..432868e3b171 100644
--- a/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch
+++ b/patches/0014-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:21 -0500
-Subject: [PATCH 09/40] tracing: Give event triggers access to
+Date: Fri, 22 Sep 2017 14:59:45 -0500
+Subject: [PATCH 14/42] tracing: Give event triggers access to
ring_buffer_event
The ring_buffer event can provide a timestamp that may be useful to
diff --git a/patches/0010-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch b/patches/0015-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch
index 84a46a8b7074..6d66fd3301fa 100644
--- a/patches/0010-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch
+++ b/patches/0015-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:22 -0500
-Subject: [PATCH 10/40] tracing: Add ring buffer event param to hist field
+Date: Fri, 22 Sep 2017 14:59:46 -0500
+Subject: [PATCH 15/42] tracing: Add ring buffer event param to hist field
functions
Some events such as timestamps require access to a ring_buffer_event
diff --git a/patches/0012-tracing-Break-out-hist-trigger-assignment-parsing.patch b/patches/0016-tracing-Break-out-hist-trigger-assignment-parsing.patch
index d49318f8575c..6c222455b905 100644
--- a/patches/0012-tracing-Break-out-hist-trigger-assignment-parsing.patch
+++ b/patches/0016-tracing-Break-out-hist-trigger-assignment-parsing.patch
@@ -1,19 +1,20 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:24 -0500
-Subject: [PATCH 12/40] tracing: Break out hist trigger assignment parsing
+Date: Fri, 22 Sep 2017 14:59:47 -0500
+Subject: [PATCH 16/42] tracing: Break out hist trigger assignment parsing
This will make it easier to add variables, and makes the parsing code
cleaner regardless.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Rajvi Jingar <rajvi.jingar@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 56 ++++++++++++++++++++++++---------------
- 1 file changed, 35 insertions(+), 21 deletions(-)
+ kernel/trace/trace_events_hist.c | 72 +++++++++++++++++++++++++++------------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
-@@ -251,6 +251,35 @@ static void destroy_hist_trigger_attrs(s
+@@ -251,6 +251,51 @@ static void destroy_hist_trigger_attrs(s
kfree(attrs);
}
@@ -22,17 +23,33 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ int ret = 0;
+
+ if ((strncmp(str, "key=", strlen("key=")) == 0) ||
-+ (strncmp(str, "keys=", strlen("keys=")) == 0))
++ (strncmp(str, "keys=", strlen("keys=")) == 0)) {
+ attrs->keys_str = kstrdup(str, GFP_KERNEL);
-+ else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
++ if (!attrs->keys_str) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ } else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
+ (strncmp(str, "vals=", strlen("vals=")) == 0) ||
-+ (strncmp(str, "values=", strlen("values=")) == 0))
++ (strncmp(str, "values=", strlen("values=")) == 0)) {
+ attrs->vals_str = kstrdup(str, GFP_KERNEL);
-+ else if (strncmp(str, "sort=", strlen("sort=")) == 0)
++ if (!attrs->vals_str) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ } else if (strncmp(str, "sort=", strlen("sort=")) == 0) {
+ attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
-+ else if (strncmp(str, "name=", strlen("name=")) == 0)
++ if (!attrs->sort_key_str) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ } else if (strncmp(str, "name=", strlen("name=")) == 0) {
+ attrs->name = kstrdup(str, GFP_KERNEL);
-+ else if (strncmp(str, "size=", strlen("size=")) == 0) {
++ if (!attrs->name) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ } else if (strncmp(str, "size=", strlen("size=")) == 0) {
+ int map_bits = parse_map_size(str);
+
+ if (map_bits < 0) {
@@ -49,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
{
struct hist_trigger_attrs *attrs;
-@@ -263,33 +292,18 @@ static struct hist_trigger_attrs *parse_
+@@ -263,33 +308,18 @@ static struct hist_trigger_attrs *parse_
while (trigger_str) {
char *str = strsep(&trigger_str, ":");
diff --git a/patches/0014-tracing-Add-hist-trigger-timestamp-support.patch b/patches/0017-tracing-Add-hist-trigger-timestamp-support.patch
index c70686bbd64c..68fe5920ec63 100644
--- a/patches/0014-tracing-Add-hist-trigger-timestamp-support.patch
+++ b/patches/0017-tracing-Add-hist-trigger-timestamp-support.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:26 -0500
-Subject: [PATCH 14/40] tracing: Add hist trigger timestamp support
+Date: Fri, 22 Sep 2017 14:59:48 -0500
+Subject: [PATCH 17/42] tracing: Add hist trigger timestamp support
Add support for a timestamp event field. This is actually a 'pseudo-'
event field in that it behaves like it's part of the event record, but
@@ -21,10 +21,11 @@ event rather than an offset. This mode will be enabled if and only if
a histogram makes use of the "$common_timestamp" field.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Baohong Liu <baohong.liu@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 88 ++++++++++++++++++++++++++++-----------
- 1 file changed, 65 insertions(+), 23 deletions(-)
+ kernel/trace/trace_events_hist.c | 90 +++++++++++++++++++++++++++++----------
+ 1 file changed, 67 insertions(+), 23 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -42,10 +43,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_##type(struct hist_field *hist_field, \
void *event, \
@@ -135,6 +141,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_SYSCALL = 128,
- HIST_FIELD_FL_STACKTRACE = 256,
- HIST_FIELD_FL_LOG2 = 512,
-+ HIST_FIELD_FL_TIMESTAMP = 1024,
+ HIST_FIELD_FL_SYSCALL = 1 << 7,
+ HIST_FIELD_FL_STACKTRACE = 1 << 8,
+ HIST_FIELD_FL_LOG2 = 1 << 9,
++ HIST_FIELD_FL_TIMESTAMP = 1 << 10,
};
struct hist_trigger_attrs {
@@ -66,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (field_name == NULL)
field_name = "";
-@@ -424,6 +434,12 @@ static struct hist_field *create_hist_fi
+@@ -440,6 +450,12 @@ static struct hist_field *create_hist_fi
goto out;
}
@@ -79,7 +80,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (WARN_ON_ONCE(!field))
goto out;
-@@ -501,10 +517,15 @@ static int create_val_field(struct hist_
+@@ -517,10 +533,15 @@ static int create_val_field(struct hist_
}
}
@@ -99,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
hist_data->fields[val_idx] = create_hist_field(field, flags);
-@@ -599,16 +620,22 @@ static int create_key_field(struct hist_
+@@ -615,16 +636,22 @@ static int create_key_field(struct hist_
}
}
@@ -131,7 +132,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
hist_data->fields[key_idx] = create_hist_field(field, flags);
-@@ -804,6 +831,9 @@ static int create_tracing_map_fields(str
+@@ -820,6 +847,9 @@ static int create_tracing_map_fields(str
if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
cmp_fn = tracing_map_cmp_none;
@@ -141,7 +142,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
else if (is_string_field(field))
cmp_fn = tracing_map_cmp_string;
else
-@@ -1201,7 +1231,11 @@ static void hist_field_print(struct seq_
+@@ -1217,7 +1247,11 @@ static void hist_field_print(struct seq_
{
const char *field_name = hist_field_name(hist_field, 0);
@@ -154,7 +155,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_field->flags) {
const char *flags_str = get_hist_field_flags(hist_field);
-@@ -1252,27 +1286,25 @@ static int event_hist_trigger_print(stru
+@@ -1268,27 +1302,25 @@ static int event_hist_trigger_print(stru
for (i = 0; i < hist_data->n_sort_keys; i++) {
struct tracing_map_sort_key *sort_key;
@@ -189,7 +190,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
if (data->filter_str)
-@@ -1440,6 +1472,10 @@ static bool hist_trigger_match(struct ev
+@@ -1456,6 +1488,10 @@ static bool hist_trigger_match(struct ev
return false;
if (key_field->offset != key_field_test->offset)
return false;
@@ -200,7 +201,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
for (i = 0; i < hist_data->n_sort_keys; i++) {
-@@ -1522,6 +1558,9 @@ static int hist_register_trigger(char *g
+@@ -1538,6 +1574,9 @@ static int hist_register_trigger(char *g
update_cond_flag(file);
@@ -210,13 +211,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (trace_event_trigger_enable_disable(file, 1) < 0) {
list_del_rcu(&data->list);
update_cond_flag(file);
-@@ -1556,6 +1595,9 @@ static void hist_unregister_trigger(char
+@@ -1572,6 +1611,11 @@ static void hist_unregister_trigger(char
if (unregistered && test->ops->free)
test->ops->free(test->ops, test);
+
-+ if (hist_data->enable_timestamps)
-+ tracing_set_time_stamp_abs(file->tr, false);
++ if (hist_data->enable_timestamps) {
++ if (unregistered)
++ tracing_set_time_stamp_abs(file->tr, false);
++ }
}
static void hist_unreg_all(struct trace_event_file *file)
diff --git a/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch b/patches/0018-tracing-Add-per-element-variable-support-to-tracing_.patch
index c06a44682c81..e1bf618e80dc 100644
--- a/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch
+++ b/patches/0018-tracing-Add-per-element-variable-support-to-tracing_.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:27 -0500
-Subject: [PATCH 15/40] tracing: Add per-element variable support to
+Date: Fri, 22 Sep 2017 14:59:49 -0500
+Subject: [PATCH 18/42] tracing: Add per-element variable support to
tracing_map
In order to allow information to be passed between trace events, add
diff --git a/patches/0016-tracing-Add-hist_data-member-to-hist_field.patch b/patches/0019-tracing-Add-hist_data-member-to-hist_field.patch
index fc725401801b..0e9fda263a6a 100644
--- a/patches/0016-tracing-Add-hist_data-member-to-hist_field.patch
+++ b/patches/0019-tracing-Add-hist_data-member-to-hist_field.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:28 -0500
-Subject: [PATCH 16/40] tracing: Add hist_data member to hist_field
+Date: Fri, 22 Sep 2017 14:59:50 -0500
+Subject: [PATCH 19/42] tracing: Add hist_data member to hist_field
Allow hist_data access via hist_field. Some users of hist_fields
require or will require more access to the associated hist_data.
@@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
static u64 hist_field_none(struct hist_field *field, void *event,
-@@ -404,7 +405,8 @@ static void destroy_hist_field(struct hi
+@@ -420,7 +421,8 @@ static void destroy_hist_field(struct hi
kfree(hist_field);
}
@@ -31,7 +31,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
unsigned long flags)
{
struct hist_field *hist_field;
-@@ -416,6 +418,8 @@ static struct hist_field *create_hist_fi
+@@ -432,6 +434,8 @@ static struct hist_field *create_hist_fi
if (!hist_field)
return NULL;
@@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (flags & HIST_FIELD_FL_HITCOUNT) {
hist_field->fn = hist_field_counter;
goto out;
-@@ -429,7 +433,7 @@ static struct hist_field *create_hist_fi
+@@ -445,7 +449,7 @@ static struct hist_field *create_hist_fi
if (flags & HIST_FIELD_FL_LOG2) {
unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
hist_field->fn = hist_field_log2;
@@ -49,7 +49,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_field->size = hist_field->operands[0]->size;
goto out;
}
-@@ -482,7 +486,7 @@ static void destroy_hist_fields(struct h
+@@ -498,7 +502,7 @@ static void destroy_hist_fields(struct h
static int create_hitcount_val(struct hist_trigger_data *hist_data)
{
hist_data->fields[HITCOUNT_IDX] =
@@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!hist_data->fields[HITCOUNT_IDX])
return -ENOMEM;
-@@ -528,7 +532,7 @@ static int create_val_field(struct hist_
+@@ -544,7 +548,7 @@ static int create_val_field(struct hist_
}
}
@@ -67,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!hist_data->fields[val_idx]) {
ret = -ENOMEM;
goto out;
-@@ -638,7 +642,7 @@ static int create_key_field(struct hist_
+@@ -654,7 +658,7 @@ static int create_key_field(struct hist_
}
}
diff --git a/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch b/patches/0020-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch
index 948c91bd8ded..08b8db054d7f 100644
--- a/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch
+++ b/patches/0020-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:29 -0500
-Subject: [PATCH 17/40] tracing: Add usecs modifier for hist trigger timestamps
+Date: Fri, 22 Sep 2017 14:59:51 -0500
+Subject: [PATCH 20/42] tracing: Add usecs modifier for hist trigger timestamps
Appending .usecs onto a common_timestamp field will cause the
timestamp value to be in microseconds instead of the default
@@ -65,10 +65,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_##type(struct hist_field *hist_field, \
void *event, \
@@ -143,6 +137,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_STACKTRACE = 256,
- HIST_FIELD_FL_LOG2 = 512,
- HIST_FIELD_FL_TIMESTAMP = 1024,
-+ HIST_FIELD_FL_TIMESTAMP_USECS = 2048,
+ HIST_FIELD_FL_STACKTRACE = 1 << 8,
+ HIST_FIELD_FL_LOG2 = 1 << 9,
+ HIST_FIELD_FL_TIMESTAMP = 1 << 10,
++ HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
};
struct hist_trigger_attrs {
@@ -101,7 +101,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static const char *hist_field_name(struct hist_field *field,
unsigned int level)
{
-@@ -618,6 +628,8 @@ static int create_key_field(struct hist_
+@@ -634,6 +644,8 @@ static int create_key_field(struct hist_
flags |= HIST_FIELD_FL_SYSCALL;
else if (strcmp(field_str, "log2") == 0)
flags |= HIST_FIELD_FL_LOG2;
@@ -110,7 +110,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
else {
ret = -EINVAL;
goto out;
-@@ -627,6 +639,8 @@ static int create_key_field(struct hist_
+@@ -643,6 +655,8 @@ static int create_key_field(struct hist_
if (strcmp(field_name, "$common_timestamp") == 0) {
flags |= HIST_FIELD_FL_TIMESTAMP;
hist_data->enable_timestamps = true;
@@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
key_size = sizeof(u64);
} else {
field = trace_find_event_field(file->event_call, field_name);
-@@ -1227,6 +1241,8 @@ static const char *get_hist_field_flags(
+@@ -1243,6 +1257,8 @@ static const char *get_hist_field_flags(
flags_str = "syscall";
else if (hist_field->flags & HIST_FIELD_FL_LOG2)
flags_str = "log2";
diff --git a/patches/0018-tracing-Add-variable-support-to-hist-triggers.patch b/patches/0021-tracing-Add-variable-support-to-hist-triggers.patch
index bbc4e015e8bb..582a59e3743e 100644
--- a/patches/0018-tracing-Add-variable-support-to-hist-triggers.patch
+++ b/patches/0021-tracing-Add-variable-support-to-hist-triggers.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:30 -0500
-Subject: [PATCH 18/40] tracing: Add variable support to hist triggers
+Date: Fri, 22 Sep 2017 14:59:52 -0500
+Subject: [PATCH 21/42] tracing: Add variable support to hist triggers
Add support for saving the value of a current event's event field by
assigning it to a variable that can be read by a subsequent event.
@@ -36,8 +36,8 @@ Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Baohong Liu <baohong.liu@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 372 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 333 insertions(+), 39 deletions(-)
+ kernel/trace/trace_events_hist.c | 374 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 334 insertions(+), 40 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -64,11 +64,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_none(struct hist_field *field, void *event,
@@ -138,6 +146,14 @@ enum hist_field_flags {
- HIST_FIELD_FL_LOG2 = 512,
- HIST_FIELD_FL_TIMESTAMP = 1024,
- HIST_FIELD_FL_TIMESTAMP_USECS = 2048,
-+ HIST_FIELD_FL_VAR = 4096,
-+ HIST_FIELD_FL_VAR_ONLY = 8192,
+ HIST_FIELD_FL_LOG2 = 1 << 9,
+ HIST_FIELD_FL_TIMESTAMP = 1 << 10,
+ HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
++ HIST_FIELD_FL_VAR = 1 << 12,
++ HIST_FIELD_FL_VAR_ONLY = 1 << 13,
+};
+
+struct var_defs {
@@ -123,7 +123,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(attrs->name);
kfree(attrs->sort_key_str);
kfree(attrs->keys_str);
-@@ -295,8 +324,22 @@ static int parse_assignment(char *str, s
+@@ -311,8 +340,22 @@ static int parse_assignment(char *str, s
goto out;
}
attrs->map_bits = map_bits;
@@ -148,7 +148,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
out:
return ret;
}
-@@ -412,12 +455,15 @@ static void destroy_hist_field(struct hi
+@@ -428,12 +471,15 @@ static void destroy_hist_field(struct hi
for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++)
destroy_hist_field(hist_field->operands[i], level + 1);
@@ -165,7 +165,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
struct hist_field *hist_field;
-@@ -443,7 +489,7 @@ static struct hist_field *create_hist_fi
+@@ -459,7 +505,7 @@ static struct hist_field *create_hist_fi
if (flags & HIST_FIELD_FL_LOG2) {
unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
hist_field->fn = hist_field_log2;
@@ -174,7 +174,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_field->size = hist_field->operands[0]->size;
goto out;
}
-@@ -478,14 +524,23 @@ static struct hist_field *create_hist_fi
+@@ -494,14 +540,23 @@ static struct hist_field *create_hist_fi
hist_field->field = field;
hist_field->flags = flags;
@@ -199,7 +199,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_data->fields[i]) {
destroy_hist_field(hist_data->fields[i], 0);
hist_data->fields[i] = NULL;
-@@ -496,11 +551,12 @@ static void destroy_hist_fields(struct h
+@@ -512,11 +567,12 @@ static void destroy_hist_fields(struct h
static int create_hitcount_val(struct hist_trigger_data *hist_data)
{
hist_data->fields[HITCOUNT_IDX] =
@@ -213,7 +213,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX))
return -EINVAL;
-@@ -508,19 +564,53 @@ static int create_hitcount_val(struct hi
+@@ -524,19 +580,53 @@ static int create_hitcount_val(struct hi
return 0;
}
@@ -275,7 +275,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
field_name = strsep(&field_str, ".");
if (field_str) {
if (strcmp(field_str, "hex") == 0)
-@@ -542,25 +632,65 @@ static int create_val_field(struct hist_
+@@ -558,25 +648,65 @@ static int create_val_field(struct hist_
}
}
@@ -344,7 +344,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
int ret;
ret = create_hitcount_val(hist_data);
-@@ -580,12 +710,15 @@ static int create_val_fields(struct hist
+@@ -596,12 +726,15 @@ static int create_val_fields(struct hist
field_str = strsep(&fields_str, ",");
if (!field_str)
break;
@@ -360,7 +360,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (fields_str && (strcmp(fields_str, "hitcount") != 0))
ret = -EINVAL;
out:
-@@ -599,11 +732,12 @@ static int create_key_field(struct hist_
+@@ -615,11 +748,12 @@ static int create_key_field(struct hist_
char *field_str)
{
struct ftrace_event_field *field = NULL;
@@ -374,7 +374,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return -EINVAL;
flags |= HIST_FIELD_FL_KEY;
-@@ -611,6 +745,7 @@ static int create_key_field(struct hist_
+@@ -627,6 +761,7 @@ static int create_key_field(struct hist_
if (strcmp(field_str, "stacktrace") == 0) {
flags |= HIST_FIELD_FL_STACKTRACE;
key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH;
@@ -382,7 +382,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
} else {
char *field_name = strsep(&field_str, ".");
-@@ -656,7 +791,7 @@ static int create_key_field(struct hist_
+@@ -672,7 +807,7 @@ static int create_key_field(struct hist_
}
}
@@ -391,7 +391,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!hist_data->fields[key_idx]) {
ret = -ENOMEM;
goto out;
-@@ -672,6 +807,7 @@ static int create_key_field(struct hist_
+@@ -688,6 +823,7 @@ static int create_key_field(struct hist_
}
hist_data->n_keys++;
@@ -399,7 +399,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (WARN_ON(hist_data->n_keys > TRACING_MAP_KEYS_MAX))
return -EINVAL;
-@@ -715,21 +851,108 @@ static int create_key_fields(struct hist
+@@ -731,21 +867,108 @@ static int create_key_fields(struct hist
return ret;
}
@@ -510,7 +510,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ret;
}
-@@ -752,7 +975,7 @@ static int create_sort_keys(struct hist_
+@@ -768,7 +991,7 @@ static int create_sort_keys(struct hist_
char *fields_str = hist_data->attrs->sort_key_str;
struct tracing_map_sort_key *sort_key;
int descending, ret = 0;
@@ -519,7 +519,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_data->n_sort_keys = 1; /* we always have at least one, hitcount */
-@@ -800,12 +1023,19 @@ static int create_sort_keys(struct hist_
+@@ -816,12 +1039,19 @@ static int create_sort_keys(struct hist_
continue;
}
@@ -541,7 +541,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
descending = is_descending(field_str);
if (descending < 0) {
ret = descending;
-@@ -820,6 +1050,7 @@ static int create_sort_keys(struct hist_
+@@ -836,6 +1066,7 @@ static int create_sort_keys(struct hist_
break;
}
}
@@ -549,7 +549,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_data->n_sort_keys = i;
out:
return ret;
-@@ -860,12 +1091,19 @@ static int create_tracing_map_fields(str
+@@ -876,12 +1107,19 @@ static int create_tracing_map_fields(str
idx = tracing_map_add_key_field(map,
hist_field->offset,
cmp_fn);
@@ -571,7 +571,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
return 0;
-@@ -889,7 +1127,8 @@ static bool need_tracing_map_ops(struct
+@@ -905,7 +1143,8 @@ static bool need_tracing_map_ops(struct
static struct hist_trigger_data *
create_hist_data(unsigned int map_bits,
struct hist_trigger_attrs *attrs,
@@ -581,7 +581,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
const struct tracing_map_ops *map_ops = NULL;
struct hist_trigger_data *hist_data;
-@@ -900,6 +1139,7 @@ create_hist_data(unsigned int map_bits,
+@@ -916,6 +1155,7 @@ create_hist_data(unsigned int map_bits,
return ERR_PTR(-ENOMEM);
hist_data->attrs = attrs;
@@ -589,7 +589,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = create_hist_fields(hist_data, file);
if (ret)
-@@ -946,14 +1186,29 @@ static void hist_trigger_elt_update(stru
+@@ -962,14 +1202,29 @@ static void hist_trigger_elt_update(stru
struct ring_buffer_event *rbe)
{
struct hist_field *hist_field;
@@ -621,7 +621,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static inline void add_to_key(char *compound_key, void *key,
-@@ -1128,6 +1383,9 @@ hist_trigger_entry_print(struct seq_file
+@@ -1144,6 +1399,9 @@ hist_trigger_entry_print(struct seq_file
for (i = 1; i < hist_data->n_vals; i++) {
field_name = hist_field_name(hist_data->fields[i], 0);
@@ -631,7 +631,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
seq_printf(m, " %s: %10llx", field_name,
tracing_map_read_sum(elt, i));
-@@ -1251,6 +1509,9 @@ static void hist_field_print(struct seq_
+@@ -1267,6 +1525,9 @@ static void hist_field_print(struct seq_
{
const char *field_name = hist_field_name(hist_field, 0);
@@ -641,7 +641,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
seq_puts(m, "$common_timestamp");
else if (field_name)
-@@ -1269,7 +1530,8 @@ static int event_hist_trigger_print(stru
+@@ -1285,7 +1546,8 @@ static int event_hist_trigger_print(stru
struct event_trigger_data *data)
{
struct hist_trigger_data *hist_data = data->private_data;
@@ -651,7 +651,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
unsigned int i;
seq_puts(m, "hist:");
-@@ -1280,25 +1542,47 @@ static int event_hist_trigger_print(stru
+@@ -1296,25 +1558,47 @@ static int event_hist_trigger_print(stru
seq_puts(m, "keys=");
for_each_hist_key_field(i, hist_data) {
@@ -703,7 +703,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
}
-@@ -1306,7 +1590,10 @@ static int event_hist_trigger_print(stru
+@@ -1322,7 +1606,10 @@ static int event_hist_trigger_print(stru
for (i = 0; i < hist_data->n_sort_keys; i++) {
struct tracing_map_sort_key *sort_key;
@@ -715,7 +715,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
sort_key = &hist_data->sort_keys[i];
idx = sort_key->field_idx;
-@@ -1319,8 +1606,11 @@ static int event_hist_trigger_print(stru
+@@ -1335,8 +1622,11 @@ static int event_hist_trigger_print(stru
if (idx == HITCOUNT_IDX)
seq_puts(m, "hitcount");
@@ -728,7 +728,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (sort_key->descending)
seq_puts(m, ".descending");
-@@ -1644,12 +1934,16 @@ static int event_hist_trigger_func(struc
+@@ -1633,7 +1923,7 @@ static void hist_unregister_trigger(char
+ test->ops->free(test->ops, test);
+
+ if (hist_data->enable_timestamps) {
+- if (unregistered)
++ if (!hist_data->remove || unregistered)
+ tracing_set_time_stamp_abs(file->tr, false);
+ }
+ }
+@@ -1662,12 +1952,16 @@ static int event_hist_trigger_func(struc
struct hist_trigger_attrs *attrs;
struct event_trigger_ops *trigger_ops;
struct hist_trigger_data *hist_data;
@@ -745,7 +754,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/* separate the trigger from the filter (k:v [if filter]) */
trigger = strsep(&param, " \t");
if (!trigger)
-@@ -1662,7 +1956,7 @@ static int event_hist_trigger_func(struc
+@@ -1680,7 +1974,7 @@ static int event_hist_trigger_func(struc
if (attrs->map_bits)
hist_trigger_bits = attrs->map_bits;
@@ -754,7 +763,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (IS_ERR(hist_data)) {
destroy_hist_trigger_attrs(attrs);
return PTR_ERR(hist_data);
-@@ -1691,7 +1985,7 @@ static int event_hist_trigger_func(struc
+@@ -1709,7 +2003,7 @@ static int event_hist_trigger_func(struc
goto out_free;
}
diff --git a/patches/0019-tracing-Account-for-variables-in-named-trigger-compa.patch b/patches/0022-tracing-Account-for-variables-in-named-trigger-compa.patch
index 8e717ed18ce7..e441633a373e 100644
--- a/patches/0019-tracing-Account-for-variables-in-named-trigger-compa.patch
+++ b/patches/0022-tracing-Account-for-variables-in-named-trigger-compa.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:31 -0500
-Subject: [PATCH 19/40] tracing: Account for variables in named trigger
+Date: Fri, 22 Sep 2017 14:59:53 -0500
+Subject: [PATCH 22/42] tracing: Account for variables in named trigger
compatibility
Named triggers must also have the same set of variables in order to be
@@ -13,12 +13,12 @@ are meant to allow one or more events to set the same variable.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
+ kernel/trace/trace_events_hist.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
-@@ -1598,7 +1598,7 @@ static int event_hist_trigger_print(stru
+@@ -1614,7 +1614,7 @@ static int event_hist_trigger_print(stru
sort_key = &hist_data->sort_keys[i];
idx = sort_key->field_idx;
@@ -27,15 +27,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return -EINVAL;
if (i > 0)
-@@ -1786,6 +1786,12 @@ static bool hist_trigger_match(struct ev
+@@ -1802,6 +1802,11 @@ static bool hist_trigger_match(struct ev
return false;
if (key_field->is_signed != key_field_test->is_signed)
return false;
-+ if ((key_field->var.name && !key_field_test->var.name) ||
-+ (!key_field->var.name && key_field_test->var.name))
++ if (!!key_field->var.name != !!key_field_test->var.name)
+ return false;
-+ if ((key_field->var.name && key_field_test->var.name) &&
-+ strcmp(key_field->var.name, key_field_test->var.name) != 0)
++ if (key_field->var.name &&
++ strcmp(key_field->var.name, key_field_test->var.name) != 0)
+ return false;
}
diff --git a/patches/0023-tracing-Move-get_hist_field_flags.patch b/patches/0023-tracing-Move-get_hist_field_flags.patch
new file mode 100644
index 000000000000..5c3c8efd5ad0
--- /dev/null
+++ b/patches/0023-tracing-Move-get_hist_field_flags.patch
@@ -0,0 +1,73 @@
+From: Tom Zanussi <tom.zanussi@linux.intel.com>
+Date: Fri, 22 Sep 2017 14:59:54 -0500
+Subject: [PATCH 23/42] tracing: Move get_hist_field_flags()
+
+Move get_hist_field_flags() to make it more easily accessible for new
+code (and keep the move separate from new functionality).
+
+Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/trace/trace_events_hist.c | 44 +++++++++++++++++++--------------------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -457,6 +457,28 @@ static const struct tracing_map_ops hist
+ .elt_init = hist_trigger_elt_comm_init,
+ };
+
++static const char *get_hist_field_flags(struct hist_field *hist_field)
++{
++ const char *flags_str = NULL;
++
++ if (hist_field->flags & HIST_FIELD_FL_HEX)
++ flags_str = "hex";
++ else if (hist_field->flags & HIST_FIELD_FL_SYM)
++ flags_str = "sym";
++ else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
++ flags_str = "sym-offset";
++ else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
++ flags_str = "execname";
++ else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
++ flags_str = "syscall";
++ else if (hist_field->flags & HIST_FIELD_FL_LOG2)
++ flags_str = "log2";
++ else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
++ flags_str = "usecs";
++
++ return flags_str;
++}
++
+ static void destroy_hist_field(struct hist_field *hist_field,
+ unsigned int level)
+ {
+@@ -1499,28 +1521,6 @@ const struct file_operations event_hist_
+ .release = single_release,
+ };
+
+-static const char *get_hist_field_flags(struct hist_field *hist_field)
+-{
+- const char *flags_str = NULL;
+-
+- if (hist_field->flags & HIST_FIELD_FL_HEX)
+- flags_str = "hex";
+- else if (hist_field->flags & HIST_FIELD_FL_SYM)
+- flags_str = "sym";
+- else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
+- flags_str = "sym-offset";
+- else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
+- flags_str = "execname";
+- else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
+- flags_str = "syscall";
+- else if (hist_field->flags & HIST_FIELD_FL_LOG2)
+- flags_str = "log2";
+- else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
+- flags_str = "usecs";
+-
+- return flags_str;
+-}
+-
+ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
+ {
+ const char *field_name = hist_field_name(hist_field, 0);
diff --git a/patches/0020-tracing-Add-simple-expression-support-to-hist-trigge.patch b/patches/0024-tracing-Add-simple-expression-support-to-hist-trigge.patch
index 56b2385fe37f..1c8e56ff0580 100644
--- a/patches/0020-tracing-Add-simple-expression-support-to-hist-trigge.patch
+++ b/patches/0024-tracing-Add-simple-expression-support-to-hist-trigge.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:32 -0500
-Subject: [PATCH 20/40] tracing: Add simple expression support to hist triggers
+Date: Fri, 22 Sep 2017 14:59:55 -0500
+Subject: [PATCH 24/42] tracing: Add simple expression support to hist triggers
Add support for simple addition, subtraction, and unary expressions
(-(expr) and expr, where expr = b-a, a+b, a+b+c) to hist triggers, in
@@ -16,8 +16,8 @@ parsing.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 556 ++++++++++++++++++++++++++++++++-------
- 1 file changed, 460 insertions(+), 96 deletions(-)
+ kernel/trace/trace_events_hist.c | 514 +++++++++++++++++++++++++++++++++------
+ 1 file changed, 440 insertions(+), 74 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -87,10 +87,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_##type(struct hist_field *hist_field, \
void *event, \
@@ -148,6 +192,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_TIMESTAMP_USECS = 2048,
- HIST_FIELD_FL_VAR = 4096,
- HIST_FIELD_FL_VAR_ONLY = 8192,
-+ HIST_FIELD_FL_EXPR = 16384,
+ HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
+ HIST_FIELD_FL_VAR = 1 << 12,
+ HIST_FIELD_FL_VAR_ONLY = 1 << 13,
++ HIST_FIELD_FL_EXPR = 1 << 14,
};
struct var_defs {
@@ -103,32 +103,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (field_name == NULL)
field_name = "";
-@@ -441,6 +488,115 @@ static const struct tracing_map_ops hist
- .elt_init = hist_trigger_elt_comm_init,
- };
+@@ -479,6 +526,93 @@ static const char *get_hist_field_flags(
+ return flags_str;
+ }
-+static const char *get_hist_field_flags(struct hist_field *hist_field)
-+{
-+ const char *flags_str = NULL;
-+
-+ if (hist_field->flags & HIST_FIELD_FL_HEX)
-+ flags_str = "hex";
-+ else if (hist_field->flags & HIST_FIELD_FL_SYM)
-+ flags_str = "sym";
-+ else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
-+ flags_str = "sym-offset";
-+ else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
-+ flags_str = "execname";
-+ else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
-+ flags_str = "syscall";
-+ else if (hist_field->flags & HIST_FIELD_FL_LOG2)
-+ flags_str = "log2";
-+ else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
-+ flags_str = "usecs";
-+
-+ return flags_str;
-+}
-+
+static char *expr_str(struct hist_field *field, unsigned int level)
+{
+ char *expr;
@@ -219,7 +197,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void destroy_hist_field(struct hist_field *hist_field,
unsigned int level)
{
-@@ -456,6 +612,7 @@ static void destroy_hist_field(struct hi
+@@ -494,6 +628,7 @@ static void destroy_hist_field(struct hi
destroy_hist_field(hist_field->operands[i], level + 1);
kfree(hist_field->var.name);
@@ -227,7 +205,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_field);
}
-@@ -476,6 +633,9 @@ static struct hist_field *create_hist_fi
+@@ -514,6 +649,9 @@ static struct hist_field *create_hist_fi
hist_field->hist_data = hist_data;
@@ -237,7 +215,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (flags & HIST_FIELD_FL_HITCOUNT) {
hist_field->fn = hist_field_counter;
goto out;
-@@ -548,6 +708,287 @@ static void destroy_hist_fields(struct h
+@@ -586,6 +724,289 @@ static void destroy_hist_fields(struct h
}
}
@@ -392,8 +370,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ }
+
+ strsep(&str, "(");
-+ if (!str)
++ if (!str) {
++ ret = -EINVAL;
+ goto free;
++ }
+
+ flags |= HIST_FIELD_FL_EXPR;
+ expr = create_hist_field(hist_data, NULL, flags, var_name);
@@ -525,7 +505,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static int create_hitcount_val(struct hist_trigger_data *hist_data)
{
hist_data->fields[HITCOUNT_IDX] =
-@@ -607,41 +1048,21 @@ static int __create_val_field(struct his
+@@ -645,41 +1066,21 @@ static int __create_val_field(struct his
char *var_name, char *field_str,
unsigned long flags)
{
@@ -574,7 +554,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_data->n_var_only++;
if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
-@@ -731,8 +1152,8 @@ static int create_key_field(struct hist_
+@@ -769,8 +1170,8 @@ static int create_key_field(struct hist_
struct trace_event_file *file,
char *field_str)
{
@@ -584,7 +564,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
unsigned long flags = 0;
unsigned int key_size;
int ret = 0;
-@@ -747,60 +1168,24 @@ static int create_key_field(struct hist_
+@@ -785,60 +1186,24 @@ static int create_key_field(struct hist_
key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH;
hist_field = create_hist_field(hist_data, NULL, flags, NULL);
} else {
@@ -654,7 +634,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_data->key_size > HIST_KEY_SIZE_MAX) {
ret = -EINVAL;
goto out;
-@@ -1383,7 +1768,8 @@ hist_trigger_entry_print(struct seq_file
+@@ -1421,7 +1786,8 @@ hist_trigger_entry_print(struct seq_file
for (i = 1; i < hist_data->n_vals; i++) {
field_name = hist_field_name(hist_data->fields[i], 0);
@@ -664,32 +644,3 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
continue;
if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
-@@ -1483,28 +1869,6 @@ const struct file_operations event_hist_
- .release = single_release,
- };
-
--static const char *get_hist_field_flags(struct hist_field *hist_field)
--{
-- const char *flags_str = NULL;
--
-- if (hist_field->flags & HIST_FIELD_FL_HEX)
-- flags_str = "hex";
-- else if (hist_field->flags & HIST_FIELD_FL_SYM)
-- flags_str = "sym";
-- else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
-- flags_str = "sym-offset";
-- else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
-- flags_str = "execname";
-- else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
-- flags_str = "syscall";
-- else if (hist_field->flags & HIST_FIELD_FL_LOG2)
-- flags_str = "log2";
-- else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
-- flags_str = "usecs";
--
-- return flags_str;
--}
--
- static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
- {
- const char *field_name = hist_field_name(hist_field, 0);
diff --git a/patches/0025-tracing-Add-support-for-dynamic-tracepoints.patch b/patches/0025-tracing-Add-support-for-dynamic-tracepoints.patch
deleted file mode 100644
index 153daef07243..000000000000
--- a/patches/0025-tracing-Add-support-for-dynamic-tracepoints.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:37 -0500
-Subject: [PATCH 25/40] tracing: Add support for dynamic tracepoints
-
-The tracepoint infrastructure assumes statically-defined tracepoints
-and uses static_keys for tracepoint enablement. In order to define
-tracepoints on the fly, we need to have a dynamic counterpart.
-
-Add a 'dynamic' flag to struct tracepoint along with accompanying
-logic for this purpose.
-
-Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- include/linux/tracepoint-defs.h | 1 +
- kernel/tracepoint.c | 18 +++++++++++++-----
- 2 files changed, 14 insertions(+), 5 deletions(-)
-
---- a/include/linux/tracepoint-defs.h
-+++ b/include/linux/tracepoint-defs.h
-@@ -32,6 +32,7 @@ struct tracepoint {
- int (*regfunc)(void);
- void (*unregfunc)(void);
- struct tracepoint_func __rcu *funcs;
-+ bool dynamic;
- };
-
- #endif
---- a/kernel/tracepoint.c
-+++ b/kernel/tracepoint.c
-@@ -197,7 +197,9 @@ static int tracepoint_add_func(struct tr
- struct tracepoint_func *old, *tp_funcs;
- int ret;
-
-- if (tp->regfunc && !static_key_enabled(&tp->key)) {
-+ if (tp->regfunc &&
-+ ((tp->dynamic && !(atomic_read(&tp->key.enabled) > 0)) ||
-+ !static_key_enabled(&tp->key))) {
- ret = tp->regfunc();
- if (ret < 0)
- return ret;
-@@ -219,7 +221,9 @@ static int tracepoint_add_func(struct tr
- * is used.
- */
- rcu_assign_pointer(tp->funcs, tp_funcs);
-- if (!static_key_enabled(&tp->key))
-+ if (tp->dynamic && !(atomic_read(&tp->key.enabled) > 0))
-+ atomic_inc(&tp->key.enabled);
-+ else if (!tp->dynamic && !static_key_enabled(&tp->key))
- static_key_slow_inc(&tp->key);
- release_probes(old);
- return 0;
-@@ -246,10 +250,14 @@ static int tracepoint_remove_func(struct
-
- if (!tp_funcs) {
- /* Removed last function */
-- if (tp->unregfunc && static_key_enabled(&tp->key))
-+ if (tp->unregfunc &&
-+ ((tp->dynamic && (atomic_read(&tp->key.enabled) > 0)) ||
-+ static_key_enabled(&tp->key)))
- tp->unregfunc();
-
-- if (static_key_enabled(&tp->key))
-+ if (tp->dynamic && (atomic_read(&tp->key.enabled) > 0))
-+ atomic_dec(&tp->key.enabled);
-+ else if (!tp->dynamic && static_key_enabled(&tp->key))
- static_key_slow_dec(&tp->key);
- }
- rcu_assign_pointer(tp->funcs, tp_funcs);
-@@ -258,7 +266,7 @@ static int tracepoint_remove_func(struct
- }
-
- /**
-- * tracepoint_probe_register - Connect a probe to a tracepoint
-+ * tracepoint_probe_register_prio - Connect a probe to a tracepoint
- * @tp: tracepoint
- * @probe: probe handler
- * @data: tracepoint data
diff --git a/patches/0021-tracing-Generalize-per-element-hist-trigger-data.patch b/patches/0025-tracing-Generalize-per-element-hist-trigger-data.patch
index 1ab8f84aefed..2841c24bff57 100644
--- a/patches/0021-tracing-Generalize-per-element-hist-trigger-data.patch
+++ b/patches/0025-tracing-Generalize-per-element-hist-trigger-data.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:33 -0500
-Subject: [PATCH 21/40] tracing: Generalize per-element hist trigger data
+Date: Fri, 22 Sep 2017 14:59:56 -0500
+Subject: [PATCH 25/42] tracing: Generalize per-element hist trigger data
Up until now, hist triggers only needed per-element support for saving
'comm' data, which was saved directly as a private data pointer.
@@ -12,8 +12,8 @@ new hist_elt_data struct for the purpose, and switch the current
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 65 +++++++++++++++++++--------------------
- 1 file changed, 32 insertions(+), 33 deletions(-)
+ kernel/trace/trace_events_hist.c | 71 ++++++++++++++++++++-------------------
+ 1 file changed, 38 insertions(+), 33 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -28,18 +28,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static const char *hist_field_name(struct hist_field *field,
unsigned int level)
{
-@@ -447,26 +451,36 @@ static inline void save_comm(char *comm,
+@@ -463,45 +467,61 @@ static inline void save_comm(char *comm,
memcpy(comm, task->comm, TASK_COMM_LEN);
}
-static void hist_trigger_elt_comm_free(struct tracing_map_elt *elt)
++static void hist_elt_data_free(struct hist_elt_data *elt_data)
++{
++ kfree(elt_data->comm);
++ kfree(elt_data);
++}
++
+static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
{
- kfree((char *)elt->private_data);
-+ struct hist_elt_data *private_data = elt->private_data;
++ struct hist_elt_data *elt_data = elt->private_data;
+
-+ kfree(private_data->comm);
-+ kfree(private_data);
++ hist_elt_data_free(elt_data);
}
-static int hist_trigger_elt_comm_alloc(struct tracing_map_elt *elt)
@@ -51,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct hist_field *key_field;
unsigned int i;
-+ elt->private_data = elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
++ elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
+ if (!elt_data)
+ return -ENOMEM;
+
@@ -66,13 +71,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ elt_data->comm = kzalloc(size, GFP_KERNEL);
+ if (!elt_data->comm) {
+ kfree(elt_data);
-+ elt->private_data = NULL;
return -ENOMEM;
+ }
break;
}
}
-@@ -474,18 +488,18 @@ static int hist_trigger_elt_comm_alloc(s
+
++ elt->private_data = elt_data;
++
return 0;
}
@@ -80,12 +86,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+static void hist_trigger_elt_data_init(struct tracing_map_elt *elt)
{
- char *comm = elt->private_data;
-+ struct hist_elt_data *private_data = elt->private_data;
++ struct hist_elt_data *elt_data = elt->private_data;
- if (comm)
- save_comm(comm, current);
-+ if (private_data->comm)
-+ save_comm(private_data->comm, current);
++ if (elt_data->comm)
++ save_comm(elt_data->comm, current);
}
-static const struct tracing_map_ops hist_trigger_elt_comm_ops = {
@@ -99,7 +105,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
static const char *get_hist_field_flags(struct hist_field *hist_field)
-@@ -1494,21 +1508,6 @@ static int create_tracing_map_fields(str
+@@ -1512,21 +1532,6 @@ static int create_tracing_map_fields(str
return 0;
}
@@ -121,7 +127,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_trigger_data *
create_hist_data(unsigned int map_bits,
struct hist_trigger_attrs *attrs,
-@@ -1534,8 +1533,7 @@ create_hist_data(unsigned int map_bits,
+@@ -1552,8 +1557,7 @@ create_hist_data(unsigned int map_bits,
if (ret)
goto free;
@@ -131,7 +137,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_data->map = tracing_map_create(map_bits, hist_data->key_size,
map_ops, hist_data);
-@@ -1724,7 +1722,8 @@ hist_trigger_entry_print(struct seq_file
+@@ -1742,7 +1746,8 @@ hist_trigger_entry_print(struct seq_file
seq_printf(m, "%s: [%llx] %-55s", field_name,
uval, str);
} else if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
diff --git a/patches/0022-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch b/patches/0026-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch
index faa6dd2a0da7..815078f45786 100644
--- a/patches/0022-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch
+++ b/patches/0026-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:34 -0500
-Subject: [PATCH 22/40] tracing: Pass tracing_map_elt to hist_field accessor
+Date: Fri, 22 Sep 2017 14:59:57 -0500
+Subject: [PATCH 26/42] tracing: Pass tracing_map_elt to hist_field accessor
functions
Some accessor functions, such as for variable references, require
@@ -181,7 +181,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
struct hist_trigger_data *hist_data = hist_field->hist_data;
struct trace_array *tr = hist_data->event_file->tr;
-@@ -1574,7 +1597,7 @@ static void hist_trigger_elt_update(stru
+@@ -1598,7 +1621,7 @@ static void hist_trigger_elt_update(stru
for_each_hist_val_field(i, hist_data) {
hist_field = hist_data->fields[i];
@@ -190,7 +190,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (hist_field->flags & HIST_FIELD_FL_VAR) {
var_idx = hist_field->var.idx;
tracing_map_set_var(elt, var_idx, hist_val);
-@@ -1587,7 +1610,7 @@ static void hist_trigger_elt_update(stru
+@@ -1611,7 +1634,7 @@ static void hist_trigger_elt_update(stru
for_each_hist_key_field(i, hist_data) {
hist_field = hist_data->fields[i];
if (hist_field->flags & HIST_FIELD_FL_VAR) {
@@ -199,7 +199,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
var_idx = hist_field->var.idx;
tracing_map_set_var(elt, var_idx, hist_val);
}
-@@ -1625,9 +1648,9 @@ static void event_hist_trigger(struct ev
+@@ -1649,9 +1672,9 @@ static void event_hist_trigger(struct ev
bool use_compound_key = (hist_data->n_keys > 1);
unsigned long entries[HIST_STACKTRACE_DEPTH];
char compound_key[HIST_KEY_SIZE_MAX];
@@ -210,7 +210,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
u64 field_contents;
void *key = NULL;
unsigned int i;
-@@ -1648,7 +1671,7 @@ static void event_hist_trigger(struct ev
+@@ -1672,7 +1695,7 @@ static void event_hist_trigger(struct ev
key = entries;
} else {
diff --git a/patches/0023-tracing-Add-hist_field-type-field.patch b/patches/0027-tracing-Add-hist_field-type-field.patch
index 63bd58c3f92a..4e1ef6b176b1 100644
--- a/patches/0023-tracing-Add-hist_field-type-field.patch
+++ b/patches/0027-tracing-Add-hist_field-type-field.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:35 -0500
-Subject: [PATCH 23/40] tracing: Add hist_field 'type' field
+Date: Fri, 22 Sep 2017 14:59:58 -0500
+Subject: [PATCH 27/42] tracing: Add hist_field 'type' field
Future support for synthetic events requires hist_field 'type'
information, so add a field for that.
@@ -24,7 +24,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
struct hist_trigger_data *hist_data;
struct hist_var var;
-@@ -650,6 +651,7 @@ static void destroy_hist_field(struct hi
+@@ -672,6 +673,7 @@ static void destroy_hist_field(struct hi
kfree(hist_field->var.name);
kfree(hist_field->name);
@@ -32,7 +32,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_field);
}
-@@ -675,6 +677,10 @@ static struct hist_field *create_hist_fi
+@@ -697,6 +699,10 @@ static struct hist_field *create_hist_fi
if (flags & HIST_FIELD_FL_HITCOUNT) {
hist_field->fn = hist_field_counter;
@@ -43,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
goto out;
}
-@@ -688,12 +694,18 @@ static struct hist_field *create_hist_fi
+@@ -710,12 +716,18 @@ static struct hist_field *create_hist_fi
hist_field->fn = hist_field_log2;
hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
hist_field->size = hist_field->operands[0]->size;
@@ -62,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
goto out;
}
-@@ -703,6 +715,11 @@ static struct hist_field *create_hist_fi
+@@ -725,6 +737,11 @@ static struct hist_field *create_hist_fi
if (is_string_field(field)) {
flags |= HIST_FIELD_FL_STRING;
@@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (field->filter_type == FILTER_STATIC_STRING)
hist_field->fn = hist_field_string;
else if (field->filter_type == FILTER_DYN_STRING)
-@@ -710,6 +727,12 @@ static struct hist_field *create_hist_fi
+@@ -732,6 +749,12 @@ static struct hist_field *create_hist_fi
else
hist_field->fn = hist_field_pstring;
} else {
@@ -87,7 +87,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
hist_field->fn = select_value_fn(field->size,
field->is_signed);
if (!hist_field->fn) {
-@@ -917,6 +940,11 @@ static struct hist_field *parse_unary(st
+@@ -941,6 +964,11 @@ static struct hist_field *parse_unary(st
expr->operands[0] = operand1;
expr->operator = FIELD_OP_UNARY_MINUS;
expr->name = expr_str(expr, 0);
@@ -99,7 +99,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return expr;
free:
-@@ -1005,6 +1033,11 @@ static struct hist_field *parse_expr(str
+@@ -1029,6 +1057,11 @@ static struct hist_field *parse_expr(str
expr->operands[1] = operand2;
expr->operator = field_op;
expr->name = expr_str(expr, 0);
diff --git a/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch b/patches/0028-tracing-Add-variable-reference-handling-to-hist-trig.patch
index ac5c8d2a971b..c3862a8cbf1d 100644
--- a/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch
+++ b/patches/0028-tracing-Add-variable-reference-handling-to-hist-trig.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:36 -0500
-Subject: [PATCH 24/40] tracing: Add variable reference handling to hist
+Date: Fri, 22 Sep 2017 14:59:59 -0500
+Subject: [PATCH 28/42] tracing: Add variable reference handling to hist
triggers
Add the necessary infrastructure to allow the variables defined on one
@@ -26,13 +26,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/trace/trace.c | 2
kernel/trace/trace.h | 3
- kernel/trace/trace_events_hist.c | 606 ++++++++++++++++++++++++++++++++----
+ kernel/trace/trace_events_hist.c | 613 ++++++++++++++++++++++++++++++++----
kernel/trace/trace_events_trigger.c | 6
- 4 files changed, 561 insertions(+), 56 deletions(-)
+ 4 files changed, 568 insertions(+), 56 deletions(-)
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
-@@ -7755,6 +7755,7 @@ static int instance_mkdir(const char *na
+@@ -7756,6 +7756,7 @@ static int instance_mkdir(const char *na
INIT_LIST_HEAD(&tr->systems);
INIT_LIST_HEAD(&tr->events);
@@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (allocate_trace_buffers(tr, trace_buf_size) < 0)
goto out_free_tr;
-@@ -8498,6 +8499,7 @@ ssize_t trace_parse_run_command(struct f
+@@ -8503,6 +8504,7 @@ ssize_t trace_parse_run_command(struct f
INIT_LIST_HEAD(&global_trace.systems);
INIT_LIST_HEAD(&global_trace.events);
@@ -80,10 +80,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_none(struct hist_field *field,
@@ -215,6 +218,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_VAR = 4096,
- HIST_FIELD_FL_VAR_ONLY = 8192,
- HIST_FIELD_FL_EXPR = 16384,
-+ HIST_FIELD_FL_VAR_REF = 32768,
+ HIST_FIELD_FL_VAR = 1 << 12,
+ HIST_FIELD_FL_VAR_ONLY = 1 << 13,
+ HIST_FIELD_FL_EXPR = 1 << 14,
++ HIST_FIELD_FL_VAR_REF = 1 << 15,
};
struct var_defs {
@@ -451,7 +451,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
field_name = field->name;
if (field_name == NULL)
-@@ -574,6 +915,8 @@ static char *expr_str(struct hist_field
+@@ -596,6 +937,8 @@ static char *expr_str(struct hist_field
return expr;
}
@@ -460,7 +460,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
strcat(expr, hist_field_name(field->operands[0], 0));
if (field->operands[0]->flags) {
const char *flags_str = get_hist_field_flags(field->operands[0]);
-@@ -596,6 +939,8 @@ static char *expr_str(struct hist_field
+@@ -618,6 +961,8 @@ static char *expr_str(struct hist_field
return NULL;
}
@@ -469,7 +469,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
strcat(expr, hist_field_name(field->operands[1], 0));
if (field->operands[1]->flags) {
const char *flags_str = get_hist_field_flags(field->operands[1]);
-@@ -675,6 +1020,11 @@ static struct hist_field *create_hist_fi
+@@ -697,6 +1042,11 @@ static struct hist_field *create_hist_fi
if (flags & HIST_FIELD_FL_EXPR)
goto out; /* caller will populate */
@@ -481,7 +481,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (flags & HIST_FIELD_FL_HITCOUNT) {
hist_field->fn = hist_field_counter;
hist_field->size = sizeof(u64);
-@@ -768,6 +1118,51 @@ static void destroy_hist_fields(struct h
+@@ -790,6 +1140,51 @@ static void destroy_hist_fields(struct h
}
}
@@ -533,7 +533,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static char *field_name_from_var(struct hist_trigger_data *hist_data,
char *var_name)
{
-@@ -779,7 +1174,7 @@ static char *field_name_from_var(struct
+@@ -801,7 +1196,7 @@ static char *field_name_from_var(struct
if (strcmp(var_name, name) == 0) {
field = hist_data->attrs->var_defs.expr[i];
@@ -542,7 +542,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
continue;
return field;
}
-@@ -791,11 +1186,32 @@ static char *field_name_from_var(struct
+@@ -813,11 +1208,32 @@ static char *field_name_from_var(struct
static char *local_field_var_ref(struct hist_trigger_data *hist_data,
char *var_name)
{
@@ -575,7 +575,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct ftrace_event_field *
parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
char *field_str, unsigned long *flags)
-@@ -852,13 +1268,31 @@ struct hist_field *parse_atom(struct his
+@@ -874,13 +1290,39 @@ struct hist_field *parse_atom(struct his
struct trace_event_file *file, char *str,
unsigned long *flags, char *var_name)
{
@@ -593,7 +593,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ s = strchr(++s, '.');
+ if (s) {
+ ref_system = strsep(&str, ".");
++ if (!str) {
++ ret = -EINVAL;
++ goto out;
++ }
+ ref_event = strsep(&str, ".");
++ if (!str) {
++ ret = -EINVAL;
++ goto out;
++ }
+ ref_var = str;
+ }
+ }
@@ -610,7 +618,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
str = s;
field = parse_field(hist_data, file, str, flags);
-@@ -1029,6 +1463,9 @@ static struct hist_field *parse_expr(str
+@@ -1053,6 +1495,9 @@ static struct hist_field *parse_expr(str
goto free;
}
@@ -620,7 +628,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
expr->operands[0] = operand1;
expr->operands[1] = operand2;
expr->operator = field_op;
-@@ -1075,43 +1512,6 @@ static int create_hitcount_val(struct hi
+@@ -1099,43 +1544,6 @@ static int create_hitcount_val(struct hi
return 0;
}
@@ -664,7 +672,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static int __create_val_field(struct hist_trigger_data *hist_data,
unsigned int val_idx,
struct trace_event_file *file,
-@@ -1245,6 +1645,12 @@ static int create_key_field(struct hist_
+@@ -1269,6 +1677,12 @@ static int create_key_field(struct hist_
goto out;
}
@@ -677,7 +685,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
key_size = hist_field->size;
}
-@@ -1580,6 +1986,7 @@ create_hist_data(unsigned int map_bits,
+@@ -1604,6 +2018,7 @@ create_hist_data(unsigned int map_bits,
hist_data->attrs = attrs;
hist_data->remove = remove;
@@ -685,7 +693,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = create_hist_fields(hist_data, file);
if (ret)
-@@ -1602,12 +2009,6 @@ create_hist_data(unsigned int map_bits,
+@@ -1626,12 +2041,6 @@ create_hist_data(unsigned int map_bits,
ret = create_tracing_map_fields(hist_data);
if (ret)
goto free;
@@ -698,7 +706,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
out:
return hist_data;
free:
-@@ -1622,12 +2023,17 @@ create_hist_data(unsigned int map_bits,
+@@ -1646,12 +2055,17 @@ create_hist_data(unsigned int map_bits,
static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
struct tracing_map_elt *elt, void *rec,
@@ -717,7 +725,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
for_each_hist_val_field(i, hist_data) {
hist_field = hist_data->fields[i];
hist_val = hist_field->fn(hist_field, elt, rbe, rec);
-@@ -1680,6 +2086,7 @@ static void event_hist_trigger(struct ev
+@@ -1704,6 +2118,7 @@ static void event_hist_trigger(struct ev
struct hist_trigger_data *hist_data = data->private_data;
bool use_compound_key = (hist_data->n_keys > 1);
unsigned long entries[HIST_STACKTRACE_DEPTH];
@@ -725,7 +733,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
char compound_key[HIST_KEY_SIZE_MAX];
struct tracing_map_elt *elt = NULL;
struct stack_trace stacktrace;
-@@ -1719,9 +2126,15 @@ static void event_hist_trigger(struct ev
+@@ -1743,9 +2158,15 @@ static void event_hist_trigger(struct ev
if (use_compound_key)
key = compound_key;
@@ -743,7 +751,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static void hist_trigger_stacktrace_print(struct seq_file *m,
-@@ -1824,7 +2237,8 @@ hist_trigger_entry_print(struct seq_file
+@@ -1848,7 +2269,8 @@ hist_trigger_entry_print(struct seq_file
field_name = hist_field_name(hist_data->fields[i], 0);
if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR ||
@@ -753,7 +761,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
continue;
if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
-@@ -2074,7 +2488,11 @@ static void event_hist_trigger_free(stru
+@@ -2098,7 +2520,11 @@ static void event_hist_trigger_free(stru
if (!data->ref) {
if (data->name)
del_named_trigger(data);
@@ -765,7 +773,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
destroy_hist_data(hist_data);
}
}
-@@ -2288,23 +2706,55 @@ static int hist_register_trigger(char *g
+@@ -2311,23 +2737,55 @@ static int hist_register_trigger(char *g
goto out;
}
@@ -825,8 +833,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
struct event_trigger_data *data,
struct trace_event_file *file)
-@@ -2335,10 +2785,30 @@ static void hist_unregister_trigger(char
- tracing_set_time_stamp_abs(file->tr, false);
+@@ -2360,10 +2818,29 @@ static void hist_unregister_trigger(char
+ }
}
+static bool hist_file_check_refs(struct trace_event_file *file)
@@ -839,7 +847,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ hist_data = test->private_data;
+ if (check_var_refs(hist_data))
+ return true;
-+ break;
+ }
+ }
+
@@ -856,7 +863,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
list_for_each_entry_safe(test, n, &file->triggers, list) {
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
list_del_rcu(&test->list);
-@@ -2411,6 +2881,11 @@ static int event_hist_trigger_func(struc
+@@ -2436,6 +2913,11 @@ static int event_hist_trigger_func(struc
}
if (remove) {
@@ -868,7 +875,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
ret = 0;
goto out_free;
-@@ -2428,14 +2903,33 @@ static int event_hist_trigger_func(struc
+@@ -2453,14 +2935,33 @@ static int event_hist_trigger_func(struc
goto out_free;
} else if (ret < 0)
goto out_free;
diff --git a/patches/0026-tracing-Add-hist-trigger-action-hook.patch b/patches/0029-tracing-Add-hist-trigger-action-hook.patch
index 5b693de18759..19981d5ec291 100644
--- a/patches/0026-tracing-Add-hist-trigger-action-hook.patch
+++ b/patches/0029-tracing-Add-hist-trigger-action-hook.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:38 -0500
-Subject: [PATCH 26/40] tracing: Add hist trigger action hook
+Date: Fri, 22 Sep 2017 15:00:00 -0500
+Subject: [PATCH 29/42] tracing: Add hist trigger action hook
Add a hook for executing extra actions whenever a histogram entry is
added or updated.
@@ -16,8 +16,8 @@ implemented on top of it in later patches.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 114 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 111 insertions(+), 3 deletions(-)
+ kernel/trace/trace_events_hist.c | 91 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 88 insertions(+), 3 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -88,7 +88,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)
{
int ret = 0;
-@@ -784,8 +816,9 @@ static struct hist_trigger_attrs *parse_
+@@ -800,8 +832,9 @@ static struct hist_trigger_attrs *parse_
else if (strcmp(str, "clear") == 0)
attrs->clear = true;
else {
@@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
}
-@@ -1917,11 +1950,63 @@ static int create_sort_keys(struct hist_
+@@ -1949,11 +1982,42 @@ static int create_sort_keys(struct hist_
return ret;
}
@@ -129,27 +129,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ return ret;
+}
+
-+static void print_actions(struct seq_file *m,
-+ struct hist_trigger_data *hist_data,
-+ struct tracing_map_elt *elt)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < hist_data->n_actions; i++) {
-+ struct action_data *data = hist_data->actions[i];
-+ }
-+}
-+
-+static void print_actions_spec(struct seq_file *m,
-+ struct hist_trigger_data *hist_data)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < hist_data->n_actions; i++) {
-+ struct action_data *data = hist_data->actions[i];
-+ }
-+}
-+
static void destroy_hist_data(struct hist_trigger_data *hist_data)
{
+ if (!hist_data)
@@ -164,7 +143,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_data);
}
-@@ -2080,6 +2165,20 @@ static inline void add_to_key(char *comp
+@@ -2112,6 +2176,20 @@ static inline void add_to_key(char *comp
memcpy(compound_key + key_field->offset, key, size);
}
@@ -185,7 +164,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void event_hist_trigger(struct event_trigger_data *data, void *rec,
struct ring_buffer_event *rbe)
{
-@@ -2135,6 +2234,9 @@ static void event_hist_trigger(struct ev
+@@ -2167,6 +2245,9 @@ static void event_hist_trigger(struct ev
return;
hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals);
@@ -195,16 +174,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static void hist_trigger_stacktrace_print(struct seq_file *m,
-@@ -2450,6 +2552,8 @@ static int event_hist_trigger_print(stru
- }
- seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
-
-+ print_actions_spec(m, hist_data);
-+
- if (data->filter_str)
- seq_printf(m, " if %s", data->filter_str);
-
-@@ -2910,6 +3014,10 @@ static int event_hist_trigger_func(struc
+@@ -2942,6 +3023,10 @@ static int event_hist_trigger_func(struc
if (has_hist_vars(hist_data))
save_hist_vars(hist_data);
@@ -215,7 +185,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = tracing_map_init(hist_data->map);
if (ret)
goto out_unreg;
-@@ -2931,8 +3039,8 @@ static int event_hist_trigger_func(struc
+@@ -2963,8 +3048,8 @@ static int event_hist_trigger_func(struc
remove_hist_vars(hist_data);
kfree(trigger_data);
diff --git a/patches/0027-tracing-Add-support-for-synthetic-events.patch b/patches/0030-tracing-Add-support-for-synthetic-events.patch
index 945a4d9c6e19..06af7d6bbd77 100644
--- a/patches/0027-tracing-Add-support-for-synthetic-events.patch
+++ b/patches/0030-tracing-Add-support-for-synthetic-events.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:39 -0500
-Subject: [PATCH 27/40] tracing: Add support for 'synthetic' events
+Date: Fri, 22 Sep 2017 15:00:01 -0500
+Subject: [PATCH 30/42] tracing: Add support for 'synthetic' events
Synthetic events are user-defined events generated from hist trigger
variables saved from one or more other events.
@@ -47,8 +47,8 @@ discussed in a subsequent patch.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 863 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 863 insertions(+)
+ kernel/trace/trace_events_hist.c | 865 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 865 insertions(+)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -96,7 +96,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct action_data;
typedef void (*action_fn_t) (struct hist_trigger_data *hist_data,
-@@ -282,6 +308,798 @@ struct action_data {
+@@ -282,6 +308,800 @@ struct action_data {
unsigned int var_ref_idx;
};
@@ -174,7 +174,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ return -EINVAL;
+
+ len = end - start;
-+ if (len > 2)
++ if (len > 3)
+ return -EINVAL;
+
+ strncpy(buf, start, len);
@@ -297,12 +297,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ if (tr->trace_flags & TRACE_ITER_VERBOSE)
+ trace_seq_printf(s, "%s ", fmt);
+
-+ sprintf(print_fmt, "%%s=%s%%s", fmt);
++ snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
+
+ /* parameter values */
+ if (se->fields[i]->is_string) {
+ trace_seq_printf(s, print_fmt, se->fields[i]->name,
-+ (char *)entry->fields[n_u64],
++ (char *)(long)entry->fields[n_u64],
+ i == se->n_fields - 1 ? "" : " ");
+ n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
+ } else {
@@ -347,7 +347,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+ for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
+ if (event->fields[i]->is_string) {
-+ char *str_val = (char *)var_ref_vals[var_ref_idx + i];
++ char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i];
+ char *str_field = (char *)&entry->fields[n_u64];
+
+ strncpy(str_field, str_val, STR_VAR_LEN_MAX);
@@ -363,8 +363,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+static void free_synth_event_print_fmt(struct trace_event_call *call)
+{
-+ if (call)
++ if (call) {
+ kfree(call->print_fmt);
++ call->print_fmt = NULL;
++ }
+}
+
+static int __set_synth_event_print_fmt(struct synth_event *event,
@@ -493,27 +495,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+static struct tracepoint *alloc_synth_tracepoint(char *name)
+{
+ struct tracepoint *tp;
-+ int ret = 0;
+
+ tp = kzalloc(sizeof(*tp), GFP_KERNEL);
-+ if (!tp) {
-+ ret = -ENOMEM;
-+ goto free;
-+ }
++ if (!tp)
++ return ERR_PTR(-ENOMEM);
+
+ tp->name = kstrdup(name, GFP_KERNEL);
+ if (!tp->name) {
-+ ret = -ENOMEM;
-+ goto free;
++ kfree(tp);
++ return ERR_PTR(-ENOMEM);
+ }
+
-+ tp->dynamic = true;
-+
+ return tp;
-+ free:
-+ free_synth_tracepoint(tp);
-+
-+ return ERR_PTR(ret);
+}
+
+typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals,
@@ -535,8 +528,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ probe_func_ptr = rcu_dereference_sched((tp)->funcs);
+ if (probe_func_ptr) {
+ do {
-+ probe_func = (probe_func_ptr)->func;
-+ __data = (probe_func_ptr)->data;
++ probe_func = probe_func_ptr->func;
++ __data = probe_func_ptr->data;
+ probe_func(__data, var_ref_vals, var_ref_idx);
+ } while ((++probe_func_ptr)->func);
+ }
@@ -555,6 +548,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ return NULL;
+}
+
++/* This function releases synth_event_mutex */
+static int register_synth_event(struct synth_event *event)
+{
+ struct trace_event_call *call = &event->call;
@@ -589,6 +583,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ call->data = event;
+ call->tp = event->tp;
+
++ /*
++ * trace_add_event_call() grabs event_mutex, but that can
++ * deadlock with a hist trigger cmd already holding it that
++ * can grab synth_event_mutex
++ */
+ mutex_unlock(&synth_event_mutex);
+ ret = trace_add_event_call(call);
+ mutex_lock(&synth_event_mutex);
@@ -612,6 +611,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ goto out;
+}
+
++/* This function releases synth_event_mutex */
+static int unregister_synth_event(struct synth_event *event)
+{
+ struct trace_event_call *call = &event->call;
@@ -620,20 +620,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ mutex_unlock(&synth_event_mutex);
+ ret = trace_remove_event_call(call);
+ mutex_lock(&synth_event_mutex);
-+ if (ret) {
-+ pr_warn("Failed to remove synthetic event: %s\n",
-+ trace_event_name(call));
-+ free_synth_event_print_fmt(call);
-+ unregister_trace_event(&call->event);
-+ }
+
+ return ret;
+}
+
-+static void remove_synth_event(struct synth_event *event)
++static int remove_synth_event(struct synth_event *event)
+{
-+ unregister_synth_event(event);
-+ list_del(&event->list);
++ int ret = unregister_synth_event(event);
++
++ if (!ret)
++ list_del(&event->list);
++
++ return ret;
+}
+
+static int add_synth_event(struct synth_event *event)
@@ -701,6 +699,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ return event;
+}
+
++/* This function releases synth_event_mutex */
+static int create_synth_event(int argc, char **argv)
+{
+ struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
@@ -735,8 +734,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ ret = -EBUSY;
+ goto out;
+ }
-+ remove_synth_event(event);
-+ free_synth_event(event);
++ ret = remove_synth_event(event);
++ if (!ret)
++ free_synth_event(event);
+ goto out;
+ }
+ ret = -EEXIST;
@@ -793,6 +793,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ goto out;
+}
+
++/* This function releases synth_event_mutex */
+static int release_all_synth_events(void)
+{
+ struct synth_event *event, *e;
@@ -808,8 +809,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ }
+
+ list_for_each_entry_safe(event, e, &synth_event_list, list) {
-+ remove_synth_event(event);
-+ free_synth_event(event);
++ ret = remove_synth_event(event);
++ if (!ret)
++ free_synth_event(event);
+ }
+ out:
+ mutex_unlock(&synth_event_mutex);
@@ -895,7 +897,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static u64 hist_field_timestamp(struct hist_field *hist_field,
struct tracing_map_elt *elt,
struct ring_buffer_event *rbe,
-@@ -2933,6 +3751,8 @@ static int event_hist_trigger_func(struc
+@@ -2942,6 +3762,8 @@ static int event_hist_trigger_func(struc
struct hist_trigger_attrs *attrs;
struct event_trigger_ops *trigger_ops;
struct hist_trigger_data *hist_data;
@@ -904,7 +906,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
bool remove = false;
char *trigger;
int ret = 0;
-@@ -2991,6 +3811,14 @@ static int event_hist_trigger_func(struc
+@@ -3000,6 +3822,14 @@ static int event_hist_trigger_func(struc
}
cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
@@ -919,7 +921,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = 0;
goto out_free;
}
-@@ -3008,6 +3836,13 @@ static int event_hist_trigger_func(struc
+@@ -3017,6 +3847,13 @@ static int event_hist_trigger_func(struc
} else if (ret < 0)
goto out_free;
@@ -933,7 +935,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (get_named_trigger_data(trigger_data))
goto enable;
-@@ -3198,3 +4033,31 @@ static __init void unregister_trigger_hi
+@@ -3207,3 +4044,31 @@ static __init void unregister_trigger_hi
return ret;
}
diff --git a/patches/0028-tracing-Add-support-for-field-variables.patch b/patches/0031-tracing-Add-support-for-field-variables.patch
index ecadd73b2aaf..cc1addb9c0ee 100644
--- a/patches/0028-tracing-Add-support-for-field-variables.patch
+++ b/patches/0031-tracing-Add-support-for-field-variables.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:40 -0500
-Subject: [PATCH 28/40] tracing: Add support for 'field variables'
+Date: Fri, 22 Sep 2017 15:00:02 -0500
+Subject: [PATCH 31/42] tracing: Add support for 'field variables'
Users should be able to directly specify event fields in hist trigger
'actions' rather than being forced to explicitly create a variable for
@@ -13,11 +13,35 @@ on another (matching) event, it even creates a special histogram for
the purpose (since variables can't be defined on an existing histogram
after histogram creation).
+Here's a simple example that demonstrates both. Basically the
+onmatch() action creates a list of variables corresponding to the
+parameters of the synthetic event to be generated, and then uses those
+values to generate the event. So for the wakeup_latency synthetic
+event 'call' below the first param, $wakeup_lat, is a variable defined
+explicitly on sched_switch, where 'next_pid' is just a normal field on
+sched_switch, and prio is a normal field on sched_waking.
+
+Since the mechanism works on variables, those two normal fields just
+have 'invisible' variables created internally for them. In the case of
+'prio', which is on another event, we actually need to create an
+additional hist trigger and define the invisible event on that, since
+once a hist trigger is defined, variables can't be added to it later.
+
+ echo 'wakeup_latency u64 lat; pid_t pid; int prio' >>
+ /sys/kernel/debug/tracing/synthetic_events
+
+ echo 'hist:keys=pid:ts0=$common_timestamp.usecs >>
+ /sys/kernel/debug/tracing/events/sched/sched_waking/trigger
+
+echo 'hist:keys=next_pid:wakeup_lat=$common_timestamp.usecs-$ts0:
+ onmatch(sched.sched_waking).wakeup_latency($wakeup_lat,next_pid,prio)
+ >> /sys/kernel/debug/tracing/events/sched/sched_switch/trigger
+
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 452 ++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 451 insertions(+), 1 deletion(-)
+ kernel/trace/trace_events_hist.c | 450 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 449 insertions(+), 1 deletion(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -53,7 +77,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
struct synth_field {
-@@ -1392,6 +1410,7 @@ static struct hist_field *find_event_var
+@@ -1394,6 +1412,7 @@ static struct hist_field *find_event_var
struct hist_elt_data {
char *comm;
u64 *var_ref_vals;
@@ -61,31 +85,28 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
static u64 hist_field_var_ref(struct hist_field *hist_field,
-@@ -1669,7 +1688,14 @@ static inline void save_comm(char *comm,
+@@ -1687,6 +1706,11 @@ static inline void save_comm(char *comm,
- static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
+ static void hist_elt_data_free(struct hist_elt_data *elt_data)
{
-+ struct hist_trigger_data *hist_data = elt->map->private_data;
- struct hist_elt_data *private_data = elt->private_data;
-+ unsigned int i, n_str;
++ unsigned int i;
+
-+ n_str = hist_data->n_field_var_str;
++ for (i = 0; i < SYNTH_FIELDS_MAX; i++)
++ kfree(elt_data->field_var_str[i]);
+
-+ for (i = 0; i < n_str; i++)
-+ kfree(private_data->field_var_str[i]);
-
- kfree(private_data->comm);
- kfree(private_data);
-@@ -1681,7 +1707,7 @@ static int hist_trigger_elt_data_alloc(s
+ kfree(elt_data->comm);
+ kfree(elt_data);
+ }
+@@ -1704,7 +1728,7 @@ static int hist_trigger_elt_data_alloc(s
unsigned int size = TASK_COMM_LEN + 1;
struct hist_elt_data *elt_data;
struct hist_field *key_field;
- unsigned int i;
+ unsigned int i, n_str;
- elt->private_data = elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
+ elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
if (!elt_data)
-@@ -1701,6 +1727,18 @@ static int hist_trigger_elt_data_alloc(s
+@@ -1723,6 +1747,18 @@ static int hist_trigger_elt_data_alloc(s
}
}
@@ -96,15 +117,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ for (i = 0; i < n_str; i++) {
+ elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL);
+ if (!elt_data->field_var_str[i]) {
-+ hist_trigger_elt_data_free(elt);
++ hist_elt_data_free(elt_data);
+ return -ENOMEM;
+ }
+ }
+
- return 0;
- }
+ elt->private_data = elt_data;
-@@ -2347,6 +2385,387 @@ static struct hist_field *parse_expr(str
+ return 0;
+@@ -2381,6 +2417,387 @@ static struct hist_field *parse_expr(str
return ERR_PTR(ret);
}
@@ -492,8 +513,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static int create_hitcount_val(struct hist_trigger_data *hist_data)
{
hist_data->fields[HITCOUNT_IDX] =
-@@ -2814,6 +3233,16 @@ static void print_actions_spec(struct se
- }
+@@ -2827,6 +3244,16 @@ static int create_actions(struct hist_tr
+ return ret;
}
+static void destroy_field_var_hists(struct hist_trigger_data *hist_data)
@@ -509,7 +530,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void destroy_hist_data(struct hist_trigger_data *hist_data)
{
if (!hist_data)
-@@ -2824,6 +3253,8 @@ static void destroy_hist_data(struct his
+@@ -2837,6 +3264,8 @@ static void destroy_hist_data(struct his
tracing_map_destroy(hist_data->map);
destroy_actions(hist_data);
@@ -518,7 +539,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_data);
}
-@@ -2957,6 +3388,8 @@ static void hist_trigger_elt_update(stru
+@@ -2970,6 +3399,8 @@ static void hist_trigger_elt_update(stru
tracing_map_set_var(elt, var_idx, hist_val);
}
}
@@ -527,7 +548,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static inline void add_to_key(char *compound_key, void *key,
-@@ -3677,6 +4110,21 @@ static bool hist_trigger_check_refs(stru
+@@ -3687,6 +4118,21 @@ static bool hist_trigger_check_refs(stru
return false;
}
@@ -549,7 +570,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
struct event_trigger_data *data,
struct trace_event_file *file)
-@@ -3692,6 +4140,7 @@ static void hist_unregister_trigger(char
+@@ -3702,6 +4148,7 @@ static void hist_unregister_trigger(char
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
if (!hist_trigger_match(data, test, named_data, false))
continue;
@@ -557,7 +578,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
unregistered = true;
list_del_rcu(&test->list);
trace_event_trigger_enable_disable(file, 0);
-@@ -3733,6 +4182,7 @@ static void hist_unreg_all(struct trace_
+@@ -3744,6 +4191,7 @@ static void hist_unreg_all(struct trace_
list_for_each_entry_safe(test, n, &file->triggers, list) {
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
diff --git a/patches/0029-tracing-Add-onmatch-hist-trigger-action-support.patch b/patches/0032-tracing-Add-onmatch-hist-trigger-action-support.patch
index 85b59bde2318..ba623ffffb44 100644
--- a/patches/0029-tracing-Add-onmatch-hist-trigger-action-support.patch
+++ b/patches/0032-tracing-Add-onmatch-hist-trigger-action-support.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:41 -0500
-Subject: [PATCH 29/40] tracing: Add 'onmatch' hist trigger action support
+Date: Fri, 22 Sep 2017 15:00:03 -0500
+Subject: [PATCH 32/42] tracing: Add 'onmatch' hist trigger action support
Add an 'onmatch(matching.event).<synthetic_event_name>(param list)'
hist trigger action which is invoked with the set of variables or
@@ -39,10 +39,11 @@ tracing/events/synthetic directory, as usual:
/sys/kernel/debug/tracing/events/synthetic/wakeup_new_test/trigger
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Rajvi Jingar <rajvi.jingar@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 394 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 382 insertions(+), 12 deletions(-)
+ kernel/trace/trace_events_hist.c | 406 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 394 insertions(+), 12 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -66,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
static LIST_HEAD(synth_event_list);
-@@ -927,6 +938,21 @@ static struct synth_event *alloc_synth_e
+@@ -925,6 +936,21 @@ static struct synth_event *alloc_synth_e
return event;
}
@@ -85,9 +86,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ struct hist_trigger_data *hist_data;
+};
+
+ /* This function releases synth_event_mutex */
static int create_synth_event(int argc, char **argv)
{
- struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
@@ -967,10 +993,8 @@ static int create_synth_event(int argc,
}
ret = -EEXIST;
@@ -100,7 +101,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (argc < 2) {
ret = -EINVAL;
-@@ -1134,11 +1158,6 @@ static u64 hist_field_timestamp(struct h
+@@ -1136,11 +1160,6 @@ static u64 hist_field_timestamp(struct h
return ts;
}
@@ -112,7 +113,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_field *check_var_ref(struct hist_field *hist_field,
struct hist_trigger_data *var_data,
unsigned int var_idx)
-@@ -1578,11 +1597,21 @@ static void destroy_hist_trigger_attrs(s
+@@ -1580,11 +1599,21 @@ static void destroy_hist_trigger_attrs(s
static int parse_action(char *str, struct hist_trigger_attrs *attrs)
{
@@ -135,7 +136,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ret;
}
-@@ -2420,7 +2449,7 @@ static bool compatible_keys(struct hist_
+@@ -2452,7 +2481,7 @@ static bool compatible_keys(struct hist_
for (n = 0; n < n_keys; n++) {
hist_field = hist_data->fields[i + n];
@@ -144,7 +145,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (strcmp(hist_field->type, target_hist_field->type) != 0)
return false;
-@@ -2738,6 +2767,27 @@ create_target_field_var(struct hist_trig
+@@ -2770,6 +2799,27 @@ create_target_field_var(struct hist_trig
return create_field_var(hist_data, file, var_name);
}
@@ -161,18 +162,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ for (i = 0; i < data->n_params; i++)
+ kfree(data->params[i]);
+
-+ kfree(data);
-+
+ if (data->onmatch.synth_event)
+ data->onmatch.synth_event->ref--;
+
++ kfree(data);
++
+ mutex_unlock(&synth_event_mutex);
+}
+
static void destroy_field_var(struct field_var *field_var)
{
if (!field_var)
-@@ -2766,6 +2816,281 @@ static void save_field_var(struct hist_t
+@@ -2798,6 +2848,283 @@ static void save_field_var(struct hist_t
hist_data->n_field_var_str++;
}
@@ -221,8 +222,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ goto out;
+
+ param = strsep(&params, ",");
-+ if (!param)
++ if (!param) {
++ ret = -EINVAL;
+ goto out;
++ }
+
+ param = strstrip(param);
+ if (strlen(param) < 2) {
@@ -309,12 +312,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ int ret = 0;
+
+ mutex_lock(&synth_event_mutex);
-+
+ event = find_synth_event(data->onmatch.synth_event_name);
+ if (!event) {
-+ ret = -EINVAL;
-+ goto out;
++ mutex_unlock(&synth_event_mutex);
++ return -EINVAL;
+ }
++ mutex_unlock(&synth_event_mutex);
+
+ var_ref_idx = hist_data->n_var_refs;
+
@@ -322,8 +325,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ char *p;
+
+ p = param = kstrdup(data->params[i], GFP_KERNEL);
-+ if (!param)
++ if (!param) {
++ ret = -ENOMEM;
+ goto out;
++ }
+
+ system = strsep(&param, ".");
+ if (!param) {
@@ -383,8 +388,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ hist_data->actions[hist_data->n_actions++] = data;
+ event->ref++;
+ out:
-+ mutex_unlock(&synth_event_mutex);
-+
+ return ret;
+}
+
@@ -454,7 +457,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static int create_hitcount_val(struct hist_trigger_data *hist_data)
{
hist_data->fields[HITCOUNT_IDX] =
-@@ -3194,19 +3519,38 @@ static void destroy_actions(struct hist_
+@@ -3226,24 +3553,76 @@ static void destroy_actions(struct hist_
for (i = 0; i < hist_data->n_actions; i++) {
struct action_data *data = hist_data->actions[i];
@@ -494,8 +497,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
return ret;
-@@ -3223,6 +3567,26 @@ static void print_actions(struct seq_fil
- }
}
+static void print_onmatch_spec(struct seq_file *m,
@@ -518,20 +519,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ seq_puts(m, ")");
+}
+
- static void print_actions_spec(struct seq_file *m,
- struct hist_trigger_data *hist_data)
- {
-@@ -3230,6 +3594,9 @@ static void print_actions_spec(struct se
-
- for (i = 0; i < hist_data->n_actions; i++) {
- struct action_data *data = hist_data->actions[i];
++static void print_actions_spec(struct seq_file *m,
++ struct hist_trigger_data *hist_data)
++{
++ unsigned int i;
++
++ for (i = 0; i < hist_data->n_actions; i++) {
++ struct action_data *data = hist_data->actions[i];
+
+ if (data->fn == action_trace)
+ print_onmatch_spec(m, hist_data, data);
- }
- }
-
-@@ -3255,6 +3622,7 @@ static void destroy_hist_data(struct his
++ }
++}
++
+ static void destroy_field_var_hists(struct hist_trigger_data *hist_data)
+ {
+ unsigned int i;
+@@ -3266,6 +3645,7 @@ static void destroy_hist_data(struct his
destroy_actions(hist_data);
destroy_field_vars(hist_data);
destroy_field_var_hists(hist_data);
@@ -539,12 +543,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(hist_data);
}
-@@ -3603,6 +3971,8 @@ hist_trigger_entry_print(struct seq_file
- }
+@@ -3814,6 +4194,8 @@ static int event_hist_trigger_print(stru
}
+ seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
-+ print_actions(m, hist_data, elt);
++ print_actions_spec(m, hist_data);
+
- seq_puts(m, "\n");
- }
+ if (data->filter_str)
+ seq_printf(m, " if %s", data->filter_str);
diff --git a/patches/0030-tracing-Add-onmax-hist-trigger-action-support.patch b/patches/0033-tracing-Add-onmax-hist-trigger-action-support.patch
index 61c4e76e3a7b..a7a345dc91ea 100644
--- a/patches/0030-tracing-Add-onmax-hist-trigger-action-support.patch
+++ b/patches/0033-tracing-Add-onmax-hist-trigger-action-support.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:42 -0500
-Subject: [PATCH 30/40] tracing: Add 'onmax' hist trigger action support
+Date: Fri, 22 Sep 2017 15:00:04 -0500
+Subject: [PATCH 33/42] tracing: Add 'onmax' hist trigger action support
Add an 'onmax(var).save(field,...)' hist trigger action which is
invoked whenever an event exceeds the current maximum.
@@ -54,8 +54,8 @@ fields:
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 313 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 279 insertions(+), 34 deletions(-)
+ kernel/trace/trace_events_hist.c | 332 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 297 insertions(+), 35 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -85,7 +85,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
};
-@@ -1602,7 +1614,8 @@ static int parse_action(char *str, struc
+@@ -1604,7 +1616,8 @@ static int parse_action(char *str, struc
if (attrs->n_actions >= HIST_ACTIONS_MAX)
return ret;
@@ -95,16 +95,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
if (!attrs->action_str[attrs->n_actions]) {
ret = -ENOMEM;
-@@ -1721,7 +1734,7 @@ static void hist_trigger_elt_data_free(s
- struct hist_elt_data *private_data = elt->private_data;
- unsigned int i, n_str;
-
-- n_str = hist_data->n_field_var_str;
-+ n_str = hist_data->n_field_var_str + hist_data->n_max_var_str;
-
- for (i = 0; i < n_str; i++)
- kfree(private_data->field_var_str[i]);
-@@ -1756,7 +1769,7 @@ static int hist_trigger_elt_data_alloc(s
+@@ -1776,7 +1789,7 @@ static int hist_trigger_elt_data_alloc(s
}
}
@@ -113,7 +104,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
size = STR_VAR_LEN_MAX;
-@@ -2658,6 +2671,15 @@ static void update_field_vars(struct his
+@@ -2690,6 +2703,15 @@ static void update_field_vars(struct his
hist_data->n_field_vars, 0);
}
@@ -129,7 +120,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_field *create_var(struct hist_trigger_data *hist_data,
struct trace_event_file *file,
char *name, int size, const char *type)
-@@ -2767,6 +2789,223 @@ create_target_field_var(struct hist_trig
+@@ -2799,6 +2821,229 @@ create_target_field_var(struct hist_trig
return create_field_var(hist_data, file, var_name);
}
@@ -245,8 +236,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+ for (i = 0; i < data->n_params; i++) {
+ param = kstrdup(data->params[i], GFP_KERNEL);
-+ if (!param)
++ if (!param) {
++ ret = -ENOMEM;
+ goto out;
++ }
+
+ field_var = create_target_field_var(hist_data, NULL, NULL, param);
+ if (IS_ERR(field_var)) {
@@ -277,8 +270,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ goto out;
+
+ param = strsep(&params, ",");
-+ if (!param)
++ if (!param) {
++ ret = -EINVAL;
+ goto out;
++ }
+
+ param = strstrip(param);
+ if (strlen(param) < 2) {
@@ -328,8 +323,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ if (strncmp(onmax_fn_name, "save", strlen("save")) == 0) {
+ char *params = strsep(&str, ")");
+
-+ if (!params)
++ if (!params) {
++ ret = -EINVAL;
+ goto free;
++ }
+
+ ret = parse_action_params(params, data);
+ if (ret)
@@ -353,7 +350,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void onmatch_destroy(struct action_data *data)
{
unsigned int i;
-@@ -2851,37 +3090,6 @@ static int check_synth_field(struct synt
+@@ -2883,39 +3128,6 @@ static int check_synth_field(struct synt
return 0;
}
@@ -367,8 +364,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- goto out;
-
- param = strsep(&params, ",");
-- if (!param)
+- if (!param) {
+- ret = -EINVAL;
- goto out;
+- }
-
- param = strstrip(param);
- if (strlen(param) < 2) {
@@ -391,7 +390,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_field *
onmatch_find_var(struct hist_trigger_data *hist_data, struct action_data *data,
char *system, char *event, char *var)
-@@ -3521,6 +3729,8 @@ static void destroy_actions(struct hist_
+@@ -3555,6 +3767,8 @@ static void destroy_actions(struct hist_
if (data->fn == action_trace)
onmatch_destroy(data);
@@ -400,7 +399,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
else
kfree(data);
}
-@@ -3550,6 +3760,18 @@ static int create_actions(struct hist_tr
+@@ -3584,12 +3798,56 @@ static int create_actions(struct hist_tr
onmatch_destroy(data);
return ret;
}
@@ -419,16 +418,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
}
-@@ -3564,9 +3786,30 @@ static void print_actions(struct seq_fil
+ return ret;
+ }
- for (i = 0; i < hist_data->n_actions; i++) {
- struct action_data *data = hist_data->actions[i];
++static void print_actions(struct seq_file *m,
++ struct hist_trigger_data *hist_data,
++ struct tracing_map_elt *elt)
++{
++ unsigned int i;
++
++ for (i = 0; i < hist_data->n_actions; i++) {
++ struct action_data *data = hist_data->actions[i];
+
+ if (data->fn == onmax_save)
+ onmax_print(m, hist_data, elt, data);
- }
- }
-
++ }
++}
++
+static void print_onmax_spec(struct seq_file *m,
+ struct hist_trigger_data *hist_data,
+ struct action_data *data)
@@ -450,7 +456,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static void print_onmatch_spec(struct seq_file *m,
struct hist_trigger_data *hist_data,
struct action_data *data)
-@@ -3597,6 +3840,8 @@ static void print_actions_spec(struct se
+@@ -3620,6 +3878,8 @@ static void print_actions_spec(struct se
if (data->fn == action_trace)
print_onmatch_spec(m, hist_data, data);
@@ -459,3 +465,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
}
+@@ -3994,6 +4254,8 @@ hist_trigger_entry_print(struct seq_file
+ }
+ }
+
++ print_actions(m, hist_data, elt);
++
+ seq_puts(m, "\n");
+ }
+
diff --git a/patches/0031-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch b/patches/0034-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch
index 1694bb042120..94ced8362605 100644
--- a/patches/0031-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch
+++ b/patches/0034-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch
@@ -1,21 +1,24 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:43 -0500
-Subject: [PATCH 31/40] tracing: Allow whitespace to surround hist trigger
+Date: Fri, 22 Sep 2017 15:00:05 -0500
+Subject: [PATCH 34/42] tracing: Allow whitespace to surround hist trigger
filter
The existing code only allows for one space before and after the 'if'
specifying the filter for a hist trigger. Add code to make that more
-permissive as far as whitespace goes.
+permissive as far as whitespace goes. Specifically, we want to allow
+spaces in the trigger itself now that we have additional syntax
+(onmatch/onmax) where spaces are more natural e.g. spaces after commas
+in param lists.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- kernel/trace/trace_events_hist.c | 19 +++++++++++++++----
- 1 file changed, 15 insertions(+), 4 deletions(-)
+ kernel/trace/trace_events_hist.c | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
-@@ -4819,7 +4819,7 @@ static int event_hist_trigger_func(struc
+@@ -4857,7 +4857,7 @@ static int event_hist_trigger_func(struc
struct synth_event *se;
const char *se_name;
bool remove = false;
@@ -24,13 +27,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
int ret = 0;
if (!param)
-@@ -4829,9 +4829,19 @@ static int event_hist_trigger_func(struc
+@@ -4866,10 +4866,23 @@ static int event_hist_trigger_func(struc
+ if (glob[0] == '!')
remove = true;
- /* separate the trigger from the filter (k:v [if filter]) */
+- /* separate the trigger from the filter (k:v [if filter]) */
- trigger = strsep(&param, " \t");
- if (!trigger)
- return -EINVAL;
++ /*
++ * separate the trigger from the filter (k:v [if filter])
++ * allowing for whitespace in the trigger
++ */
+ trigger = param;
+ p = strstr(param, " if");
+ if (!p)
@@ -47,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
attrs = parse_hist_trigger_attrs(trigger);
if (IS_ERR(attrs))
-@@ -4889,6 +4899,7 @@ static int event_hist_trigger_func(struc
+@@ -4927,6 +4940,7 @@ static int event_hist_trigger_func(struc
}
ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
diff --git a/patches/0032-tracing-Add-cpu-field-for-hist-triggers.patch b/patches/0035-tracing-Add-cpu-field-for-hist-triggers.patch
index 099409f5133f..b267870e9133 100644
--- a/patches/0032-tracing-Add-cpu-field-for-hist-triggers.patch
+++ b/patches/0035-tracing-Add-cpu-field-for-hist-triggers.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:44 -0500
-Subject: [PATCH 32/40] tracing: Add cpu field for hist triggers
+Date: Fri, 22 Sep 2017 15:00:06 -0500
+Subject: [PATCH 35/42] tracing: Add cpu field for hist triggers
A common key to use in a histogram is the cpuid - add a new cpu
'synthetic' field for that purpose. This field is named cpu rather
@@ -12,8 +12,8 @@ Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
Documentation/trace/events.txt | 18 ++++++++++++++++++
- kernel/trace/trace_events_hist.c | 30 +++++++++++++++++++++++++++---
- 2 files changed, 45 insertions(+), 3 deletions(-)
+ kernel/trace/trace_events_hist.c | 28 +++++++++++++++++++++++++++-
+ 2 files changed, 45 insertions(+), 1 deletion(-)
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -21,15 +21,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
The examples below provide a more concrete illustration of the
concepts and typical usage patterns discussed above.
-+ 'synthetic' event fields
++ 'special' event fields
+ ------------------------
+
-+ There are a number of 'synthetic fields' available for use as keys
-+ or values in a hist trigger. These look like and behave as if they
-+ were event fields, but aren't actually part of the event's field
-+ definition or format file. They are however available for any
++ There are a number of 'special event fields' available for use as
++ keys or values in a hist trigger. These look like and behave as if
++ they were actual event fields, but aren't really part of the event's
++ field definition or format file. They are however available for any
+ event, and can be used anywhere an actual event field could be.
-+ 'Synthetic' field names are always prefixed with a '$' character to
++ 'Special' field names are always prefixed with a '$' character to
+ indicate that they're not normal fields (with the exception of
+ 'cpu', for compatibility with existing filter usage):
+
@@ -45,14 +45,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -226,6 +226,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_VAR_ONLY = 8192,
- HIST_FIELD_FL_EXPR = 16384,
- HIST_FIELD_FL_VAR_REF = 32768,
-+ HIST_FIELD_FL_CPU = 65536,
+ HIST_FIELD_FL_VAR_ONLY = 1 << 13,
+ HIST_FIELD_FL_EXPR = 1 << 14,
+ HIST_FIELD_FL_VAR_REF = 1 << 15,
++ HIST_FIELD_FL_CPU = 1 << 16,
};
struct var_defs {
-@@ -1170,6 +1171,16 @@ static u64 hist_field_timestamp(struct h
+@@ -1172,6 +1173,16 @@ static u64 hist_field_timestamp(struct h
return ts;
}
@@ -61,7 +61,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ struct ring_buffer_event *rbe,
+ void *event)
+{
-+ int cpu = raw_smp_processor_id();
++ int cpu = smp_processor_id();
+
+ return cpu;
+}
@@ -69,7 +69,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static struct hist_field *check_var_ref(struct hist_field *hist_field,
struct hist_trigger_data *var_data,
unsigned int var_idx)
-@@ -1518,6 +1529,8 @@ static const char *hist_field_name(struc
+@@ -1520,6 +1531,8 @@ static const char *hist_field_name(struc
field_name = hist_field_name(field->operands[0], ++level);
else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
field_name = "$common_timestamp";
@@ -78,7 +78,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
else if (field->flags & HIST_FIELD_FL_EXPR ||
field->flags & HIST_FIELD_FL_VAR_REF)
field_name = field->name;
-@@ -1990,6 +2003,15 @@ static struct hist_field *create_hist_fi
+@@ -2012,6 +2025,15 @@ static struct hist_field *create_hist_fi
goto out;
}
@@ -94,7 +94,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (WARN_ON_ONCE(!field))
goto out;
-@@ -2182,7 +2204,9 @@ parse_field(struct hist_trigger_data *hi
+@@ -2204,7 +2226,9 @@ parse_field(struct hist_trigger_data *hi
hist_data->enable_timestamps = true;
if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
hist_data->attrs->ts_in_usecs = true;
@@ -105,23 +105,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
field = trace_find_event_field(file->event_call, field_name);
if (!field || !field->size) {
field = ERR_PTR(-EINVAL);
-@@ -3185,7 +3209,6 @@ static int onmatch_create(struct hist_tr
- goto out;
- }
- }
--
- if (param[0] == '$')
- hist_field = onmatch_find_var(hist_data, data, system,
- event_name, param);
-@@ -3200,7 +3223,6 @@ static int onmatch_create(struct hist_tr
- ret = -EINVAL;
- goto out;
- }
--
- if (check_synth_field(event, hist_field, field_pos) == 0) {
- var_ref = create_var_ref(hist_field);
- if (!var_ref) {
-@@ -4315,6 +4337,8 @@ static void hist_field_print(struct seq_
+@@ -4353,6 +4377,8 @@ static void hist_field_print(struct seq_
if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
seq_puts(m, "$common_timestamp");
diff --git a/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch b/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch
deleted file mode 100644
index a90762ed786c..000000000000
--- a/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:47 -0500
-Subject: [PATCH 35/40] tracing: Reverse the order event_mutex/trace_types_lock
- are taken
-
-Change the order event_mutex and trace_types_lock are taken, to avoid
-circular dependencies and lockdep spew.
-
-Changing the order shouldn't matter to any current code, but does to
-anything that takes the event_mutex first and then trace_types_lock.
-This is the case when calling tracing_set_clock from inside an event
-command, which already holds the event_mutex.
-
-Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- kernel/trace/trace_events.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/kernel/trace/trace_events.c
-+++ b/kernel/trace/trace_events.c
-@@ -1406,8 +1406,8 @@ static int subsystem_open(struct inode *
- return -ENODEV;
-
- /* Make sure the system still exists */
-- mutex_lock(&trace_types_lock);
- mutex_lock(&event_mutex);
-+ mutex_lock(&trace_types_lock);
- list_for_each_entry(tr, &ftrace_trace_arrays, list) {
- list_for_each_entry(dir, &tr->systems, list) {
- if (dir == inode->i_private) {
-@@ -1421,8 +1421,8 @@ static int subsystem_open(struct inode *
- }
- }
- exit_loop:
-- mutex_unlock(&event_mutex);
- mutex_unlock(&trace_types_lock);
-+ mutex_unlock(&event_mutex);
-
- if (!system)
- return -ENODEV;
-@@ -2290,15 +2290,15 @@ static void __add_event_to_tracers(struc
- int trace_add_event_call(struct trace_event_call *call)
- {
- int ret;
-- mutex_lock(&trace_types_lock);
- mutex_lock(&event_mutex);
-+ mutex_lock(&trace_types_lock);
-
- ret = __register_event(call, NULL);
- if (ret >= 0)
- __add_event_to_tracers(call);
-
-- mutex_unlock(&event_mutex);
- mutex_unlock(&trace_types_lock);
-+ mutex_unlock(&event_mutex);
- return ret;
- }
-
-@@ -2352,13 +2352,13 @@ int trace_remove_event_call(struct trace
- {
- int ret;
-
-- mutex_lock(&trace_types_lock);
- mutex_lock(&event_mutex);
-+ mutex_lock(&trace_types_lock);
- down_write(&trace_event_sem);
- ret = probe_remove_event_call(call);
- up_write(&trace_event_sem);
-- mutex_unlock(&event_mutex);
- mutex_unlock(&trace_types_lock);
-+ mutex_unlock(&event_mutex);
-
- return ret;
- }
-@@ -2425,8 +2425,8 @@ static int trace_module_notify(struct no
- {
- struct module *mod = data;
-
-- mutex_lock(&trace_types_lock);
- mutex_lock(&event_mutex);
-+ mutex_lock(&trace_types_lock);
- switch (val) {
- case MODULE_STATE_COMING:
- trace_module_add_events(mod);
-@@ -2435,8 +2435,8 @@ static int trace_module_notify(struct no
- trace_module_remove_events(mod);
- break;
- }
-- mutex_unlock(&event_mutex);
- mutex_unlock(&trace_types_lock);
-+ mutex_unlock(&event_mutex);
-
- return 0;
- }
diff --git a/patches/0033-tracing-Add-hist-trigger-support-for-variable-refere.patch b/patches/0036-tracing-Add-hist-trigger-support-for-variable-refere.patch
index e6ca275f7f7d..f4babf5aa213 100644
--- a/patches/0033-tracing-Add-hist-trigger-support-for-variable-refere.patch
+++ b/patches/0036-tracing-Add-hist-trigger-support-for-variable-refere.patch
@@ -1,11 +1,25 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:45 -0500
-Subject: [PATCH 33/40] tracing: Add hist trigger support for variable
+Date: Fri, 22 Sep 2017 15:00:07 -0500
+Subject: [PATCH 36/42] tracing: Add hist trigger support for variable
reference aliases
Add support for alias=$somevar where alias can be used as
onmatch($alias).
+Aliases are a way of creating a new name for an existing variable, for
+flexibly in making naming more clear in certain cases. For example in
+the below the user perhaps feels that using $new_lat in the synthetic
+event invocation is opaque or doesn't fit well stylistically with
+previous triggers, so creates an alias of $new_lat named $latency and
+uses that in the call instead:
+
+ # echo 'hist:keys=next_pid:new_lat=$common_timestamp.usecs' >
+ /sys/kernel/debug/tracing/events/sched/sched_switch/trigger
+
+ # echo 'hist:keys=pid:latency=$new_lat:
+ onmatch(sched.sched_switch).wake2($latency,pid)' >
+ /sys/kernel/debug/tracing/events/synthetic/wake1/trigger
+
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
@@ -15,14 +29,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -227,6 +227,7 @@ enum hist_field_flags {
- HIST_FIELD_FL_EXPR = 16384,
- HIST_FIELD_FL_VAR_REF = 32768,
- HIST_FIELD_FL_CPU = 65536,
-+ HIST_FIELD_FL_ALIAS = 131072,
+ HIST_FIELD_FL_EXPR = 1 << 14,
+ HIST_FIELD_FL_VAR_REF = 1 << 15,
+ HIST_FIELD_FL_CPU = 1 << 16,
++ HIST_FIELD_FL_ALIAS = 1 << 17,
};
struct var_defs {
-@@ -1525,7 +1526,8 @@ static const char *hist_field_name(struc
+@@ -1527,7 +1528,8 @@ static const char *hist_field_name(struc
if (field->field)
field_name = field->field->name;
@@ -32,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
field_name = hist_field_name(field->operands[0], ++level);
else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
field_name = "$common_timestamp";
-@@ -1961,7 +1963,7 @@ static struct hist_field *create_hist_fi
+@@ -1983,7 +1985,7 @@ static struct hist_field *create_hist_fi
hist_field->hist_data = hist_data;
@@ -41,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
goto out; /* caller will populate */
if (flags & HIST_FIELD_FL_VAR_REF) {
-@@ -2219,6 +2221,29 @@ parse_field(struct hist_trigger_data *hi
+@@ -2241,6 +2243,29 @@ parse_field(struct hist_trigger_data *hi
return field;
}
@@ -71,7 +85,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct hist_field *parse_atom(struct hist_trigger_data *hist_data,
struct trace_event_file *file, char *str,
unsigned long *flags, char *var_name)
-@@ -2245,6 +2270,13 @@ struct hist_field *parse_atom(struct his
+@@ -2275,6 +2300,13 @@ struct hist_field *parse_atom(struct his
if (hist_field) {
hist_data->var_refs[hist_data->n_var_refs] = hist_field;
hist_field->var_ref_idx = hist_data->n_var_refs++;
@@ -85,7 +99,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return hist_field;
}
} else
-@@ -2346,6 +2378,26 @@ static int check_expr_operands(struct hi
+@@ -2378,6 +2410,26 @@ static int check_expr_operands(struct hi
unsigned long operand1_flags = operand1->flags;
unsigned long operand2_flags = operand2->flags;
@@ -112,7 +126,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
(operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS))
return -EINVAL;
-@@ -4339,8 +4391,11 @@ static void hist_field_print(struct seq_
+@@ -4379,8 +4431,11 @@ static void hist_field_print(struct seq_
seq_puts(m, "$common_timestamp");
else if (hist_field->flags & HIST_FIELD_FL_CPU)
seq_puts(m, "cpu");
diff --git a/patches/0034-tracing-Add-last-error-error-facility-for-hist-trigg.patch b/patches/0037-tracing-Add-last-error-error-facility-for-hist-trigg.patch
index 84c5378223de..ddacd44a1498 100644
--- a/patches/0034-tracing-Add-last-error-error-facility-for-hist-trigg.patch
+++ b/patches/0037-tracing-Add-last-error-error-facility-for-hist-trigg.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:46 -0500
-Subject: [PATCH 34/40] tracing: Add 'last error' error facility for hist
+Date: Fri, 22 Sep 2017 15:00:08 -0500
+Subject: [PATCH 37/42] tracing: Add 'last error' error facility for hist
triggers
With the addition of variables and actions, it's become necessary to
@@ -25,9 +25,9 @@ Also add specific error messages for variable and action errors.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- Documentation/trace/events.txt | 19 +++
- kernel/trace/trace_events_hist.c | 188 ++++++++++++++++++++++++++++++++++++---
- 2 files changed, 194 insertions(+), 13 deletions(-)
+ Documentation/trace/events.txt | 19 ++++
+ kernel/trace/trace_events_hist.c | 162 +++++++++++++++++++++++++++++++++++----
+ 2 files changed, 168 insertions(+), 13 deletions(-)
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -59,47 +59,27 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---------------------------
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
-@@ -351,6 +351,88 @@ struct action_data {
+@@ -351,6 +351,65 @@ struct action_data {
};
};
+
-+static char *hist_err_str;
-+static char *last_hist_cmd;
-+
-+static int hist_err_alloc(void)
-+{
-+ int ret = 0;
-+
-+ last_hist_cmd = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
-+ if (!last_hist_cmd)
-+ return -ENOMEM;
-+
-+ hist_err_str = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
-+ if (!hist_err_str) {
-+ kfree(last_hist_cmd);
-+ ret = -ENOMEM;
-+ }
-+
-+ return ret;
-+}
++static char last_hist_cmd[MAX_FILTER_STR_VAL];
++static char hist_err_str[MAX_FILTER_STR_VAL];
+
+static void last_cmd_set(char *str)
+{
-+ if (!last_hist_cmd || !str)
-+ return;
-+
-+ if (strlen(str) > MAX_FILTER_STR_VAL - 1)
++ if (!str)
+ return;
+
-+ strcpy(last_hist_cmd, str);
++ strncpy(last_hist_cmd, str, MAX_FILTER_STR_VAL - 1);
+}
+
+static void hist_err(char *str, char *var)
+{
+ int maxlen = MAX_FILTER_STR_VAL - 1;
+
-+ if (!hist_err_str || !str)
++ if (!str)
+ return;
+
+ if (strlen(hist_err_str))
@@ -120,26 +100,23 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ char err[MAX_FILTER_STR_VAL];
+
+ if (system && var)
-+ sprintf(err, "%s.%s.%s", system, event, var);
++ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s.%s", system, event, var);
+ else if (system)
-+ sprintf(err, "%s.%s", system, event);
++ snprintf(err, MAX_FILTER_STR_VAL, "%s.%s", system, event);
+ else
-+ strcpy(err, var);
++ strncpy(err, var, MAX_FILTER_STR_VAL);
+
+ hist_err(str, err);
+}
+
+static void hist_err_clear(void)
+{
-+ if (!hist_err_str)
-+ return;
-+
+ hist_err_str[0] = '\0';
+}
+
+static bool have_hist_err(void)
+{
-+ if (hist_err_str && strlen(hist_err_str))
++ if (strlen(hist_err_str))
+ return true;
+
+ return false;
@@ -148,7 +125,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static LIST_HEAD(synth_event_list);
static DEFINE_MUTEX(synth_event_mutex);
-@@ -2110,9 +2192,18 @@ static struct hist_field *create_var_ref
+@@ -2132,9 +2191,18 @@ static struct hist_field *create_var_ref
return ref_field;
}
@@ -168,7 +145,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return false;
return true;
-@@ -2164,6 +2255,10 @@ static struct hist_field *parse_var_ref(
+@@ -2186,6 +2254,10 @@ static struct hist_field *parse_var_ref(
if (var_field)
ref_field = create_var_ref(var_field);
@@ -179,7 +156,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ref_field;
}
-@@ -2399,8 +2494,10 @@ static int check_expr_operands(struct hi
+@@ -2431,8 +2503,10 @@ static int check_expr_operands(struct hi
}
if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
@@ -191,7 +168,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return 0;
}
-@@ -2600,19 +2697,27 @@ create_field_var_hist(struct hist_trigge
+@@ -2632,19 +2706,27 @@ create_field_var_hist(struct hist_trigge
char *cmd;
int ret;
@@ -221,7 +198,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
var_hist = kzalloc(sizeof(*var_hist), GFP_KERNEL);
if (!var_hist)
-@@ -2660,6 +2765,8 @@ create_field_var_hist(struct hist_trigge
+@@ -2692,6 +2774,8 @@ create_field_var_hist(struct hist_trigge
kfree(cmd);
kfree(var_hist->cmd);
kfree(var_hist);
@@ -230,7 +207,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ERR_PTR(ret);
}
-@@ -2671,6 +2778,8 @@ create_field_var_hist(struct hist_trigge
+@@ -2703,6 +2787,8 @@ create_field_var_hist(struct hist_trigge
kfree(cmd);
kfree(var_hist->cmd);
kfree(var_hist);
@@ -239,7 +216,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ERR_PTR(-EINVAL);
}
-@@ -2807,18 +2916,21 @@ static struct field_var *create_field_va
+@@ -2839,18 +2925,21 @@ static struct field_var *create_field_va
int ret = 0;
if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) {
@@ -261,7 +238,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(val);
ret = PTR_ERR(var);
goto err;
-@@ -2943,14 +3055,18 @@ static int onmax_create(struct hist_trig
+@@ -2975,14 +3064,18 @@ static int onmax_create(struct hist_trig
int ret = 0;
onmax_var_str = data->onmax.var_str;
@@ -282,7 +259,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
flags = HIST_FIELD_FL_VAR_REF;
ref_field = create_hist_field(hist_data, NULL, flags, NULL);
-@@ -2970,6 +3086,7 @@ static int onmax_create(struct hist_trig
+@@ -3002,6 +3095,7 @@ static int onmax_create(struct hist_trig
data->onmax.max_var_ref_idx = var_ref_idx;
max_var = create_var(hist_data, file, "max", sizeof(u64), "u64");
if (IS_ERR(max_var)) {
@@ -290,7 +267,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = PTR_ERR(max_var);
goto out;
}
-@@ -2982,6 +3099,7 @@ static int onmax_create(struct hist_trig
+@@ -3016,6 +3110,7 @@ static int onmax_create(struct hist_trig
field_var = create_target_field_var(hist_data, NULL, NULL, param);
if (IS_ERR(field_var)) {
@@ -298,7 +275,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = PTR_ERR(field_var);
kfree(param);
goto out;
-@@ -3014,6 +3132,7 @@ static int parse_action_params(char *par
+@@ -3050,6 +3145,7 @@ static int parse_action_params(char *par
param = strstrip(param);
if (strlen(param) < 2) {
@@ -306,7 +283,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = -EINVAL;
goto out;
}
-@@ -3185,6 +3304,9 @@ onmatch_find_var(struct hist_trigger_dat
+@@ -3223,6 +3319,9 @@ onmatch_find_var(struct hist_trigger_dat
hist_field = find_event_var(tr, system, event, var);
}
@@ -316,23 +293,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return hist_field;
}
-@@ -3236,6 +3358,7 @@ static int onmatch_create(struct hist_tr
-
+@@ -3273,6 +3372,7 @@ static int onmatch_create(struct hist_tr
+ mutex_lock(&synth_event_mutex);
event = find_synth_event(data->onmatch.synth_event_name);
if (!event) {
+ hist_err("onmatch: Couldn't find synthetic event: ", data->onmatch.synth_event_name);
- ret = -EINVAL;
- goto out;
+ mutex_unlock(&synth_event_mutex);
+ return -EINVAL;
}
-@@ -3275,6 +3398,7 @@ static int onmatch_create(struct hist_tr
- ret = -EINVAL;
- goto out;
- }
-+
- if (check_synth_field(event, hist_field, field_pos) == 0) {
- var_ref = create_var_ref(hist_field);
- if (!var_ref) {
-@@ -3289,12 +3413,15 @@ static int onmatch_create(struct hist_tr
+@@ -3331,12 +3431,15 @@ static int onmatch_create(struct hist_tr
continue;
}
@@ -348,7 +317,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = -EINVAL;
goto out;
}
-@@ -3322,15 +3449,22 @@ static struct action_data *onmatch_parse
+@@ -3362,15 +3465,22 @@ static struct action_data *onmatch_parse
return ERR_PTR(-ENOMEM);
match_event = strsep(&str, ")");
@@ -374,7 +343,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
data->onmatch.match_event = kstrdup(match_event, GFP_KERNEL);
if (!data->onmatch.match_event) {
-@@ -3345,12 +3479,16 @@ static struct action_data *onmatch_parse
+@@ -3385,12 +3495,16 @@ static struct action_data *onmatch_parse
}
strsep(&str, ".");
@@ -393,7 +362,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
data->onmatch.synth_event_name = kstrdup(synth_event_name, GFP_KERNEL);
if (!data->onmatch.synth_event_name) {
-@@ -3359,8 +3497,10 @@ static struct action_data *onmatch_parse
+@@ -3399,8 +3513,10 @@ static struct action_data *onmatch_parse
}
params = strsep(&str, ")");
@@ -405,7 +374,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = parse_action_params(params, data);
if (ret)
-@@ -3440,12 +3580,14 @@ static int create_var_field(struct hist_
+@@ -3480,12 +3596,14 @@ static int create_var_field(struct hist_
return -EINVAL;
if (find_var(file, var_name) && !hist_data->remove) {
@@ -420,7 +389,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return -EINVAL;
}
-@@ -3636,6 +3778,7 @@ static int parse_var_defs(struct hist_tr
+@@ -3676,6 +3794,7 @@ static int parse_var_defs(struct hist_tr
var_name = strsep(&field_str, "=");
if (!var_name || !field_str) {
@@ -428,7 +397,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = -EINVAL;
goto free;
}
-@@ -4362,6 +4505,11 @@ static int hist_show(struct seq_file *m,
+@@ -4402,6 +4521,11 @@ static int hist_show(struct seq_file *m,
hist_trigger_show(m, data, n++);
}
@@ -440,7 +409,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
out_unlock:
mutex_unlock(&event_mutex);
-@@ -4709,6 +4857,7 @@ static int hist_register_trigger(char *g
+@@ -4748,6 +4872,7 @@ static int hist_register_trigger(char *g
if (named_data) {
if (!hist_trigger_match(data, named_data, named_data,
true)) {
@@ -448,7 +417,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = -EINVAL;
goto out;
}
-@@ -4728,13 +4877,16 @@ static int hist_register_trigger(char *g
+@@ -4767,13 +4892,16 @@ static int hist_register_trigger(char *g
test->paused = false;
else if (hist_data->attrs->clear)
hist_clear(test);
@@ -466,7 +435,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = -ENOENT;
goto out;
}
-@@ -4901,6 +5053,11 @@ static int event_hist_trigger_func(struc
+@@ -4941,6 +5069,11 @@ static int event_hist_trigger_func(struc
char *trigger, *p;
int ret = 0;
@@ -478,7 +447,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (!param)
return -EINVAL;
-@@ -5019,6 +5176,9 @@ static int event_hist_trigger_func(struc
+@@ -5062,6 +5195,9 @@ static int event_hist_trigger_func(struc
/* Just return zero, not the number of registered triggers */
ret = 0;
out:
@@ -488,12 +457,3 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return ret;
out_unreg:
cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
-@@ -5208,6 +5368,8 @@ static __init int trace_events_hist_init
- goto err;
- }
-
-+ hist_err_alloc();
-+
- return err;
- err:
- pr_warn("Could not create tracefs 'synthetic_events' entry\n");
diff --git a/patches/0037-tracing-Add-inter-event-hist-trigger-Documentation.patch b/patches/0038-tracing-Add-inter-event-hist-trigger-Documentation.patch
index 08fc6d64a9d9..6ce6df392cbf 100644
--- a/patches/0037-tracing-Add-inter-event-hist-trigger-Documentation.patch
+++ b/patches/0038-tracing-Add-inter-event-hist-trigger-Documentation.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:49 -0500
-Subject: [PATCH 37/40] tracing: Add inter-event hist trigger Documentation
+Date: Fri, 22 Sep 2017 15:00:09 -0500
+Subject: [PATCH 38/42] tracing: Add inter-event hist trigger Documentation
Add background and details on inter-event hist triggers, including
hist variables, synthetic events, and actions.
diff --git a/patches/0038-tracing-Make-tracing_set_clock-non-static.patch b/patches/0039-tracing-Make-tracing_set_clock-non-static.patch
index 0dfea2d8b100..8c9bce73c8bd 100644
--- a/patches/0038-tracing-Make-tracing_set_clock-non-static.patch
+++ b/patches/0039-tracing-Make-tracing_set_clock-non-static.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:50 -0500
-Subject: [PATCH 38/40] tracing: Make tracing_set_clock() non-static
+Date: Fri, 22 Sep 2017 15:00:10 -0500
+Subject: [PATCH 39/42] tracing: Make tracing_set_clock() non-static
Allow tracing code outside of trace.c to access tracing_set_clock().
diff --git a/patches/0039-tracing-Add-a-clock-attribute-for-hist-triggers.patch b/patches/0040-tracing-Add-a-clock-attribute-for-hist-triggers.patch
index 1e23eb9bf4e3..09b0c3e83633 100644
--- a/patches/0039-tracing-Add-a-clock-attribute-for-hist-triggers.patch
+++ b/patches/0040-tracing-Add-a-clock-attribute-for-hist-triggers.patch
@@ -1,6 +1,6 @@
From: Tom Zanussi <tom.zanussi@linux.intel.com>
-Date: Tue, 5 Sep 2017 16:57:51 -0500
-Subject: [PATCH 39/40] tracing: Add a clock attribute for hist triggers
+Date: Fri, 22 Sep 2017 15:00:11 -0500
+Subject: [PATCH 40/42] tracing: Add a clock attribute for hist triggers
The default clock if timestamps are used in a histogram is "global".
If timestamps aren't used, the clock is irrelevant.
@@ -9,11 +9,12 @@ Use the "clock=" param only if you want to override the default
"global" clock for a histogram with timestamps.
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Rajvi Jingar <rajvi.jingar@intel.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
Documentation/trace/events.txt | 9 +++++++++
- kernel/trace/trace_events_hist.c | 34 +++++++++++++++++++++++++++++++---
- 2 files changed, 40 insertions(+), 3 deletions(-)
+ kernel/trace/trace_events_hist.c | 38 ++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 45 insertions(+), 2 deletions(-)
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -43,7 +44,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
bool pause;
bool cont;
bool clear;
-@@ -1701,6 +1702,7 @@ static void destroy_hist_trigger_attrs(s
+@@ -1680,6 +1681,7 @@ static void destroy_hist_trigger_attrs(s
kfree(attrs->sort_key_str);
kfree(attrs->keys_str);
kfree(attrs->vals_str);
@@ -51,12 +52,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kfree(attrs);
}
-@@ -1740,7 +1742,16 @@ static int parse_assignment(char *str, s
- attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
- else if (strncmp(str, "name=", strlen("name=")) == 0)
- attrs->name = kstrdup(str, GFP_KERNEL);
-- else if (strncmp(str, "size=", strlen("size=")) == 0) {
-+ else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
+@@ -1735,6 +1737,19 @@ static int parse_assignment(char *str, s
+ ret = -ENOMEM;
+ goto out;
+ }
++ } else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
+ strsep(&str, "=");
+ if (!str) {
+ ret = -EINVAL;
@@ -65,24 +65,29 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+ str = strstrip(str);
+ attrs->clock = kstrdup(str, GFP_KERNEL);
-+ } else if (strncmp(str, "size=", strlen("size=")) == 0) {
++ if (!attrs->clock) {
++ ret = -ENOMEM;
++ goto out;
++ }
+ } else if (strncmp(str, "size=", strlen("size=")) == 0) {
int map_bits = parse_map_size(str);
- if (map_bits < 0) {
-@@ -1803,6 +1814,12 @@ static struct hist_trigger_attrs *parse_
+@@ -1798,6 +1813,14 @@ static struct hist_trigger_attrs *parse_
goto free;
}
+ if (!attrs->clock) {
+ attrs->clock = kstrdup("global", GFP_KERNEL);
-+ if (!attrs->clock)
++ if (!attrs->clock) {
++ ret = -ENOMEM;
+ goto free;
++ }
+ }
+
return attrs;
free:
destroy_hist_trigger_attrs(attrs);
-@@ -4644,6 +4661,8 @@ static int event_hist_trigger_print(stru
+@@ -4660,6 +4683,8 @@ static int event_hist_trigger_print(stru
seq_puts(m, ".descending");
}
seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
@@ -91,7 +96,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
print_actions_spec(m, hist_data);
-@@ -4907,10 +4926,19 @@ static int hist_register_trigger(char *g
+@@ -4922,10 +4947,19 @@ static int hist_register_trigger(char *g
goto out;
}
diff --git a/patches/0041-tracing-Increase-trace_recursive_lock-limit-for-synt.patch b/patches/0041-tracing-Increase-trace_recursive_lock-limit-for-synt.patch
new file mode 100644
index 000000000000..34bc8f223b1d
--- /dev/null
+++ b/patches/0041-tracing-Increase-trace_recursive_lock-limit-for-synt.patch
@@ -0,0 +1,43 @@
+From: Tom Zanussi <tom.zanussi@linux.intel.com>
+Date: Fri, 22 Sep 2017 15:00:12 -0500
+Subject: [PATCH 41/42] tracing: Increase trace_recursive_lock() limit for
+ synthetic events
+
+Synthetic event generation needs to happen while the current event is
+still in progress, so add 1 to the trace_recursive_lock() recursion
+limit to account for that.
+
+Because we also want to allow for the possibility of a synthetic event
+being generated from another synthetic event, add an additional
+increment for that as well.
+
+Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/trace/ring_buffer.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -2590,16 +2590,16 @@ rb_wakeups(struct ring_buffer *buffer, s
+ * IRQ context
+ * NMI context
+ *
+- * If for some reason the ring buffer starts to recurse, we
+- * only allow that to happen at most 4 times (one for each
+- * context). If it happens 5 times, then we consider this a
+- * recusive loop and do not let it go further.
++ * If for some reason the ring buffer starts to recurse, we only allow
++ * that to happen at most 6 times (one for each context, plus possibly
++ * two levels of synthetic event generation). If it happens 7 times,
++ * then we consider this a recusive loop and do not let it go further.
+ */
+
+ static __always_inline int
+ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
+ {
+- if (cpu_buffer->current_context >= 4)
++ if (cpu_buffer->current_context >= 6)
+ return 1;
+
+ cpu_buffer->current_context++;
diff --git a/patches/0042-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch b/patches/0042-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch
new file mode 100644
index 000000000000..a4c1c0601797
--- /dev/null
+++ b/patches/0042-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch
@@ -0,0 +1,27 @@
+From: Tom Zanussi <tom.zanussi@linux.intel.com>
+Date: Fri, 22 Sep 2017 15:00:13 -0500
+Subject: [PATCH 42/42] tracing: Add inter-event blurb to HIST_TRIGGERS config
+ option
+
+So that users know that inter-event tracing is supported as part of
+the HIST_TRIGGERS option, include text to that effect in the help
+text.
+
+Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/trace/Kconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -585,6 +585,9 @@ config HIST_TRIGGERS
+ event activity as an initial guide for further investigation
+ using more advanced tools.
+
++ Inter-event tracing of quantities such as latencies is also
++ supported using hist triggers under this option.
++
+ See Documentation/trace/events.txt.
+ If in doubt, say N.
+
diff --git a/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch b/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch
index de4b4bca6253..e376e6d7c1c2 100644
--- a/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch
+++ b/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch
@@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
return false;
}
-+ zram_meta_init_table_locks(zram, disksize);
++ zram_meta_init_table_locks(zram, num_pages);
return true;
}
diff --git a/patches/fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch b/patches/fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch
new file mode 100644
index 000000000000..69f27721fa9c
--- /dev/null
+++ b/patches/fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch
@@ -0,0 +1,118 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Fri, 20 Oct 2017 11:29:53 +0200
+Subject: [PATCH] fs/dcache: disable preemption on i_dir_seq's write side
+
+i_dir_seq is an opencoded seqcounter. Based on the code it looks like we
+could have two writers in parallel despite the fact that the d_lock is
+held. The problem is that during the write process on RT the preemption
+is still enabled and if this process is interrupted by a reader with RT
+priority then we lock up.
+To avoid that lock up I am disabling the preemption during the update.
+The rename of i_dir_seq is here to ensure to catch new write sides in
+future.
+
+Cc: stable-rt@vger.kernel.org
+Reported-by: Oleg.Karfich@wago.com
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ fs/dcache.c | 12 +++++++-----
+ fs/inode.c | 2 +-
+ fs/libfs.c | 6 ++++--
+ include/linux/fs.h | 2 +-
+ 4 files changed, 13 insertions(+), 9 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -2405,9 +2405,10 @@ EXPORT_SYMBOL(d_rehash);
+ static inline unsigned start_dir_add(struct inode *dir)
+ {
+
++ preempt_disable_rt();
+ for (;;) {
+- unsigned n = dir->i_dir_seq;
+- if (!(n & 1) && cmpxchg(&dir->i_dir_seq, n, n + 1) == n)
++ unsigned n = dir->__i_dir_seq;
++ if (!(n & 1) && cmpxchg(&dir->__i_dir_seq, n, n + 1) == n)
+ return n;
+ cpu_relax();
+ }
+@@ -2415,7 +2416,8 @@ static inline unsigned start_dir_add(str
+
+ static inline void end_dir_add(struct inode *dir, unsigned n)
+ {
+- smp_store_release(&dir->i_dir_seq, n + 2);
++ smp_store_release(&dir->__i_dir_seq, n + 2);
++ preempt_enable_rt();
+ }
+
+ static void d_wait_lookup(struct dentry *dentry)
+@@ -2448,7 +2450,7 @@ struct dentry *d_alloc_parallel(struct d
+
+ retry:
+ rcu_read_lock();
+- seq = smp_load_acquire(&parent->d_inode->i_dir_seq) & ~1;
++ seq = smp_load_acquire(&parent->d_inode->__i_dir_seq) & ~1;
+ r_seq = read_seqbegin(&rename_lock);
+ dentry = __d_lookup_rcu(parent, name, &d_seq);
+ if (unlikely(dentry)) {
+@@ -2470,7 +2472,7 @@ struct dentry *d_alloc_parallel(struct d
+ goto retry;
+ }
+ hlist_bl_lock(b);
+- if (unlikely(parent->d_inode->i_dir_seq != seq)) {
++ if (unlikely(parent->d_inode->__i_dir_seq != seq)) {
+ hlist_bl_unlock(b);
+ rcu_read_unlock();
+ goto retry;
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -154,7 +154,7 @@ int inode_init_always(struct super_block
+ inode->i_bdev = NULL;
+ inode->i_cdev = NULL;
+ inode->i_link = NULL;
+- inode->i_dir_seq = 0;
++ inode->__i_dir_seq = 0;
+ inode->i_rdev = 0;
+ inode->dirtied_when = 0;
+
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -90,7 +90,7 @@ static struct dentry *next_positive(stru
+ struct list_head *from,
+ int count)
+ {
+- unsigned *seq = &parent->d_inode->i_dir_seq, n;
++ unsigned *seq = &parent->d_inode->__i_dir_seq, n;
+ struct dentry *res;
+ struct list_head *p;
+ bool skipped;
+@@ -123,8 +123,9 @@ static struct dentry *next_positive(stru
+ static void move_cursor(struct dentry *cursor, struct list_head *after)
+ {
+ struct dentry *parent = cursor->d_parent;
+- unsigned n, *seq = &parent->d_inode->i_dir_seq;
++ unsigned n, *seq = &parent->d_inode->__i_dir_seq;
+ spin_lock(&parent->d_lock);
++ preempt_disable_rt();
+ for (;;) {
+ n = *seq;
+ if (!(n & 1) && cmpxchg(seq, n, n + 1) == n)
+@@ -137,6 +138,7 @@ static void move_cursor(struct dentry *c
+ else
+ list_add_tail(&cursor->d_child, &parent->d_subdirs);
+ smp_store_release(seq, n + 2);
++ preempt_enable_rt();
+ spin_unlock(&parent->d_lock);
+ }
+
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -651,7 +651,7 @@ struct inode {
+ struct block_device *i_bdev;
+ struct cdev *i_cdev;
+ char *i_link;
+- unsigned i_dir_seq;
++ unsigned __i_dir_seq;
+ };
+
+ __u32 i_generation;
diff --git a/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch b/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch
index 9ca117f2bb6c..eeb7b926e1c8 100644
--- a/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch
+++ b/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch
@@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/fs/dcache.c
+++ b/fs/dcache.c
-@@ -2432,21 +2432,24 @@ static inline void end_dir_add(struct in
+@@ -2434,21 +2434,24 @@ static inline void end_dir_add(struct in
static void d_wait_lookup(struct dentry *dentry)
{
@@ -69,7 +69,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
unsigned int hash = name->hash;
struct hlist_bl_head *b = in_lookup_hash(parent, hash);
-@@ -2555,7 +2558,7 @@ void __d_lookup_done(struct dentry *dent
+@@ -2557,7 +2560,7 @@ void __d_lookup_done(struct dentry *dent
hlist_bl_lock(b);
dentry->d_flags &= ~DCACHE_PAR_LOOKUP;
__hlist_bl_del(&dentry->d_u.d_in_lookup_hash);
diff --git a/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch
index b8071b716e18..d40310049a41 100644
--- a/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch
+++ b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch
@@ -45,7 +45,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
};
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
-@@ -209,7 +209,12 @@ int irq_set_affinity_locked(struct irq_d
+@@ -212,7 +212,12 @@ int irq_set_affinity_locked(struct irq_d
if (desc->affinity_notify) {
kref_get(&desc->affinity_notify->kref);
@@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
irqd_set(data, IRQD_AFFINITY_SET);
-@@ -247,10 +252,8 @@ int irq_set_affinity_hint(unsigned int i
+@@ -250,10 +255,8 @@ int irq_set_affinity_hint(unsigned int i
}
EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
@@ -70,7 +70,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
struct irq_desc *desc = irq_to_desc(notify->irq);
cpumask_var_t cpumask;
unsigned long flags;
-@@ -272,6 +275,35 @@ static void irq_affinity_notify(struct w
+@@ -275,6 +278,35 @@ static void irq_affinity_notify(struct w
kref_put(&notify->kref, notify->release);
}
@@ -106,7 +106,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/**
* irq_set_affinity_notifier - control notification of IRQ affinity changes
* @irq: Interrupt for which to enable/disable notification
-@@ -300,7 +332,12 @@ irq_set_affinity_notifier(unsigned int i
+@@ -303,7 +335,12 @@ irq_set_affinity_notifier(unsigned int i
if (notify) {
notify->irq = irq;
kref_init(&notify->kref);
diff --git a/patches/genirq-update-irq_set_irqchip_state-documentation.patch b/patches/genirq-update-irq_set_irqchip_state-documentation.patch
index 1b5688b8d6d6..2c91e2981913 100644
--- a/patches/genirq-update-irq_set_irqchip_state-documentation.patch
+++ b/patches/genirq-update-irq_set_irqchip_state-documentation.patch
@@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
-@@ -2160,7 +2160,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state)
+@@ -2163,7 +2163,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state)
* This call sets the internal irqchip state of an interrupt,
* depending on the value of @which.
*
diff --git a/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch b/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch
index e8442d060666..a1ce806d4d4a 100644
--- a/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch
+++ b/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch
@@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -10687,7 +10687,7 @@ void intel_check_page_flip(struct drm_i9
+@@ -10691,7 +10691,7 @@ void intel_check_page_flip(struct drm_i9
struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
struct intel_flip_work *work;
diff --git a/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch b/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch
index 44a6c552faf2..f12cb2184064 100644
--- a/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch
+++ b/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch
@@ -64,7 +64,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
-@@ -858,7 +858,15 @@ irq_forced_thread_fn(struct irq_desc *de
+@@ -861,7 +861,15 @@ irq_forced_thread_fn(struct irq_desc *de
local_bh_disable();
ret = action->thread_fn(action->irq, action->dev_id);
irq_finalize_oneshot(desc, action);
@@ -81,7 +81,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
return ret;
}
-@@ -1335,6 +1343,9 @@ static int
+@@ -1338,6 +1346,9 @@ static int
irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
}
diff --git a/patches/kernel-SRCU-provide-a-static-initializer.patch b/patches/kernel-SRCU-provide-a-static-initializer.patch
index 572c852cc05a..25eaaebde5ce 100644
--- a/patches/kernel-SRCU-provide-a-static-initializer.patch
+++ b/patches/kernel-SRCU-provide-a-static-initializer.patch
@@ -13,9 +13,10 @@ complete.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- include/linux/notifier.h | 34 +++++++++++++++++++++++++---------
+ include/linux/notifier.h | 42 +++++++++++++++++++++++++++++++++---------
+ include/linux/srcutiny.h | 6 +++---
include/linux/srcutree.h | 6 +++---
- 2 files changed, 28 insertions(+), 12 deletions(-)
+ 3 files changed, 39 insertions(+), 15 deletions(-)
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -63,16 +64,24 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
#define ATOMIC_NOTIFIER_HEAD(name) \
struct atomic_notifier_head name = \
-@@ -115,6 +119,18 @@ extern void srcu_init_notifier_head(stru
+@@ -115,6 +119,26 @@ extern void srcu_init_notifier_head(stru
struct raw_notifier_head name = \
RAW_NOTIFIER_INIT(name)
++#ifdef CONFIG_TREE_SRCU
+#define _SRCU_NOTIFIER_HEAD(name, mod) \
+ static DEFINE_PER_CPU(struct srcu_data, \
+ name##_head_srcu_data); \
+ mod struct srcu_notifier_head name = \
+ SRCU_NOTIFIER_INIT(name, name##_head_srcu_data)
+
++#else
++#define _SRCU_NOTIFIER_HEAD(name, mod) \
++ mod struct srcu_notifier_head name = \
++ SRCU_NOTIFIER_INIT(name, name)
++
++#endif
++
+#define SRCU_NOTIFIER_HEAD(name) \
+ _SRCU_NOTIFIER_HEAD(name, )
+
@@ -82,7 +91,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
#ifdef __KERNEL__
extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
-@@ -184,12 +200,12 @@ static inline int notifier_to_errno(int
+@@ -184,12 +208,12 @@ static inline int notifier_to_errno(int
/*
* Declared notifiers so far. I can imagine quite a few more chains
@@ -98,6 +107,29 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/* CPU notfiers are defined in include/linux/cpu.h. */
/* netdevice notifiers are defined in include/linux/netdevice.h */
+--- a/include/linux/srcutiny.h
++++ b/include/linux/srcutiny.h
+@@ -43,7 +43,7 @@ struct srcu_struct {
+
+ void srcu_drive_gp(struct work_struct *wp);
+
+-#define __SRCU_STRUCT_INIT(name) \
++#define __SRCU_STRUCT_INIT(name, __ignored) \
+ { \
+ .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
+ .srcu_cb_tail = &name.srcu_cb_head, \
+@@ -56,9 +56,9 @@ void srcu_drive_gp(struct work_struct *w
+ * Tree SRCU, which needs some per-CPU data.
+ */
+ #define DEFINE_SRCU(name) \
+- struct srcu_struct name = __SRCU_STRUCT_INIT(name)
++ struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
+ #define DEFINE_STATIC_SRCU(name) \
+- static struct srcu_struct name = __SRCU_STRUCT_INIT(name)
++ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name)
+
+ void synchronize_srcu(struct srcu_struct *sp);
+
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -106,9 +106,9 @@ struct srcu_struct {
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 279489a1d145..e36eb4b6666a 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- /dev/null
+++ b/localversion-rt
@@ -0,0 +1 @@
-+-rt2
++-rt3
diff --git a/patches/random-make-it-work-on-rt.patch b/patches/random-make-it-work-on-rt.patch
index 34fcc16d8f51..ae9807aacd7c 100644
--- a/patches/random-make-it-work-on-rt.patch
+++ b/patches/random-make-it-work-on-rt.patch
@@ -56,7 +56,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
add_interrupt_bench(cycles);
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
-@@ -964,6 +964,8 @@ static void vmbus_isr(void)
+@@ -966,6 +966,8 @@ static void vmbus_isr(void)
void *page_addr = hv_cpu->synic_event_page;
struct hv_message *msg;
union hv_synic_event_flags *event;
@@ -65,7 +65,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
bool handled = false;
if (unlikely(page_addr == NULL))
-@@ -1007,7 +1009,7 @@ static void vmbus_isr(void)
+@@ -1009,7 +1011,7 @@ static void vmbus_isr(void)
tasklet_schedule(&hv_cpu->msg_dpc);
}
@@ -117,7 +117,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
note_interrupt(desc, retval);
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
-@@ -1000,6 +1000,12 @@ static int irq_thread(void *data)
+@@ -1003,6 +1003,12 @@ static int irq_thread(void *data)
if (action_ret == IRQ_WAKE_THREAD)
irq_wake_secondary(desc, action);
diff --git a/patches/series b/patches/series
index 7c910bffd0c6..de7948046f40 100644
--- a/patches/series
+++ b/patches/series
@@ -108,46 +108,50 @@ kernel-SRCU-provide-a-static-initializer.patch
kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch
add_migrate_disable.patch
-# tracing: Inter-event (e.g. latency) support | 2017-09-05
-0001-tracing-Exclude-generic-fields-from-histograms.patch
-0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch
-0003-tracing-Remove-code-which-merges-duplicates.patch
-0004-tracing-Add-hist_field_name-accessor.patch
-0005-tracing-Reimplement-log2.patch
-0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch
-0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch
-0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch
-0010-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch
-0011-tracing-Increase-tracing-map-KEYS_MAX-size.patch
-0012-tracing-Break-out-hist-trigger-assignment-parsing.patch
-0013-tracing-Make-traceprobe-parsing-code-reusable.patch
-0014-tracing-Add-hist-trigger-timestamp-support.patch
-0015-tracing-Add-per-element-variable-support-to-tracing_.patch
-0016-tracing-Add-hist_data-member-to-hist_field.patch
-0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch
-0018-tracing-Add-variable-support-to-hist-triggers.patch
-0019-tracing-Account-for-variables-in-named-trigger-compa.patch
-0020-tracing-Add-simple-expression-support-to-hist-trigge.patch
-0021-tracing-Generalize-per-element-hist-trigger-data.patch
-0022-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch
-0023-tracing-Add-hist_field-type-field.patch
-0024-tracing-Add-variable-reference-handling-to-hist-trig.patch
-0025-tracing-Add-support-for-dynamic-tracepoints.patch
-0026-tracing-Add-hist-trigger-action-hook.patch
-0027-tracing-Add-support-for-synthetic-events.patch
-0028-tracing-Add-support-for-field-variables.patch
-0029-tracing-Add-onmatch-hist-trigger-action-support.patch
-0030-tracing-Add-onmax-hist-trigger-action-support.patch
-0031-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch
-0032-tracing-Add-cpu-field-for-hist-triggers.patch
-0033-tracing-Add-hist-trigger-support-for-variable-refere.patch
-0034-tracing-Add-last-error-error-facility-for-hist-trigg.patch
-0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch
-0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch
-0037-tracing-Add-inter-event-hist-trigger-Documentation.patch
-0038-tracing-Make-tracing_set_clock-non-static.patch
-0039-tracing-Add-a-clock-attribute-for-hist-triggers.patch
-0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch
+# tracing: Bug fixes and minor cleanup | 2017-09-22
+0001-tracing-Steve-s-unofficial-trace_recursive_lock-patc.patch
+0002-tracing-Reverse-the-order-of-trace_types_lock-and-ev.patch
+0003-tracing-Exclude-generic-fields-from-histograms.patch
+0004-tracing-Remove-lookups-from-tracing_map-hitcount.patch
+0005-tracing-Increase-tracing-map-KEYS_MAX-size.patch
+0006-tracing-Make-traceprobe-parsing-code-reusable.patch
+0007-tracing-Clean-up-hist_field_flags-enum.patch
+0008-tracing-Add-hist_field_name-accessor.patch
+0009-tracing-Reimplement-log2.patch
+# v3 tracing: Inter-event (e.g. latency) support | 2017-09-22
+0010-tracing-Add-support-to-detect-and-avoid-duplicates.patch
+0011-tracing-Remove-code-which-merges-duplicates.patch
+0012-ring-buffer-Add-interface-for-setting-absolute-time-.patch
+0013-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch
+0014-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch
+0015-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch
+0016-tracing-Break-out-hist-trigger-assignment-parsing.patch
+0017-tracing-Add-hist-trigger-timestamp-support.patch
+0018-tracing-Add-per-element-variable-support-to-tracing_.patch
+0019-tracing-Add-hist_data-member-to-hist_field.patch
+0020-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch
+0021-tracing-Add-variable-support-to-hist-triggers.patch
+0022-tracing-Account-for-variables-in-named-trigger-compa.patch
+0023-tracing-Move-get_hist_field_flags.patch
+0024-tracing-Add-simple-expression-support-to-hist-trigge.patch
+0025-tracing-Generalize-per-element-hist-trigger-data.patch
+0026-tracing-Pass-tracing_map_elt-to-hist_field-accessor-.patch
+0027-tracing-Add-hist_field-type-field.patch
+0028-tracing-Add-variable-reference-handling-to-hist-trig.patch
+0029-tracing-Add-hist-trigger-action-hook.patch
+0030-tracing-Add-support-for-synthetic-events.patch
+0031-tracing-Add-support-for-field-variables.patch
+0032-tracing-Add-onmatch-hist-trigger-action-support.patch
+0033-tracing-Add-onmax-hist-trigger-action-support.patch
+0034-tracing-Allow-whitespace-to-surround-hist-trigger-fi.patch
+0035-tracing-Add-cpu-field-for-hist-triggers.patch
+0036-tracing-Add-hist-trigger-support-for-variable-refere.patch
+0037-tracing-Add-last-error-error-facility-for-hist-trigg.patch
+0038-tracing-Add-inter-event-hist-trigger-Documentation.patch
+0039-tracing-Make-tracing_set_clock-non-static.patch
+0040-tracing-Add-a-clock-attribute-for-hist-triggers.patch
+0041-tracing-Increase-trace_recursive_lock-limit-for-synt.patch
+0042-tracing-Add-inter-event-blurb-to-HIST_TRIGGERS-confi.patch
# SCHED BLOCK/WQ
block-shorten-interrupt-disabled-regions.patch
@@ -428,6 +432,7 @@ fs-block-rt-support.patch
fs-ntfs-disable-interrupt-non-rt.patch
fs-jbd2-pull-your-plug-when-waiting-for-space.patch
fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch
+fs-dcache-disable-preemption-on-i_dir_seq-s-write-si.patch
# X86
x86-mce-timer-hrtimer.patch
@@ -613,6 +618,7 @@ connector-cn_proc-Protect-send_msg-with-a-local-lock.patch
drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch
drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch
drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch
+tpm_tis-fix-stall-after-iowrite-s.patch
# I915
i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch
diff --git a/patches/tpm_tis-fix-stall-after-iowrite-s.patch b/patches/tpm_tis-fix-stall-after-iowrite-s.patch
new file mode 100644
index 000000000000..83ff41bdd110
--- /dev/null
+++ b/patches/tpm_tis-fix-stall-after-iowrite-s.patch
@@ -0,0 +1,77 @@
+From: Haris Okanovic <haris.okanovic@ni.com>
+Date: Tue, 15 Aug 2017 15:13:08 -0500
+Subject: [PATCH] tpm_tis: fix stall after iowrite*()s
+
+ioread8() operations to TPM MMIO addresses can stall the cpu when
+immediately following a sequence of iowrite*()'s to the same region.
+
+For example, cyclitest measures ~400us latency spikes when a non-RT
+usermode application communicates with an SPI-based TPM chip (Intel Atom
+E3940 system, PREEMPT_RT_FULL kernel). The spikes are caused by a
+stalling ioread8() operation following a sequence of 30+ iowrite8()s to
+the same address. I believe this happens because the write sequence is
+buffered (in cpu or somewhere along the bus), and gets flushed on the
+first LOAD instruction (ioread*()) that follows.
+
+The enclosed change appears to fix this issue: read the TPM chip's
+access register (status code) after every iowrite*() operation to
+amortize the cost of flushing data to chip across multiple instructions.
+
+Signed-off-by: Haris Okanovic <haris.okanovic@ni.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/char/tpm/tpm_tis.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -52,6 +52,31 @@ static inline struct tpm_tis_tcg_phy *to
+ return container_of(data, struct tpm_tis_tcg_phy, priv);
+ }
+
++#ifdef CONFIG_PREEMPT_RT_FULL
++/*
++ * Flushes previous write operations to chip so that a subsequent
++ * ioread*()s won't stall a cpu.
++ */
++static inline void tpm_tis_flush(void __iomem *iobase)
++{
++ ioread8(iobase + TPM_ACCESS(0));
++}
++#else
++#define tpm_tis_flush(iobase) do { } while (0)
++#endif
++
++static inline void tpm_tis_iowrite8(u8 b, void __iomem *iobase, u32 addr)
++{
++ iowrite8(b, iobase + addr);
++ tpm_tis_flush(iobase);
++}
++
++static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr)
++{
++ iowrite32(b, iobase + addr);
++ tpm_tis_flush(iobase);
++}
++
+ static bool interrupts = true;
+ module_param(interrupts, bool, 0444);
+ MODULE_PARM_DESC(interrupts, "Enable interrupts");
+@@ -230,7 +255,7 @@ static int tpm_tcg_write_bytes(struct tp
+ tpm_platform_begin_xfer();
+
+ while (len--)
+- iowrite8(*value++, phy->iobase + addr);
++ tpm_tis_iowrite8(*value++, phy->iobase, addr);
+
+ tpm_platform_end_xfer();
+
+@@ -269,7 +294,7 @@ static int tpm_tcg_write32(struct tpm_ti
+
+ tpm_platform_begin_xfer();
+
+- iowrite32(value, phy->iobase + addr);
++ tpm_tis_iowrite32(value, phy->iobase, addr);
+
+ tpm_platform_end_xfer();
+