mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tom Zanussi <tom.zanussi@linux.intel.com>
To: rostedt@goodmis.org
Cc: tglx@linutronix.de, mhiramat@kernel.org, namhyung@kernel.org,
	vedang.patel@intel.com, linux-kernel@vger.kernel.org,
	linux-rt-users@vger.kernel.org,
	Tom Zanussi <tom.zanussi@linux.intel.com>
Subject: [PATCH 20/32] tracing: Add support for dynamic tracepoints
Date: Mon, 26 Jun 2017 17:49:21 -0500	[thread overview]
Message-ID: <dc94982227615e79df977bd9a3c6b4d3b092ae02.1498510759.git.tom.zanussi@linux.intel.com> (raw)
In-Reply-To: <cover.1498510759.git.tom.zanussi@linux.intel.com>
In-Reply-To: <cover.1498510759.git.tom.zanussi@linux.intel.com>

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_tracepoint_probe_register() and a dynamic param onto
tracepoint_probe_unregister() for this purpose.

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
---
 include/linux/tracepoint.h  | 11 +++++++----
 kernel/trace/trace_events.c |  4 ++--
 kernel/tracepoint.c         | 42 ++++++++++++++++++++++++++++++------------
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index a26ffbe..dfb07dd 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -37,9 +37,12 @@ struct trace_eval_map {
 tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
 extern int
 tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data,
-			       int prio);
+			       int prio, bool dynamic);
+extern int dynamic_tracepoint_probe_register(struct tracepoint *tp,
+					     void *probe, void *data);
 extern int
-tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);
+tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data,
+			    bool dynamic);
 extern void
 for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv),
 		void *priv);
@@ -210,13 +213,13 @@ static inline void tracepoint_synchronize_unregister(void)
 				   int prio)				\
 	{								\
 		return tracepoint_probe_register_prio(&__tracepoint_##name, \
-					      (void *)probe, data, prio); \
+				      (void *)probe, data, prio, false); \
 	}								\
 	static inline int						\
 	unregister_trace_##name(void (*probe)(data_proto), void *data)	\
 	{								\
 		return tracepoint_probe_unregister(&__tracepoint_##name,\
-						(void *)probe, data);	\
+					   (void *)probe, data, false); \
 	}								\
 	static inline void						\
 	check_trace_callback_type_##name(void (*cb)(data_proto))	\
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 83dfd0d..1324393 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -297,7 +297,7 @@ int trace_event_reg(struct trace_event_call *call,
 	case TRACE_REG_UNREGISTER:
 		tracepoint_probe_unregister(call->tp,
 					    call->class->probe,
-					    file);
+					    file, false);
 		return 0;
 
 #ifdef CONFIG_PERF_EVENTS
