All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org, Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Corey Ashford <cjashfor@linux.vnet.ibm.com>,
	David Ahern <dsahern@gmail.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Paul Mackerras <paulus@samba.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Stephane Eranian <eranian@google.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 16/19] perf tools: Add kmod_path__parse function
Date: Sat, 21 Mar 2015 15:54:35 -0300	[thread overview]
Message-ID: <1426964078-16384-17-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1426964078-16384-1-git-send-email-acme@kernel.org>

From: Jiri Olsa <jolsa@kernel.org>

Provides united way of parsing kernel module path
into several components.

The new kmod_path__parse function and few defines:

  int __kmod_path__parse(struct kmod_path *m, const char *path,
                         bool alloc_name, bool alloc_ext);

  #define kmod_path__parse(__m, __p)      __kmod_path__parse(__m, __p, false, false)
  #define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
  #define kmod_path__parse_ext(__m, __p)  __kmod_path__parse(__m, __p, false, true)

parse kernel module @path and updates @m argument like:

  @comp - true if @path contains supported compression suffix,
          false otherwise
  @kmod - true if @path contains '.ko' suffix in right position,
          false otherwise
  @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
          of the kernel module without suffixes, otherwise strudup-ed
          base name of @path
  @ext  - if (@alloc_ext && @comp) is true, it contains strdup-ed string
          the compression suffix

It returns 0 if there's no strdup error, -ENOMEM otherwise.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-9t6eqg8j610r94l743hkntiv@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 +++
 tools/perf/tests/kmod-path.c    | 73 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/dso.c           | 66 +++++++++++++++++++++++++++++++++++++
 tools/perf/util/dso.h           | 14 ++++++++
 6 files changed, 159 insertions(+)
 create mode 100644 tools/perf/tests/kmod-path.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 2de01a4b4084..6a8801b32017 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -30,6 +30,7 @@ perf-y += keep-tracking.o
 perf-y += code-reading.o
 perf-y += sample-parsing.o
 perf-y += parse-no-sample-id-all.o
