linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] perf tools: Add hist_entry allocation callbacks
@ 2016-07-05  6:56 Jiri Olsa
  2016-07-05  6:56 ` [PATCH 1/3] perf tools: Introduce hist_entry__init function Jiri Olsa
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Jiri Olsa @ 2016-07-05  6:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra

hi,
this patchset tries to add support provide own allocation
zalloc/free methods for hist_entry object.

v2 changes:
  - merged patch 1 and 2 from RFC

The reason is to provide a way to be able to store more
data within hist_entry object in a transparent way to
its current usage by allocating its own hist_entry sub
object.

The user/app which wants to allocate its own hist_entry
sub object provides following ops struct:

  struct hist_entry_ops *ops {
    void*   (*new)(size_t);
    void    (*free)(void *);
  }

via new interface function:

  struct hist_entry *
  hists__add_entry_ops(struct hists *hists,
                       struct hist_entry_ops *ops,
                       ...

I'm using this for c2c code to enlarge hist_entry object
with large stats structure, which has no use to standard
perf usage/commands.

It might be used to lower the hist_entry footproint for
default perf usage by uing this for things like hierarchy
output that adds extra stuff into hist_entry object.

Available at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/he_ops

thanks,
jirka


---
Jiri Olsa (3):
      perf tools: Introduce hist_entry__init function
      perf tools: Introduce hist_entry_ops
      perf tools: Introduce hists__add_entry_ops function

 tools/perf/util/hist.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------
 tools/perf/util/hist.h |  11 ++++++
 tools/perf/util/sort.h |   6 ++++
 3 files changed, 148 insertions(+), 73 deletions(-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] perf tools: Introduce hist_entry__init function
  2016-07-05  6:56 [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Jiri Olsa
@ 2016-07-05  6:56 ` Jiri Olsa
  2016-07-13  7:00   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
  2016-07-05  6:56 ` [PATCH 2/3] perf tools: Introduce hist_entry_ops Jiri Olsa
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Jiri Olsa @ 2016-07-05  6:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra

Move hist_entry initialization code into separate function.
It'll be useful and more clear for following patches that
introduce allocation callbacks.

Releasing the hist_entry object in hist_entry__new function
(where it's allocated) rather than in hist_entry__init.

Link: http://lkml.kernel.org/n/tip-j8dz6ytir91x8qd1zk4vf7ki@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/hist.c | 139 ++++++++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 66 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e1fcc8d7c01a..04f3b52a319c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -352,86 +352,93 @@ void hists__delete_entries(struct hists *hists)
  * histogram, sorted on item, collects periods
  */
 
-static struct hist_entry *hist_entry__new(struct hist_entry *template,
-					  bool sample_self)
-{
-	size_t callchain_size = 0;
-	struct hist_entry *he;
+static int hist_entry__init(struct hist_entry *he,
+			    struct hist_entry *template,
+			    bool sample_self)
+{
+	*he = *template;
+
+	if (symbol_conf.cumulate_callchain) {
+		he->stat_acc = malloc(sizeof(he->stat));
+		if (he->stat_acc == NULL)
+			return -ENOMEM;
+		memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
+		if (!sample_self)
+			memset(&he->stat, 0, sizeof(he->stat));
+	}
 
-	if (symbol_conf.use_callchain)
-		callchain_size = sizeof(struct callchain_root);
+	map__get(he->ms.map);
 
-	he = zalloc(sizeof(*he) + callchain_size);
+	if (he->branch_info) {
+		/*
+		 * This branch info is (a part of) allocated from
+		 * sample__resolve_bstack() and will be freed after
+		 * adding new entries.  So we need to save a copy.
+		 */
+		he->branch_info = malloc(sizeof(*he->branch_info));
+		if (he->branch_info == NULL) {
+			map__zput(he->ms.map);
+			free(he->stat_acc);
+			return -ENOMEM;
+		}
 
-	if (he != NULL) {
-		*he = *template;
+		memcpy(he->branch_info, template->branch_info,
+		       sizeof(*he->branch_info));
 
-		if (symbol_conf.cumulate_callchain) {
-			he->stat_acc = malloc(sizeof(he->stat));
-			if (he->stat_acc == NULL) {
-				free(he);
-				return NULL;
-			}
-			memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
-			if (!sample_self)
-				memset(&he->stat, 0, sizeof(he->stat));
-		}
+		map__get(he->branch_info->from.map);
+		map__get(he->branch_info->to.map);
+	}
 
-		map__get(he->ms.map);
+	if (he->mem_info) {
+		map__get(he->mem_info->iaddr.map);
+		map__get(he->mem_info->daddr.map);
+	}
 
-		if (he->branch_info) {
-			/*
-			 * This branch info is (a part of) allocated from
-			 * sample__resolve_bstack() and will be freed after
-			 * adding new entries.  So we need to save a copy.
-			 */
-			he->branch_info = malloc(sizeof(*he->branch_info));
-			if (he->branch_info == NULL) {
-				map__zput(he->ms.map);
-				free(he->stat_acc);
-				free(he);
-				return NULL;
-			}
+	if (symbol_conf.use_callchain)
+		callchain_init(he->callchain);
 
-			memcpy(he->branch_info, template->branch_info,
-			       sizeof(*he->branch_info));
+	if (he->raw_data) {
+		he->raw_data = memdup(he->raw_data, he->raw_size);
 
-			map__get(he->branch_info->from.map);
-			map__get(he->branch_info->to.map);
+		if (he->raw_data == NULL) {
+			map__put(he->ms.map);
+			if (he->branch_info) {
+				map__put(he->branch_info->from.map);
+				map__put(he->branch_info->to.map);
+				free(he->branch_info);
+			}
+			if (he->mem_info) {
+				map__put(he->mem_info->iaddr.map);
+				map__put(he->mem_info->daddr.map);
+			}
+			free(he->stat_acc);
+			return -ENOMEM;
 		}
+	}
+	INIT_LIST_HEAD(&he->pairs.node);
+	thread__get(he->thread);
 
-		if (he->mem_info) {
-			map__get(he->mem_info->iaddr.map);
-			map__get(he->mem_info->daddr.map);
-		}
+	if (!symbol_conf.report_hierarchy)
+		he->leaf = true;
 
-		if (symbol_conf.use_callchain)
-			callchain_init(he->callchain);
+	return 0;
+}
 
-		if (he->raw_data) {
-			he->raw_data = memdup(he->raw_data, he->raw_size);
+static struct hist_entry *hist_entry__new(struct hist_entry *template,
+					  bool sample_self)
+{
+	size_t callchain_size = 0;
+	struct hist_entry *he;
+	int err = 0;
 
-			if (he->raw_data == NULL) {
-				map__put(he->ms.map);
-				if (he->branch_info) {
-					map__put(he->branch_info->from.map);
-					map__put(he->branch_info->to.map);
-					free(he->branch_info);
-				}
-				if (he->mem_info) {
-					map__put(he->mem_info->iaddr.map);
-					map__put(he->mem_info->daddr.map);
-				}
-				free(he->stat_acc);
-				free(he);
-				return NULL;
-			}
-		}
-		INIT_LIST_HEAD(&he->pairs.node);
-		thread__get(he->thread);
+	if (symbol_conf.use_callchain)
+		callchain_size = sizeof(struct callchain_root);
 
-		if (!symbol_conf.report_hierarchy)
-			he->leaf = true;
+	he = zalloc(sizeof(*he) + callchain_size);
+	if (he) {
+		err = hist_entry__init(he, template, sample_self);
+		if (err)
+			zfree(&he);
 	}
 
 	return he;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] perf tools: Introduce hist_entry_ops
  2016-07-05  6:56 [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Jiri Olsa
  2016-07-05  6:56 ` [PATCH 1/3] perf tools: Introduce hist_entry__init function Jiri Olsa