@@ -308,7 +308,7 @@ int trace_event_reg(struct trace_event_call *call,
 	case TRACE_REG_PERF_UNREGISTER:
 		tracepoint_probe_unregister(call->tp,
 					    call->class->perf_probe,
-					    call);
+					    call, false);
 		return 0;
 	case TRACE_REG_PERF_OPEN:
 	case TRACE_REG_PERF_CLOSE:
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 685c50a..4068809 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -192,12 +192,15 @@ static void *func_remove(struct tracepoint_func **funcs,
  * Add the probe function to a tracepoint.
  */
 static int tracepoint_add_func(struct tracepoint *tp,
-			       struct tracepoint_func *func, int prio)
+			       struct tracepoint_func *func, int prio,
+			       bool dynamic)
 {
 	struct tracepoint_func *old, *tp_funcs;
 	int ret;
 
-	if (tp->regfunc && !static_key_enabled(&tp->key)) {
+	if (tp->regfunc &&
+	    ((dynamic && !(atomic_read(&tp->key.enabled) > 0)) ||
+	     !static_key_enabled(&tp->key))) {
 		ret = tp->regfunc();
 		if (ret < 0)
 			return ret;
@@ -219,7 +222,9 @@ static int tracepoint_add_func(struct tracepoint *tp,
 	 * is used.
 	 */
 	rcu_assign_pointer(tp->funcs, tp_funcs);
-	if (!static_key_enabled(&tp->key))
+	if (dynamic && !(atomic_read(&tp->key.enabled) > 0))
+		atomic_inc(&tp->key.enabled);
+	else if (!dynamic && !static_key_enabled(&tp->key))
 		static_key_slow_inc(&tp->key);
 	release_probes(old);
 	return 0;
@@ -232,7 +237,7 @@ static int tracepoint_add_func(struct tracepoint *tp,
  * by preempt_disable around the call site.
  */
 static int tracepoint_remove_func(struct tracepoint *tp,
-		struct tracepoint_func *func)
+				  struct tracepoint_func *func, bool dynamic)
 {
 	struct tracepoint_func *old, *tp_funcs;
 
@@ -246,10 +251,14 @@ static int tracepoint_remove_func(struct tracepoint *tp,
 
 	if (!tp_funcs) {
 		/* Removed last function */
-		if (tp->unregfunc && static_key_enabled(&tp->key))
+		if (tp->unregfunc &&
+		    ((dynamic && (atomic_read(&tp->key.enabled) > 0)) ||
+		     static_key_enabled(&tp->key)))
 			tp->unregfunc();
 
-		if (static_key_enabled(&tp->key))
+		if (dynamic && (atomic_read(&tp->key.enabled) > 0))
+			atomic_dec(&tp->key.enabled);
+		else if (!dynamic && static_key_enabled(&tp->key))
 			static_key_slow_dec(&tp->key);
 	}
 	rcu_assign_pointer(tp->funcs, tp_funcs);
@@ -258,7 +267,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
 }
 
 /**
- * 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
@@ -271,7 +280,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
  * within module exit functions.
  */
 int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe,
-				   void *data, int prio)
+				   void *data, int prio, bool dynamic)
 {
 	struct tracepoint_func tp_func;
 	int ret;
@@ -280,7 +289,7 @@ int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe,
 	tp_func.func = probe;
 	tp_func.data = data;
 	tp_func.prio = prio;
-	ret = tracepoint_add_func(tp, &tp_func, prio);
+	ret = tracepoint_add_func(tp, &tp_func, prio, dynamic);
 	mutex_unlock(&tracepoints_mutex);
 	return ret;
 }
@@ -301,10 +310,18 @@ int tracepoint_probe_register_prio(struct tracepoint *tp, void *probe,
  */
 int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data)
 {
-	return tracepoint_probe_register_prio(tp, probe, data, TRACEPOINT_DEFAULT_PRIO);
+	return tracepoint_probe_register_prio(tp, probe, data, TRACEPOINT_DEFAULT_PRIO, false);
 }
 EXPORT_SYMBOL_GPL(tracepoint_probe_register);
 
+int dynamic_tracepoint_probe_register(struct tracepoint *tp, void *probe,
+				      void *data)
+{
+	return tracepoint_probe_register_prio(tp, probe, data,
+					      TRACEPOINT_DEFAULT_PRIO, true);
+}
+EXPORT_SYMBOL_GPL(dynamic_tracepoint_probe_register);
+
 /**
  * tracepoint_probe_unregister -  Disconnect a probe from a tracepoint
  * @tp: tracepoint
@@ -313,7 +330,8 @@ int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data)
  *
  * Returns 0 if ok, error value on error.
  */
-int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data)
+int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data,
+				bool dynamic)
 {
 	struct tracepoint_func tp_func;
 	int ret;
@@ -321,7 +339,7 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data)
 	mutex_lock(&tracepoints_mutex);
 	tp_func.func = probe;
 	tp_func.data = data;
-	ret = tracepoint_remove_func(tp, &tp_func);
+	ret = tracepoint_remove_func(tp, &tp_func, dynamic);
 	mutex_unlock(&tracepoints_mutex);
 	return ret;
 }