+perf-y += kmod-path.o
 
 perf-$(CONFIG_X86) += perf-time-to-tsc.o
 
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ed8e05c6839a..4f4098167112 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -167,6 +167,10 @@ static struct test {
 		.func = test__fdarray__add,
 	},
 	{
+		.desc = "Test kmod_path__parse function",
+		.func = test__kmod_path__parse,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c
new file mode 100644
index 000000000000..e8d7cbb9320c
--- /dev/null
+++ b/tools/perf/tests/kmod-path.c
@@ -0,0 +1,73 @@
+#include <stdbool.h>
+#include "tests.h"
+#include "dso.h"
+#include "debug.h"
+
+static int test(const char *path, bool alloc_name, bool alloc_ext,
+		bool kmod, bool comp, const char *name, const char *ext)
+{
+	struct kmod_path m;
+
+	memset(&m, 0x0, sizeof(m));
+
+	TEST_ASSERT_VAL("kmod_path__parse",
+			!__kmod_path__parse(&m, path, alloc_name, alloc_ext));
+
+	pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
+		 path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
+
+	TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
+	TEST_ASSERT_VAL("wrong comp", m.comp == comp);
+
+	if (ext)
+		TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
+	else
+		TEST_ASSERT_VAL("wrong ext", !m.ext);
+
+	if (name)
+		TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
+	else
+		TEST_ASSERT_VAL("wrong name", !m.name);
+
+	free(m.name);
+	free(m.ext);
+	return 0;
+}
+
+#define T(path, an, ae, k, c, n, e) \
+	TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
+
+int test__kmod_path__parse(void)
+{
+	/* path                alloc_name  alloc_ext   kmod  comp   name     ext */
+	T("/xxxx/xxxx/x-x.ko", true      , true      , true, false, "[x_x]", NULL);
+	T("/xxxx/xxxx/x-x.ko", false     , true      , true, false, NULL   , NULL);
+	T("/xxxx/xxxx/x-x.ko", true      , false     , true, false, "[x_x]", NULL);
+	T("/xxxx/xxxx/x-x.ko", false     , false     , true, false, NULL   , NULL);
+
+	/* path                alloc_name  alloc_ext   kmod  comp  name   ext */
+	T("/xxxx/xxxx/x.ko.gz", true     , true      , true, true, "[x]", "gz");
+	T("/xxxx/xxxx/x.ko.gz", false    , true      , true, true, NULL , "gz");
+	T("/xxxx/xxxx/x.ko.gz", true     , false     , true, true, "[x]", NULL);
+	T("/xxxx/xxxx/x.ko.gz", false    , false     , true, true, NULL , NULL);
+
+	/* path              alloc_name  alloc_ext  kmod   comp  name    ext */
+	T("/xxxx/xxxx/x.gz", true      , true     , false, true, "x.gz" ,"gz");
+	T("/xxxx/xxxx/x.gz", false     , true     , false, true, NULL   ,"gz");
+	T("/xxxx/xxxx/x.gz", true      , false    , false, true, "x.gz" , NULL);
+	T("/xxxx/xxxx/x.gz", false     , false    , false, true, NULL   , NULL);
+
+	/* path   alloc_name  alloc_ext  kmod   comp  name     ext */
+	T("x.gz", true      , true     , false, true, "x.gz", "gz");
+	T("x.gz", false     , true     , false, true, NULL  , "gz");
+	T("x.gz", true      , false    , false, true, "x.gz", NULL);
+	T("x.gz", false     , false    , false, true, NULL  , NULL);
+
+	/* path      alloc_name  alloc_ext  kmod  comp  name  ext */
+	T("x.ko.gz", true      , true     , true, true, "[x]", "gz");
+	T("x.ko.gz", false     , true     , true, true, NULL , "gz");
+	T("x.ko.gz", true      , false    , true, true, "[x]", NULL);
+	T("x.ko.gz", false     , false    , true, true, NULL , NULL);
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 00e776a87a9c..52758a33f64c 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -51,6 +51,7 @@ int test__hists_cumulate(void);
 int test__switch_tracking(void);
 int test__fdarray__filter(void);
 int test__fdarray__add(void);
+int test__kmod_path__parse(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index be368414036c..3e6863feb066 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -212,6 +212,72 @@ bool dso__needs_decompress(struct dso *dso)
 }
 
 /*
+ * Parses kernel module specified in @path and updates
+ * @m argument like:
+ *
+ *    @comp - true if @path contains supported compression suffix,
+ *            false otherwise
+ *    @kmod - true if @path contains '.ko' suffix in right position,
+ *            false otherwise
+ *    @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
+ *            of the kernel module without suffixes, otherwise strudup-ed
+ *            base name of @path
+ *    @ext  - if (@alloc_ext && @comp) is true, it contains strdup-ed string
+ *            the compression suffix
+ *
+ * Returns 0 if there's no strdup error, -ENOMEM otherwise.
+ */
+int __kmod_path__parse(struct kmod_path *m, const char *path,
+		       bool alloc_name, bool alloc_ext)
+{
+	const char *name = strrchr(path, '/');
+	const char *ext  = strrchr(path, '.');
+
+	memset(m, 0x0, sizeof(*m));
+	name = name ? name + 1 : path;
+
+	/* No extension, just return name. */
+	if (ext == NULL) {
+		if (alloc_name) {
+			m->name = strdup(name);
+			return m->name ? 0 : -ENOMEM;
+		}
+		return 0;
+	}
+
+	if (is_supported_compression(ext + 1)) {
+		m->comp = true;
+		ext -= 3;
+	}
+
+	/* Check .ko extension only if there's enough name left. */
+	if (ext > name)
+		m->kmod = !strncmp(ext, ".ko", 3);
+
+	if (alloc_name) {
+		if (m->kmod) {
+			if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
+				return -ENOMEM;
+		} else {
+			if (asprintf(&m->name, "%s", name) == -1)
+				return -ENOMEM;
+		}
+
+		strxfrchar(m->name, '-', '_');
+	}
+
+	if (alloc_ext && m->comp) {
+		m->ext = strdup(ext + 4);
+		if (!m->ext) {
+			free((void *) m->name);
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Global list of open DSOs and the counter.
  */
 static LIST_HEAD(dso__data_open);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 408c65f1a757..384cd2918e8f 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -195,6 +195,20 @@ bool is_kernel_module(const char *pathname, bool *compressed);
 bool decompress_to_file(const char *ext, const char *filename, int output_fd);
 bool dso__needs_decompress(struct dso *dso);
 
+struct kmod_path {
+	char *name;
+	char *ext;
+	bool  comp;
+	bool  kmod;
+};
+
+int __kmod_path__parse(struct kmod_path *m, const char *path,
+		     bool alloc_name, bool alloc_ext);
+
+#define kmod_path__parse(__m, __p)      __kmod_path__parse(__m, __p, false, false)
+#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
+#define kmod_path__parse_ext(__m, __p)  __kmod_path__parse(__m, __p, false, true)
+
 /*
  * The dso__data_* external interface provides following functions:
  *   dso__data_fd
-- 
1.9.3


  parent reply	other threads:[~2015-03-21 18:56 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-21 18:54 [GIT PULL 00/19] perf/core improvements and fixes Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 01/19] perf tools: Fix race in build_id_cache__add_s() Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 02/19] perf tools: Don't allow empty argument for field-separator Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 03/19] perf build: Use FEATURE-DUMP instead of PERF-FEATURES in the .gitignore file Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 04/19] perf build: Add config/feature-checks/*.output to " Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 05/19] perf probe: Fix failure to add multiple probes without debuginfo Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 06/19] perf trace: Fix summary_only option Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 07/19] perf build: Fix feature_check name clash Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 08/19] perf build: Separate feature make support into config/Makefile.feature Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 09/19] perf build: Make features checks directory configurable Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 10/19] perf build: Move feature checks code under tools/build Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 11/19] perf trace: Handle legacy syscalls tracepoints Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 12/19] perf hists browser: Indicate which callchain entries are annotated Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 13/19] tools lib traceevent: Add destructor for format_field Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 14/19] tools build: Add feature check for lzma library Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 15/19] perf tools: Add lzma decompression support for kernel module Arnaldo Carvalho de Melo
2015-03-21 18:54 ` Arnaldo Carvalho de Melo [this message]
2015-03-21 18:54 ` [PATCH 17/19] perf tools: Add dsos__addnew function Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 18/19] perf tools: Add machine__module_dso function Arnaldo Carvalho de Melo
2015-03-21 18:54 ` [PATCH 19/19] perf tools: Use kmod_path__parse for machine__new_dso Arnaldo Carvalho de Melo
2015-03-22  9:58 ` [GIT PULL 00/19] perf/core improvements and fixes Ingo Molnar

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=1426964078-16384-17-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=cjashfor@linux.vnet.ibm.com \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=paulus@samba.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.