linux-rt-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tom Zanussi <zanussi@kernel.org>
To: rostedt@goodmis.org
Cc: artem.bityutskiy@linux.intel.com, mhiramat@kernel.org,
	linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org
Subject: [PATCH 2/7] tracing: Add get/put_event_file()
Date: Wed, 18 Dec 2019 09:27:38 -0600	[thread overview]
Message-ID: <8ee01da8f9a1aa7bbec4ea9492a464e43d31f70c.1576679206.git.zanussi@kernel.org> (raw)
In-Reply-To: <cover.1576679206.git.zanussi@kernel.org>
In-Reply-To: <cover.1576679206.git.zanussi@kernel.org>

Add a function to get an event file and prevent it from going away on
module or instance removal.

get_event_file() will find an event file in a given instance (if
instance is NULL, it assumes the top trace array) and return it,
pinning the instance's trace array as well as the event's module, if
applicable, so they won't go away while in use.

put_event_file() does the matching release.

Also included are _nolock() versions, which can be used if event_mutex
is already held.

Signed-off-by: Tom Zanussi <zanussi@kernel.org>
---
 include/linux/trace_events.h |  10 ++++
 kernel/trace/trace_events.c  | 130 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 4c6e15605766..cf982c7d6636 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -348,6 +348,16 @@ enum {
 	EVENT_FILE_FL_WAS_ENABLED_BIT,
 };
 
+extern struct trace_event_file *get_event_file(const char *instance,
+					       const char *system,
+					       const char *event);
+extern struct trace_event_file *get_event_file_nolock(const char *instance,
+						      const char *system,
+						      const char *event);
+
+extern void put_event_file(struct trace_event_file *file);
+extern void put_event_file_nolock(struct trace_event_file *file);
+
 /*
  * Event file flags:
  *  ENABLED	  - The event is enabled
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index c6de3cebc127..2ee417d003eb 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2535,6 +2535,136 @@ find_event_file(struct trace_array *tr, const char *system, const char *event)
 	return file;
 }
 
+static struct trace_event_file *__get_event_file(const char *instance,
+						 const char *system,
+						 const char *event,
+						 bool lock)
+{
+	struct trace_array *tr = top_trace_array();
+	struct trace_event_file *file = NULL;
+	int ret = -EINVAL;
+
+	if (instance) {
+		tr = trace_array_find(instance);
+		if (!tr)
+			return ERR_PTR(ret);
+	}
+
+	ret = trace_array_get(tr);
+	if (ret)
+		return ERR_PTR(ret);
+
+	if (lock)
+		mutex_lock(&event_mutex);
+
+	file = find_event_file(tr, system, event);
+	if (!file) {
+		trace_array_put(tr);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* Don't let event modules unload while in use */
+	ret = try_module_get(file->event_call->mod);
+	if (!ret) {
+		trace_array_put(tr);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = 0;
+ out:
+	if (lock)
+		mutex_unlock(&event_mutex);
+
+	if (ret)
+		file = ERR_PTR(ret);
+
+	return file;
+}
+
+/**
+ * get_event_file - Find and return a trace event file
+ * @instance: The name of the trace instance containing the event
+ * @system: The name of the system containing the event
+ * @event: The name of the event
+ *
+ * Return a trace event file given the trace instance name, trace
+ * system, and trace event name.  If the instance name is NULL, it
+ * refers to the top-level trace array.
+ *
+ * This function will look it up and return it if found, after calling
+ * trace_array_get() to prevent the instance from going away, and
+ * increment the event's module refcount to prevent it from being
+ * removed.
+ *
+ * To release the file, call put_event_file(), which will call
+ * trace_array_put() and decrement the event's module refcount.
+ *
+ * Return: The trace event on success, ERR_PTR otherwise.
+ */
+struct trace_event_file *get_event_file(const char *instance,
+					const char *system,
+					const char *event)
+{
+	return __get_event_file(instance, system, event, true);
+}
+EXPORT_SYMBOL_GPL(get_event_file);
+
+/**
+ * get_event_file_nolock - non-locking version of get_event_file
+ *
+ * Same as get_event_file() but doesn't take event_mutex.  See
+ * get_event_file() for details.
+ */
+struct trace_event_file *get_event_file_nolock(const char *instance,
+					       const char *system,
+					       const char *event)
+{
+	return __get_event_file(instance, system, event, false);
+}
+EXPORT_SYMBOL_GPL(get_event_file_nolock);
+
+/**
+ * put_event_file - Release a file from get_event_file()
+ * @file: The trace event file
+ *
+ * If a file was retrieved using get_event_file(), this should be
+ * called when it's no longer needed.  It will cancel the previous
+ * trace_array_get() called by that function, and decrement the
+ * event's module refcount.
+ */
+void __put_event_file(struct trace_event_file *file, bool lock)
+{
+	trace_array_put(file->tr);
+
+	if (lock)
+		mutex_lock(&event_mutex);
+
+	module_put(file->event_call->mod);
+
+	if (lock)
+		mutex_unlock(&event_mutex);
+}
+
+void put_event_file(struct trace_event_file *file)
+{
+	return __put_event_file(file, true);
+}
+EXPORT_SYMBOL_GPL(put_event_file);
+
+/**
+ * put_event_file_nolock - non-locking version of put_event_file
+ *
+ * Same as put_event_file() but doesn't take event_mutex.  See
+ * put_event_file() for details.
+ */
+void put_event_file_nolock(struct trace_event_file *file)
+{
+	return __put_event_file(file, false);
+}
+EXPORT_SYMBOL_GPL(put_event_file_nolock);
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 /* Avoid typos */
-- 
2.14.1


  parent reply	other threads:[~2019-12-18 15:28 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-18 15:27 [PATCH 0/7] tracing: Add support for in-kernel synthetic event API Tom Zanussi
2019-12-18 15:27 ` [PATCH 1/7] tracing: Add trace_array_find() to find instance trace arrays Tom Zanussi
2019-12-18 15:27 ` Tom Zanussi [this message]
2019-12-18 15:27 ` [PATCH 3/7] tracing: Add delete_synth_event() Tom Zanussi
2019-12-18 15:27 ` [PATCH 4/7] tracing: Add create_synth_event() Tom Zanussi
2019-12-18 15:27 ` [PATCH 5/7] tracing: Add generate_synth_event() and related functions Tom Zanussi
2019-12-18 15:27 ` [PATCH 6/7] tracing: Add synth event generation test module Tom Zanussi
2019-12-18 15:27 ` [PATCH 7/7] tracing: Documentation for in-kernel synthetic event API Tom Zanussi
2019-12-19 14:45 ` [PATCH 0/7] tracing: Add support " Masami Hiramatsu
2019-12-19 16:24   ` Tom Zanussi
2019-12-20  8:41     ` Masami Hiramatsu
2019-12-20 16:24       ` 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=8ee01da8f9a1aa7bbec4ea9492a464e43d31f70c.1576679206.git.zanussi@kernel.org \
    --to=zanussi@kernel.org \
    --cc=artem.bityutskiy@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=rostedt@goodmis.org \
    /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;
as well as URLs for NNTP newsgroup(s).