-- 
1.9.3

  parent reply	other threads:[~2017-06-26 22:54 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-26 22:49 [PATCH 00/32] tracing: Inter-event (e.g. latency) support Tom Zanussi
2017-06-26 22:49 ` [PATCH 01/32] tracing: Add hist_field_name() accessor Tom Zanussi
2017-07-13  6:49   ` Piotr Gregor
2017-07-13 14:41     ` Tom Zanussi
2017-07-14  2:19   ` Namhyung Kim
2017-06-26 22:49 ` [PATCH 02/32] tracing: Reimplement log2 Tom Zanussi
2017-07-14  2:33   ` Namhyung Kim
2017-07-14 16:13     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 03/32] ring-buffer: Add interface for setting absolute time stamps Tom Zanussi
2017-07-14  5:25   ` Namhyung Kim
2017-07-14 16:14     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 04/32] ring-buffer: Redefine the unimplemented RINGBUF_TIME_TIME_STAMP Tom Zanussi
2017-07-02  8:51   ` Joel Fernandes (Google)
2017-06-26 22:49 ` [PATCH 05/32] tracing: Give event triggers access to ring_buffer_event Tom Zanussi
2017-06-26 22:49 ` [PATCH 06/32] tracing: Add ring buffer event param to hist field functions Tom Zanussi
2017-06-26 22:49 ` [PATCH 07/32] tracing: Increase tracing map KEYS_MAX size Tom Zanussi
2017-06-26 22:49 ` [PATCH 08/32] tracing: Break out hist trigger assignment parsing Tom Zanussi
2017-06-26 22:49 ` [PATCH 09/32] tracing: Make traceprobe parsing code reusable Tom Zanussi
2017-06-26 22:49 ` [PATCH 10/32] tracing: Add NO_DISCARD event file flag Tom Zanussi
2017-06-26 22:49 ` [PATCH 11/32] tracing: Add post-trigger flag to hist trigger command Tom Zanussi
2017-06-26 22:49 ` [PATCH 12/32] tracing: Add hist trigger timestamp support Tom Zanussi
2017-07-17  6:00   ` Namhyung Kim
2017-07-17 16:57     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 13/32] tracing: Add per-element variable support to tracing_map Tom Zanussi
2017-06-26 22:49 ` [PATCH 14/32] tracing: Add hist_data member to hist_field Tom Zanussi
2017-06-26 22:49 ` [PATCH 15/32] tracing: Add usecs modifier for hist trigger timestamps Tom Zanussi
2017-06-26 22:49 ` [PATCH 16/32] tracing: Add variable support to hist triggers Tom Zanussi
2017-07-19  1:07   ` Namhyung Kim
2017-07-19 15:40     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 17/32] tracing: Account for variables in named trigger compatibility Tom Zanussi
2017-06-26 22:49 ` [PATCH 18/32] tracing: Add simple expression support to hist triggers Tom Zanussi
2017-07-21  2:02   ` Namhyung Kim
2017-07-21 16:29     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 19/32] tracing: Add variable reference handling " Tom Zanussi
2017-07-21  3:31   ` Namhyung Kim
2017-07-21 16:41     ` Tom Zanussi
2017-06-26 22:49 ` Tom Zanussi [this message]
2017-06-26 22:49 ` [PATCH 21/32] tracing: Add hist trigger action hook Tom Zanussi
2017-06-26 22:49 ` [PATCH 22/32] tracing: Add support for 'synthetic' events Tom Zanussi
2017-07-23 12:00   ` Namhyung Kim
2017-07-24 16:11     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 23/32] tracing: Add 'onmatch' hist trigger action support Tom Zanussi
2017-07-23 15:12   ` Namhyung Kim
2017-07-24 16:17     ` Tom Zanussi
2017-07-26  2:40   ` Namhyung Kim
2017-07-26 16:38     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 24/32] tracing: Add 'onmax' " Tom Zanussi
2017-07-26  3:04   ` Namhyung Kim
2017-07-26 16:45     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 25/32] tracing: Allow whitespace to surround hist trigger filter Tom Zanussi
2017-06-26 22:49 ` [PATCH 26/32] tracing: Make duplicate count from tracing_map available Tom Zanussi
2017-06-26 22:49 ` [PATCH 27/32] tracing: Add cpu field for hist triggers Tom Zanussi
2017-06-26 22:49 ` [PATCH 28/32] tracing: Add hist trigger support for variable reference aliases Tom Zanussi
2017-06-26 22:49 ` [PATCH 29/32] tracing: Add 'last error' error facility for hist triggers Tom Zanussi
2017-07-26  4:39   ` Namhyung Kim
2017-07-26 16:47     ` Tom Zanussi
2017-06-26 22:49 ` [PATCH 30/32] tracing: Add inter-event hist trigger Documentation Tom Zanussi
2017-06-26 22:49 ` [PATCH 31/32] tracing: Make tracing_set_clock() non-static Tom Zanussi
2017-06-26 22:49 ` [PATCH 32/32] tracing: Add a clock attribute for hist triggers Tom Zanussi
2017-06-27 14:58 ` [PATCH 00/32] tracing: Inter-event (e.g. latency) support Steven Rostedt
2017-06-28 14:21 ` Masami Hiramatsu
2017-06-28 19:09   ` Tom Zanussi
2017-07-01  7:01 ` Joel Fernandes (Google)
2017-07-12 19:17   ` Tom Zanussi
2017-07-04 16:12 ` Sebastian Andrzej Siewior
2017-07-12 19:20   ` Tom Zanussi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dc94982227615e79df977bd9a3c6b4d3b092ae02.1498510759.git.tom.zanussi@linux.intel.com \
    --to=tom.zanussi@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=vedang.patel@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®