All of lore.kernel.org
 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 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.