@ 2016-07-05  6:56 ` Jiri Olsa
  2016-07-13  7:01   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
  2016-07-05  6:56 ` [PATCH 3/3] perf tools: Introduce hists__add_entry_ops function Jiri Olsa
  2016-07-05 14:15 ` [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Arnaldo Carvalho de Melo
  3 siblings, 1 reply; 8+ messages in thread
From: Jiri Olsa @ 2016-07-05  6:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra

Introducing allocation callbacks, that allows to extend
current hist_entry object into objects with special needs
without polluting the current hist_entry object.

Link: http://lkml.kernel.org/n/tip-yvapb3gmmn01qo7qn9lzl9vr@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/hist.c | 31 +++++++++++++++++++++++++++----
 tools/perf/util/sort.h |  6 ++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 04f3b52a319c..355b7601ddb7 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -424,21 +424,42 @@ static int hist_entry__init(struct hist_entry *he,
 	return 0;
 }
 
+static void *hist_entry__zalloc(size_t size)
+{
+	return zalloc(size + sizeof(struct hist_entry));
+}
+
+static void hist_entry__free(void *ptr)
+{
+	free(ptr);
+}
+
+static struct hist_entry_ops default_ops = {
+	.new	= hist_entry__zalloc,
+	.free	= hist_entry__free,
+};
+
 static struct hist_entry *hist_entry__new(struct hist_entry *template,
 					  bool sample_self)
 {
+	struct hist_entry_ops *ops = template->ops;
 	size_t callchain_size = 0;
 	struct hist_entry *he;
 	int err = 0;
 
+	if (!ops)
+		ops = template->ops = &default_ops;
+
 	if (symbol_conf.use_callchain)
 		callchain_size = sizeof(struct callchain_root);
 
-	he = zalloc(sizeof(*he) + callchain_size);
+	he = ops->new(callchain_size);
 	if (he) {
 		err = hist_entry__init(he, template, sample_self);
-		if (err)
-			zfree(&he);
+		if (err) {
+			ops->free(he);
+			he = NULL;
+		}
 	}
 
 	return he;
@@ -1050,6 +1071,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 
 void hist_entry__delete(struct hist_entry *he)
 {
+	struct hist_entry_ops *ops = he->ops;
+
 	thread__zput(he->thread);
 	map__zput(he->ms.map);
 
@@ -1074,7 +1097,7 @@ void hist_entry__delete(struct hist_entry *he)
 	free_callchain(he->callchain);
 	free(he->trace_output);
 	free(he->raw_data);
-	free(he);
+	ops->free(he);
 }
 
 /*
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index ebb59cacd092..6fd0801d58a4 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -67,6 +67,11 @@ struct hist_entry_diff {
 	};
 };
 
+struct hist_entry_ops {
+	void*	(*new)(size_t);
+	void	(*free)(void *);
+};
+
 /**
  * struct hist_entry - histogram entry
  *
@@ -125,6 +130,7 @@ struct hist_entry {
 	void			*trace_output;
 	struct perf_hpp_list	*hpp_list;
 	struct hist_entry	*parent_he;
+	struct hist_entry_ops	*ops;
 	union {
 		/* this is for hierarchical entry structure */
 		struct {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] perf tools: Introduce hists__add_entry_ops function
  2016-07-05  6:56 [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Jiri Olsa
  2016-07-05  6:56 ` [PATCH 1/3] perf tools: Introduce hist_entry__init function Jiri Olsa
  2016-07-05  6:56 ` [PATCH 2/3] perf tools: Introduce hist_entry_ops Jiri Olsa
@ 2016-07-05  6:56 ` Jiri Olsa
  2016-07-13  7:01   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
  2016-07-05 14:15 ` [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Arnaldo Carvalho de Melo
  3 siblings, 1 reply; 8+ messages in thread
From: Jiri Olsa @ 2016-07-05  6:56 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra

Introducing hists__add_entry_ops function to allow using
the allocation callbacks externally.

Link: http://lkml.kernel.org/n/tip-r4bumbbg5st7p38hjm2z16b5@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/hist.c | 42 +++++++++++++++++++++++++++++++++++-------
 tools/perf/util/hist.h | 11 +++++++++++
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 355b7601ddb7..a18d142cdca3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -559,13 +559,15 @@ out:
 	return he;
 }
 
-struct hist_entry *hists__add_entry(struct hists *hists,
-				    struct addr_location *al,
-				    struct symbol *sym_parent,
-				    struct branch_info *bi,
-				    struct mem_info *mi,
-				    struct perf_sample *sample,
-				    bool sample_self)
+static struct hist_entry*
+__hists__add_entry(struct hists *hists,
+		   struct addr_location *al,
+		   struct symbol *sym_parent,
+		   struct branch_info *bi,
+		   struct mem_info *mi,
+		   struct perf_sample *sample,
+		   bool sample_self,
+		   struct hist_entry_ops *ops)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -592,11 +594,37 @@ struct hist_entry *hists__add_entry(struct hists *hists,
 		.transaction = sample->transaction,
 		.raw_data = sample->raw_data,
 		.raw_size = sample->raw_size,
+		.ops = ops,
 	};
 
 	return hists__findnew_entry(hists, &entry, al, sample_self);
 }
 
+struct hist_entry *hists__add_entry(struct hists *hists,
+				    struct addr_location *al,
+				    struct symbol *sym_parent,
+				    struct branch_info *bi,
+				    struct mem_info *mi,
+				    struct perf_sample *sample,
+				    bool sample_self)
+{
+	return __hists__add_entry(hists, al, sym_parent, bi, mi,
+				  sample, sample_self, NULL);
+}
+
+struct hist_entry *hists__add_entry_ops(struct hists *hists,
+					struct hist_entry_ops *ops,
+					struct addr_location *al,
+					struct symbol *sym_parent,
+					struct branch_info *bi,
+					struct mem_info *mi,
+					struct perf_sample *sample,
+					bool sample_self)
+{
+	return __hists__add_entry(hists, al, sym_parent, bi, mi,
+				  sample, sample_self, ops);
+}
+
 static int
 iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused,
 		    struct addr_location *al __maybe_unused)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 0a03e08be503..49aa4fac148f 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -10,6 +10,7 @@
 #include "ui/progress.h"
 
 struct hist_entry;
+struct hist_entry_ops;
 struct addr_location;
 struct symbol;
 
@@ -127,6 +128,16 @@ struct hist_entry *hists__add_entry(struct hists *hists,
 				    struct mem_info *mi,
 				    struct perf_sample *sample,
 				    bool sample_self);
+
+struct hist_entry *hists__add_entry_ops(struct hists *hists,
+					struct hist_entry_ops *ops,
+					struct addr_location *al,
+					struct symbol *sym_parent,
+					struct branch_info *bi,
+					struct mem_info *mi,
+					struct perf_sample *sample,
+					bool sample_self);
+
 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 			 int max_stack_depth, void *arg);
 
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/3] perf tools: Add hist_entry allocation callbacks
  2016-07-05  6:56 [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Jiri Olsa
                   ` (2 preceding siblings ...)
  2016-07-05  6:56 ` [PATCH 3/3] perf tools: Introduce hists__add_entry_ops function Jiri Olsa
@ 2016-07-05 14:15 ` Arnaldo Carvalho de Melo
  3 siblings, 0 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-05 14:15 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: lkml, David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra

Em Tue, Jul 05, 2016 at 08:56:02AM +0200, Jiri Olsa escreveu:
> hi,
> this patchset tries to add support provide own allocation
> zalloc/free methods for hist_entry object.
> 
> v2 changes:
>   - merged patch 1 and 2 from RFC

Thanks applied.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [tip:perf/core] perf hists: Introduce hist_entry__init function
  2016-07-05  6:56 ` [PATCH 1/3] perf tools: Introduce hist_entry__init function Jiri Olsa
@ 2016-07-13  7:00   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Jiri Olsa @ 2016-07-13  7:00 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: namhyung, a.p.zijlstra, acme, linux-kernel, hpa, jolsa, mingo,
	tglx, dsahern

Commit-ID:  0a269a6bb3f86abb218b8632f13c4ecd9b6b92af
Gitweb:     http://git.kernel.org/tip/0a269a6bb3f86abb218b8632f13c4ecd9b6b92af
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Tue, 5 Jul 2016 08:56:03 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 12 Jul 2016 00:00:39 -0300

perf hists: Introduce hist_entry__init function

Move the 'struct hist_entry' initialization code to a separate function.
It'll be useful and more clear for the following patches that introduce
allocation callbacks.

Releasing the hist_entry object in hist_entry__new function
(where it's allocated) rather than in hist_entry__init.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1467701765-26194-2-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/hist.c | 139 ++++++++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 66 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e1fcc8d..04f3b52 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -352,86 +352,93 @@ void hists__delete_entries(struct hists *hists)
  * histogram, sorted on item, collects periods
  */
 
-static struct hist_entry *hist_entry__new(struct hist_entry *template,
-					  bool sample_self)
-{
-	size_t callchain_size = 0;
-	struct hist_entry *he;
+static int hist_entry__init(struct hist_entry *he,
+			    struct hist_entry *template,
+			    bool sample_self)
+{
+	*he = *template;
+
+	if (symbol_conf.cumulate_callchain) {
+		he->stat_acc = malloc(sizeof(he->stat));
+		if (he->stat_acc == NULL)
+			return -ENOMEM;
+		memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
+		if (!sample_self)
+			memset(&he->stat, 0, sizeof(he->stat));
+	}
 
-	if (symbol_conf.use_callchain)
-		callchain_size = sizeof(struct callchain_root);
+	map__get(he->ms.map);
 
-	he = zalloc(sizeof(*he) + callchain_size);
+	if (he->branch_info) {
+		/*
+		 * This branch info is (a part of) allocated from
+		 * sample__resolve_bstack() and will be freed after
+		 * adding new entries.  So we need to save a copy.
+		 */
+		he->branch_info = malloc(sizeof(*he->branch_info));
+		if (he->branch_info == NULL) {
+			map__zput(he->ms.map);
+			free(he->stat_acc);
+			return -ENOMEM;
+		}
 
-	if (he != NULL) {
-		*he = *template;
+		memcpy(he->branch_info, template->branch_info,
+		       sizeof(*he->branch_info));
 
-		if (symbol_conf.cumulate_callchain) {
-			he->stat_acc = malloc(sizeof(he->stat));
-			if (he->stat_acc == NULL) {
-				free(he);
-				return NULL;
-			}
-			memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
-			if (!sample_self)
-				memset(&he->stat, 0, sizeof(he->stat));
-		}
+		map__get(he->branch_info->from.map);
+		map__get(he->branch_info->to.map);
+	}
 
-		map__get(he->ms.map);
+	if (he->mem_info) {
+		map__get(he->mem_info->iaddr.map);
+		map__get(he->mem_info->daddr.map);
+	}
 
-		if (he->branch_info) {
-			/*
-			 * This branch info is (a part of) allocated from
-			 * sample__resolve_bstack() and will be freed after
-			 * adding new entries.  So we need to save a copy.
-			 */
-			he->branch_info = malloc(sizeof(*he->branch_info));
-			if (he->branch_info == NULL) {
-				map__zput(he->ms.map);
-				free(he->stat_acc);
-				free(he);
-				return NULL;
-			}
+	if (symbol_conf.use_callchain)
+		callchain_init(he->callchain);
 
-			memcpy(he->branch_info, template->branch_info,
-			       sizeof(*he->branch_info));
+	if (he->raw_data) {
+		he->raw_data = memdup(he->raw_data, he->raw_size);
 
-			map__get(he->branch_info->from.map);
-			map__get(he->branch_info->to.map);
+		if (he->raw_data == NULL) {
+			map__put(he->ms.map);
+			if (he->branch_info) {
+				map__put(he->branch_info->from.map);
+				map__put(he->branch_info->to.map);
+				free(he->branch_info);
+			}
+			if (he->mem_info) {
+				map__put(he->mem_info->iaddr.map);
+				map__put(he->mem_info->daddr.map);
+			}
+			free(he->stat_acc);
+			return -ENOMEM;
 		}
+	}
+	INIT_LIST_HEAD(&he->pairs.node);
+	thread__get(he->thread);
 
-		if (he->mem_info) {
-			map__get(he->mem_info->iaddr.map);
-			map__get(he->mem_info->daddr.map);
-		}
+	if (!symbol_conf.report_hierarchy)
+		he->leaf = true;
 
-		if (symbol_conf.use_callchain)
-			callchain_init(he->callchain);
+	return 0;
+}
 
-		if (he->raw_data) {
-			he->raw_data = memdup(he->raw_data, he->raw_size);
+static struct hist_entry *hist_entry__new(struct hist_entry *template,
+					  bool sample_self)
+{
+	size_t callchain_size = 0;
+	struct hist_entry *he;
+	int err = 0;
 
-			if (he->raw_data == NULL) {
-				map__put(he->ms.map);
-				if (he->branch_info) {
-					map__put(he->branch_info->from.map);
-					map__put(he->branch_info->to.map);
-					free(he->branch_info);
-				}
-				if (he->mem_info) {
-					map__put(he->mem_info->iaddr.map);
-					map__put(he->mem_info->daddr.map);
-				}
-				free(he->stat_acc);
-				free(he);
-				return NULL;
-			}
-		}
-		INIT_LIST_HEAD(&he->pairs.node);
-		thread__get(he->thread);
+	if (symbol_conf.use_callchain)
+		callchain_size = sizeof(struct callchain_root);
 
-		if (!symbol_conf.report_hierarchy)
-			he->leaf = true;
+	he = zalloc(sizeof(*he) + callchain_size);
+	if (he) {
+		err = hist_entry__init(he, template, sample_self);
+		if (err)
+			zfree(&he);
 	}
 
 	return he;

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [tip:perf/core] perf hists: Introduce hist_entry_ops
  2016-07-05  6:56 ` [PATCH 2/3] perf tools: Introduce hist_entry_ops Jiri Olsa
@ 2016-07-13  7:01   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Jiri Olsa @ 2016-07-13  7:01 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: a.p.zijlstra, jolsa, acme, tglx, hpa, dsahern, mingo, namhyung,
	linux-kernel

Commit-ID:  f542e7670e48bc9d0aed351c1fd2ae0b65cc6f68
Gitweb:     http://git.kernel.org/tip/f542e7670e48bc9d0aed351c1fd2ae0b65cc6f68
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Tue, 5 Jul 2016 08:56:04 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 12 Jul 2016 00:00:39 -0300

perf hists: Introduce hist_entry_ops

Introducing allocation callbacks, that allows to extend current
hist_entry object into objects with special needs without polluting the
current hist_entry object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1467701765-26194-3-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/hist.c | 31 +++++++++++++++++++++++++++----
 tools/perf/util/sort.h |  6 ++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 04f3b52..355b760 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -424,21 +424,42 @@ static int hist_entry__init(struct hist_entry *he,
 	return 0;
 }
 
+static void *hist_entry__zalloc(size_t size)
+{
+	return zalloc(size + sizeof(struct hist_entry));
+}
+
+static void hist_entry__free(void *ptr)
+{
+	free(ptr);
+}
+
+static struct hist_entry_ops default_ops = {
+	.new	= hist_entry__zalloc,
+	.free	= hist_entry__free,
+};
+
 static struct hist_entry *hist_entry__new(struct hist_entry *template,
 					  bool sample_self)
 {
+	struct hist_entry_ops *ops = template->ops;
 	size_t callchain_size = 0;
 	struct hist_entry *he;
 	int err = 0;
 
+	if (!ops)
+		ops = template->ops = &default_ops;
+
 	if (symbol_conf.use_callchain)
 		callchain_size = sizeof(struct callchain_root);
 
-	he = zalloc(sizeof(*he) + callchain_size);
+	he = ops->new(callchain_size);
 	if (he) {
 		err = hist_entry__init(he, template, sample_self);
-		if (err)
-			zfree(&he);
+		if (err) {
+			ops->free(he);
+			he = NULL;
+		}
 	}
 
 	return he;
@@ -1050,6 +1071,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 
 void hist_entry__delete(struct hist_entry *he)
 {
+	struct hist_entry_ops *ops = he->ops;
+
 	thread__zput(he->thread);
 	map__zput(he->ms.map);
 
@@ -1074,7 +1097,7 @@ void hist_entry__delete(struct hist_entry *he)
 	free_callchain(he->callchain);
 	free(he->trace_output);
 	free(he->raw_data);
-	free(he);
+	ops->free(he);
 }
 
 /*
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index ebb59ca..7ca37ea 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -67,6 +67,11 @@ struct hist_entry_diff {
 	};
 };
 
+struct hist_entry_ops {
+	void	*(*new)(size_t size);
+	void	(*free)(void *ptr);
+};
+
 /**
  * struct hist_entry - histogram entry
  *
@@ -125,6 +130,7 @@ struct hist_entry {
 	void			*trace_output;
 	struct perf_hpp_list	*hpp_list;
 	struct hist_entry	*parent_he;
+	struct hist_entry_ops	*ops;
 	union {
 		/* this is for hierarchical entry structure */
 		struct {

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [tip:perf/core] perf hists: Introduce hists__add_entry_ops function
  2016-07-05  6:56 ` [PATCH 3/3] perf tools: Introduce hists__add_entry_ops function Jiri Olsa
@ 2016-07-13  7:01   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Jiri Olsa @ 2016-07-13  7:01 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: a.p.zijlstra, mingo, tglx, dsahern, linux-kernel, namhyung, hpa,
	acme, jolsa

Commit-ID:  a5051979f533afc65112cc42a20f25db08bf2272
Gitweb:     http://git.kernel.org/tip/a5051979f533afc65112cc42a20f25db08bf2272
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Tue, 5 Jul 2016 08:56:05 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 12 Jul 2016 00:00:39 -0300

perf hists: Introduce hists__add_entry_ops function

Introducing hists__add_entry_ops function to allow using the allocation
callbacks externally.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1467701765-26194-4-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/hist.c | 42 +++++++++++++++++++++++++++++++++++-------
 tools/perf/util/hist.h | 11 +++++++++++
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 355b760..a18d142 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -559,13 +559,15 @@ out:
 	return he;
 }
 
-struct hist_entry *hists__add_entry(struct hists *hists,
-				    struct addr_location *al,
-				    struct symbol *sym_parent,
-				    struct branch_info *bi,
-				    struct mem_info *mi,
-				    struct perf_sample *sample,
-				    bool sample_self)
+static struct hist_entry*
+__hists__add_entry(struct hists *hists,
+		   struct addr_location *al,
+		   struct symbol *sym_parent,
+		   struct branch_info *bi,
+		   struct mem_info *mi,
+		   struct perf_sample *sample,
+		   bool sample_self,
+		   struct hist_entry_ops *ops)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -592,11 +594,37 @@ struct hist_entry *hists__add_entry(struct hists *hists,
 		.transaction = sample->transaction,
 		.raw_data = sample->raw_data,
 		.raw_size = sample->raw_size,
+		.ops = ops,
 	};
 
 	return hists__findnew_entry(hists, &entry, al, sample_self);
 }
 
+struct hist_entry *hists__add_entry(struct hists *hists,
+				    struct addr_location *al,
+				    struct symbol *sym_parent,
+				    struct branch_info *bi,
+				    struct mem_info *mi,
+				    struct perf_sample *sample,
+				    bool sample_self)
+{
+	return __hists__add_entry(hists, al, sym_parent, bi, mi,
+				  sample, sample_self, NULL);
+}
+
+struct hist_entry *hists__add_entry_ops(struct hists *hists,
+					struct hist_entry_ops *ops,
+					struct addr_location *al,
+					struct symbol *sym_parent,
+					struct branch_info *bi,
+					struct mem_info *mi,
+					struct perf_sample *sample,
+					bool sample_self)
+{
+	return __hists__add_entry(hists, al, sym_parent, bi, mi,
+				  sample, sample_self, ops);
+}
+
 static int
 iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused,
 		    struct addr_location *al __maybe_unused)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 0a03e08..49aa4fa 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -10,6 +10,7 @@
 #include "ui/progress.h"
 
 struct hist_entry;
+struct hist_entry_ops;
 struct addr_location;
 struct symbol;
 
@@ -127,6 +128,16 @@ struct hist_entry *hists__add_entry(struct hists *hists,
 				    struct mem_info *mi,
 				    struct perf_sample *sample,
 				    bool sample_self);
+
+struct hist_entry *hists__add_entry_ops(struct hists *hists,
+					struct hist_entry_ops *ops,
+					struct addr_location *al,
+					struct symbol *sym_parent,
+					struct branch_info *bi,
+					struct mem_info *mi,
+					struct perf_sample *sample,
+					bool sample_self);
+
 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 			 int max_stack_depth, void *arg);
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-07-13  7:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-05  6:56 [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Jiri Olsa
2016-07-05  6:56 ` [PATCH 1/3] perf tools: Introduce hist_entry__init function Jiri Olsa
2016-07-13  7:00   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
2016-07-05  6:56 ` [PATCH 2/3] perf tools: Introduce hist_entry_ops Jiri Olsa
2016-07-13  7:01   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
2016-07-05  6:56 ` [PATCH 3/3] perf tools: Introduce hists__add_entry_ops function Jiri Olsa
2016-07-13  7:01   ` [tip:perf/core] perf hists: " tip-bot for Jiri Olsa
2016-07-05 14:15 ` [PATCH 0/3] perf tools: Add hist_entry allocation callbacks Arnaldo Carvalho de Melo

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).