public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Wang Nan <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: peterz@infradead.org, jeremie.galarneau@efficios.com,
	brendan.d.gregg@gmail.com, hekuang@huawei.com, acme@redhat.com,
	tglx@linutronix.de, dev@codyps.com, linux-kernel@vger.kernel.org,
	lizefan@huawei.com, jolsa@kernel.org, mingo@kernel.org,
	kirr@nexedi.com, adrian.hunter@intel.com, ast@kernel.org,
	hpa@zytor.com, namhyung@kernel.org,
	masami.hiramatsu.pt@hitachi.com, wangnan0@huawei.com
Subject: [tip:perf/core] perf bpf: Add API to set values to map entries in a bpf object
Date: Wed, 24 Feb 2016 21:39:03 -0800	[thread overview]
Message-ID: <tip-066dacbf2a32defb4de23ea4c1af9e77578b5ac2@git.kernel.org> (raw)
In-Reply-To: <1456132275-98875-4-git-send-email-wangnan0@huawei.com>

Commit-ID:  066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Gitweb:     http://git.kernel.org/tip/066dacbf2a32defb4de23ea4c1af9e77578b5ac2
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Mon, 22 Feb 2016 09:10:30 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 22 Feb 2016 12:17:48 -0300

perf bpf: Add API to set values to map entries in a bpf object

bpf__config_obj() is introduced as a core API to config BPF object after
loading. One configuration option of maps is introduced. After this
patch BPF object can accept assignments like:

  map:my_map.value=1234

(map.my_map.value looks pretty. However, there's a small but hard to fix
problem related to flex's greedy matching. Please see [1].  Choose ':'
to avoid it in a simpler way.)

This patch is more complex than the work it does because the
consideration of extension. In designing BPF map configuration, the
following things should be considered:

 1. Array indices selection: perf should allow user setting different
    value for different slots in an array, with syntax like:
    map:my_map.value[0,3...6]=1234;

 2. A map should be set by different config terms, each for a part
    of it. For example, set each slot to the pid of a thread;

 3. Type of value: integer is not the only valid value type. A perf
    counter can also be put into a map after commit 35578d798400
    ("bpf: Implement function bpf_perf_event_read() that get the
      selected hardware PMU counter")

 4. For a hash table, it should be possible to use a string or other
    value as a key;

 5. It is possible that map configuration is unable to be setup
    during parsing. A perf counter is an example.

Therefore, this patch does the following:

 1. Instead of updating map element during parsing, this patch stores
    map config options in 'struct bpf_map_priv'. Following patches
    will apply those configs at an appropriate time;

 2. Link map operations in a list so a map can have multiple config
    terms attached, so different parts can be configured separately;

 3. Make 'struct bpf_map_priv' extensible so that the following patches
    can add new types of keys and operations;

 4. Use bpf_obj_config__map_funcs array to support more map config options.

Since the patch changing the event parser to parse BPF object config is
relative large, I've put it in another commit. Code in this patch can be
tested after applying the next patch.

[1] http://lkml.kernel.org/g/564ED621.4050500@huawei.com

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Cody P Schafer <dev@codyps.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jeremie Galarneau <jeremie.galarneau@efficios.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kirill Smelkov <kirr@nexedi.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1456132275-98875-4-git-send-email-wangnan0@huawei.com
Signed-off-by: He Kuang <hekuang@huawei.com>
[ Changes "maps:my_map.value" to "map:my_map.value", improved error messages ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/bpf-loader.c | 276 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/bpf-loader.h |  38 ++++++
 2 files changed, 314 insertions(+)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 0bdccf4..caeef9e 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -739,6 +739,261 @@ int bpf__foreach_tev(struct bpf_object *obj,
 	return 0;
 }
 
+enum bpf_map_op_type {
+	BPF_MAP_OP_SET_VALUE,
+};
+
+enum bpf_map_key_type {
+	BPF_MAP_KEY_ALL,
+};
+
+struct bpf_map_op {
+	struct list_head list;
+	enum bpf_map_op_type op_type;
+	enum bpf_map_key_type key_type;
+	union {
+		u64 value;
+	} v;
+};
+
+struct bpf_map_priv {
+	struct list_head ops_list;
+};
+
+static void
+bpf_map_op__delete(struct bpf_map_op *op)
+{
+	if (!list_empty(&op->list))
+		list_del(&op->list);
+	free(op);
+}
+
+static void
+bpf_map_priv__purge(struct bpf_map_priv *priv)
+{
+	struct bpf_map_op *pos, *n;
+
+	list_for_each_entry_safe(pos, n, &priv->ops_list, list) {
+		list_del_init(&pos->list);
+		bpf_map_op__delete(pos);
+	}
+}
+
+static void
+bpf_map_priv__clear(struct bpf_map *map __maybe_unused,
+		    void *_priv)
+{
+	struct bpf_map_priv *priv = _priv;
+
+	bpf_map_priv__purge(priv);
+	free(priv);
+}
+
+static struct bpf_map_op *
+bpf_map_op__new(void)
+{
+	struct bpf_map_op *op;
+
+	op = zalloc(sizeof(*op));
+	if (!op) {
+		pr_debug("Failed to alloc bpf_map_op\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	INIT_LIST_HEAD(&op->list);
+
+	op->key_type = BPF_MAP_KEY_ALL;
+	return op;
+}
+
+static int
+bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
+{
+	struct bpf_map_priv *priv;
+	const char *map_name;
+	int err;
+
+	map_name = bpf_map__get_name(map);
+	err = bpf_map__get_private(map, (void **)&priv);
+	if (err) {
+		pr_debug("Failed to get private from map %s\n", map_name);
+		return err;
+	}
+
+	if (!priv) {
+		priv = zalloc(sizeof(*priv));
+		if (!priv) {
+			pr_debug("No enough memory to alloc map private\n");
+			return -ENOMEM;
+		}
+		INIT_LIST_HEAD(&priv->ops_list);
+
+		if (bpf_map__set_private(map, priv, bpf_map_priv__clear)) {
+			free(priv);
+			return -BPF_LOADER_ERRNO__INTERNAL;
+		}
+	}
+
+	list_add_tail(&op->list, &priv->ops_list);
+	return 0;
+}
+
+static int
+__bpf_map__config_value(struct bpf_map *map,
+			struct parse_events_term *term)
+{
+	struct bpf_map_def def;
+	struct bpf_map_op *op;
+	const char *map_name;
+	int err;
+
+	map_name = bpf_map__get_name(map);
+
+	err = bpf_map__get_def(map, &def);
+	if (err) {
+		pr_debug("Unable to get map definition from '%s'\n",
+			 map_name);
+		return -BPF_LOADER_ERRNO__INTERNAL;
+	}
+
+	if (def.type != BPF_MAP_TYPE_ARRAY) {
+		pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n",
+			 map_name);
+		return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
+	}
+	if (def.key_size < sizeof(unsigned int)) {
+		pr_debug("Map %s has incorrect key size\n", map_name);
+		return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE;
+	}
+	switch (def.value_size) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		break;
+	default:
+		pr_debug("Map %s has incorrect value size\n", map_name);
+		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE;
+	}
+
+	op = bpf_map_op__new();
+	if (IS_ERR(op))
+		return PTR_ERR(op);
+	op->op_type = BPF_MAP_OP_SET_VALUE;
+	op->v.value = term->val.num;
+
+	err = bpf_map__add_op(map, op);
+	if (err)
+		bpf_map_op__delete(op);
+	return err;
+}
+
+static int
+bpf_map__config_value(struct bpf_map *map,
+		      struct parse_events_term *term,
+		      struct perf_evlist *evlist __maybe_unused)
+{
+	if (!term->err_val) {
+		pr_debug("Config value not set\n");
+		return -BPF_LOADER_ERRNO__OBJCONF_CONF;
+	}
+
+	if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) {
+		pr_debug("ERROR: wrong value type\n");
+		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE;
+	}
+
+	return __bpf_map__config_value(map, term);
+}
+
+struct bpf_obj_config__map_func {
+	const char *config_opt;
+	int (*config_func)(struct bpf_map *, struct parse_events_term *,
+			   struct perf_evlist *);
+};
+
+struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = {
+	{"value", bpf_map__config_value},
+};
+
+static int
+bpf__obj_config_map(struct bpf_object *obj,
+		    struct parse_events_term *term,
+		    struct perf_evlist *evlist,
+		    int *key_scan_pos)
+{
+	/* key is "map:<mapname>.<config opt>" */
+	char *map_name = strdup(term->config + sizeof("map:") - 1);
+	struct bpf_map *map;
+	int err = -BPF_LOADER_ERRNO__OBJCONF_OPT;
+	char *map_opt;
+	size_t i;
+
+	if (!map_name)
+		return -ENOMEM;
+
+	map_opt = strchr(map_name, '.');
+	if (!map_opt) {
+		pr_debug("ERROR: Invalid map config: %s\n", map_name);
+		goto out;
+	}
+
+	*map_opt++ = '\0';
+	if (*map_opt == '\0') {
+		pr_debug("ERROR: Invalid map option: %s\n", term->config);
+		goto out;
+	}
+
+	map = bpf_object__get_map_by_name(obj, map_name);
+	if (!map) {
+		pr_debug("ERROR: Map %s doesn't exist\n", map_name);
+		err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST;
+		goto out;
+	}
+
+	*key_scan_pos += map_opt - map_name;
+	for (i = 0; i < ARRAY_SIZE(bpf_obj_config__map_funcs); i++) {
+		struct bpf_obj_config__map_func *func =
+				&bpf_obj_config__map_funcs[i];
+
+		if (strcmp(map_opt, func->config_opt) == 0) {
+			err = func->config_func(map, term, evlist);
+			goto out;
+		}
+	}
+
+	pr_debug("ERROR: Invalid map config option '%s'\n", map_opt);
+	err = -BPF_LOADER_ERRNO__OBJCONF_MAP_OPT;
+out:
+	free(map_name);
+	if (!err)
+		key_scan_pos += strlen(map_opt);
+	return err;
+}
+
+int bpf__config_obj(struct bpf_object *obj,
+		    struct parse_events_term *term,
+		    struct perf_evlist *evlist,
+		    int *error_pos)
+{
+	int key_scan_pos = 0;
+	int err;
+
+	if (!obj || !term || !term->config)
+		return -EINVAL;
+
+	if (!prefixcmp(term->config, "map:")) {
+		key_scan_pos = sizeof("map:") - 1;
+		err = bpf__obj_config_map(obj, term, evlist, &key_scan_pos);
+		goto out;
+	}
+	err = -BPF_LOADER_ERRNO__OBJCONF_OPT;
+out:
+	if (error_pos)
+		*error_pos = key_scan_pos;
+	return err;
+
+}
+
 #define ERRNO_OFFSET(e)		((e) - __BPF_LOADER_ERRNO__START)
 #define ERRCODE_OFFSET(c)	ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
 #define NR_ERRNO	(__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
@@ -753,6 +1008,14 @@ static const char *bpf_loader_strerror_table[NR_ERRNO] = {
 	[ERRCODE_OFFSET(PROLOGUE)]	= "Failed to generate prologue",
 	[ERRCODE_OFFSET(PROLOGUE2BIG)]	= "Prologue too big for program",
 	[ERRCODE_OFFSET(PROLOGUEOOB)]	= "Offset out of bound for prologue",
+	[ERRCODE_OFFSET(OBJCONF_OPT)]	= "Invalid object config option",
+	[ERRCODE_OFFSET(OBJCONF_CONF)]	= "Config value not set (missing '=')",
+	[ERRCODE_OFFSET(OBJCONF_MAP_OPT)]	= "Invalid object map config option",
+	[ERRCODE_OFFSET(OBJCONF_MAP_NOTEXIST)]	= "Target map doesn't exist",
+	[ERRCODE_OFFSET(OBJCONF_MAP_VALUE)]	= "Incorrect value type for map",
+	[ERRCODE_OFFSET(OBJCONF_MAP_TYPE)]	= "Incorrect map type",
+	[ERRCODE_OFFSET(OBJCONF_MAP_KEYSIZE)]	= "Incorrect map key size",
+	[ERRCODE_OFFSET(OBJCONF_MAP_VALUESIZE)]	= "Incorrect map value size",
 };
 
 static int
@@ -872,3 +1135,16 @@ int bpf__strerror_load(struct bpf_object *obj,
 	bpf__strerror_end(buf, size);
 	return 0;
 }
+
+int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused,
+			     struct parse_events_term *term __maybe_unused,
+			     struct perf_evlist *evlist __maybe_unused,
+			     int *error_pos __maybe_unused, int err,
+			     char *buf, size_t size)
+{
+	bpf__strerror_head(err, buf, size);
+	bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE,
+			    "Can't use this config term with this map type");
+	bpf__strerror_end(buf, size);
+	return 0;
+}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 6fdc045..cc46a07 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -10,6 +10,7 @@
 #include <string.h>
 #include <bpf/libbpf.h>
 #include "probe-event.h"
+#include "evlist.h"
 #include "debug.h"
 
 enum bpf_loader_errno {
@@ -24,10 +25,19 @@ enum bpf_loader_errno {
 	BPF_LOADER_ERRNO__PROLOGUE,	/* Failed to generate prologue */
 	BPF_LOADER_ERRNO__PROLOGUE2BIG,	/* Prologue too big for program */
 	BPF_LOADER_ERRNO__PROLOGUEOOB,	/* Offset out of bound for prologue */
+	BPF_LOADER_ERRNO__OBJCONF_OPT,	/* Invalid object config option */
+	BPF_LOADER_ERRNO__OBJCONF_CONF,	/* Config value not set (lost '=')) */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_OPT,	/* Invalid object map config option */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST,	/* Target map not exist */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE,	/* Incorrect value type for map */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE,	/* Incorrect map type */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE,	/* Incorrect map key size */
+	BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE,/* Incorrect map value size */
 	__BPF_LOADER_ERRNO__END,
 };
 
 struct bpf_object;
+struct parse_events_term;
 #define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
 
 typedef int (*bpf_prog_iter_callback_t)(struct probe_trace_event *tev,
@@ -53,6 +63,14 @@ int bpf__strerror_load(struct bpf_object *obj, int err,
 		       char *buf, size_t size);
 int bpf__foreach_tev(struct bpf_object *obj,
 		     bpf_prog_iter_callback_t func, void *arg);
+
+int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term,
+		    struct perf_evlist *evlist, int *error_pos);
+int bpf__strerror_config_obj(struct bpf_object *obj,
+			     struct parse_events_term *term,
+			     struct perf_evlist *evlist,
+			     int *error_pos, int err, char *buf,
+			     size_t size);
 #else
 static inline struct bpf_object *
 bpf__prepare_load(const char *filename __maybe_unused,
@@ -84,6 +102,15 @@ bpf__foreach_tev(struct bpf_object *obj __maybe_unused,
 }
 
 static inline int
+bpf__config_obj(struct bpf_object *obj __maybe_unused,
+		struct parse_events_term *term __maybe_unused,
+		struct perf_evlist *evlist __maybe_unused,
+		int *error_pos __maybe_unused)
+{
+	return 0;
+}
+
+static inline int
 __bpf_strerror(char *buf, size_t size)
 {
 	if (!size)
@@ -118,5 +145,16 @@ static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
 {
 	return __bpf_strerror(buf, size);
 }
+
+static inline int
+bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused,
+			 struct parse_events_term *term __maybe_unused,
+			 struct perf_evlist *evlist __maybe_unused,
+			 int *error_pos __maybe_unused,
+			 int err __maybe_unused,
+			 char *buf, size_t size)
+{
+	return __bpf_strerror(buf, size);
+}
 #endif
 #endif

  reply	other threads:[~2016-02-25  6:27 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-22  9:10 [PATCH 00/48] perf tools: Bugfix, BPF improvements and overwrite ring buffer support Wang Nan
2016-02-22  9:10 ` [PATCH 01/48] perf tools: Record text offset in dso to calculate objdump address Wang Nan
2016-02-22  9:10 ` [PATCH 02/48] perf tools: Adjust symbol for shared objects Wang Nan
2016-02-22  9:10 ` [PATCH 03/48] perf bpf: Add API to set values to map entries in a bpf object Wang Nan
2016-02-25  5:39   ` tip-bot for Wang Nan [this message]
2016-02-22  9:10 ` [PATCH 04/48] perf tools: Enable BPF object configure syntax Wang Nan
2016-02-25  5:39   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 05/48] perf record: Apply config to BPF objects before recording Wang Nan
2016-02-25  5:39   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 06/48] perf tools: Enable passing event to BPF object Wang Nan
2016-02-25  5:40   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 07/48] perf tools: Support setting different slots in a BPF map separately Wang Nan
2016-02-25  5:40   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 08/48] perf tools: Enable indices setting syntax for BPF map Wang Nan
2016-02-25  5:40   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 09/48] perf tools: Pass tracepoint options to BPF script Wang Nan
2016-02-25  5:41   ` [tip:perf/core] perf tools: Apply tracepoint event definition " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 10/48] perf tools: Introduce bpf-output event Wang Nan
2016-02-23 17:45   ` Arnaldo Carvalho de Melo
2016-02-24  1:58     ` Wangnan (F)
2016-02-24  2:04       ` Wangnan (F)
2016-02-24  4:03         ` Wangnan (F)
2016-02-24  5:03           ` Wangnan (F)
2016-02-24 13:36       ` Arnaldo Carvalho de Melo
2016-02-25  5:41   ` [tip:perf/core] " tip-bot for Wang Nan
2016-02-22  9:10 ` [PATCH 11/48] perf data: Support converting data from bpf_perf_event_output() Wang Nan
2016-02-23 16:14   ` Arnaldo Carvalho de Melo
2016-02-23 17:23   ` Jiri Olsa
2016-02-23 17:24     ` Jiri Olsa
2016-02-23 19:22   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 12/48] perf data: Explicitly set byte order for integer types Wang Nan
2016-02-22  9:10 ` [PATCH 13/48] perf core: Introduce new ioctl options to pause and resume ring buffer Wang Nan
2016-02-22  9:10 ` [PATCH 14/48] perf core: Set event's default overflow_handler Wang Nan
2016-02-22  9:10 ` [PATCH 15/48] perf core: Prepare writing into ring buffer from end Wang Nan
2016-02-22  9:10 ` [PATCH 16/48] perf core: Add backward attribute to perf event Wang Nan
2016-02-24 13:08   ` Jiri Olsa
2016-02-24 13:21     ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 17/48] perf core: Reduce perf event output overhead by new overflow handler Wang Nan
2016-02-22  9:10 ` [PATCH 18/48] perf tools: Only validate is_pos for tracking evsels Wang Nan
2016-02-24 14:21   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 19/48] perf tools: Print write_backward value in perf_event_attr__fprintf Wang Nan
2016-02-22  9:10 ` [PATCH 20/48] perf tools: Make ordered_events reusable Wang Nan
2016-02-24 14:18   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 21/48] perf record: Extract synthesize code to record__synthesize() Wang Nan
2016-02-24 14:29   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 22/48] perf tools: Add perf_data_file__switch() helper Wang Nan
2016-02-24 14:34   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 23/48] perf record: Turns auxtrace_snapshot_enable into 3 states Wang Nan
2016-02-24 14:43   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 24/48] perf record: Introduce record__finish_output() to finish a perf.data Wang Nan
2016-02-22  9:10 ` [PATCH 25/48] perf record: Add '--timestamp-filename' option to append timestamp to output filename Wang Nan
2016-02-22  9:10 ` [PATCH 26/48] perf record: Split output into multiple files via '--switch-output' Wang Nan
2016-02-22  9:10 ` [PATCH 27/48] perf record: Force enable --timestamp-filename when --switch-output is provided Wang Nan
2016-02-22  9:10 ` [PATCH 28/48] perf record: Disable buildid cache options by default in switch output mode Wang Nan
2016-02-22  9:10 ` [PATCH 29/48] perf record: Re-synthesize tracking events after output switching Wang Nan
2016-02-24 14:57   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 30/48] perf record: Generate tracking events for process forked by perf Wang Nan
2016-02-24 15:01   ` Jiri Olsa
2016-02-22  9:10 ` [PATCH 31/48] perf record: Ensure return non-zero rc when mmap fail Wang Nan
2016-02-22  9:10 ` [PATCH 32/48] perf record: Prevent reading invalid data in record__mmap_read Wang Nan
2016-02-22  9:11 ` [PATCH 33/48] perf tools: Add evlist channel helpers Wang Nan
2016-02-22  9:11 ` [PATCH 34/48] perf tools: Automatically add new channel according to evlist Wang Nan
2016-02-22  9:11 ` [PATCH 35/48] perf tools: Operate multiple channels Wang Nan
2016-02-22  9:11 ` [PATCH 36/48] perf tools: Squash overwrite setting into channel Wang Nan
2016-02-22  9:11 ` [PATCH 37/48] perf record: Don't read from and poll overwrite channel Wang Nan
2016-02-22  9:11 ` [PATCH 38/48] perf record: Don't poll on " Wang Nan
2016-02-22  9:11 ` [PATCH 39/48] perf tools: Detect avalibility of write_backward Wang Nan
2016-02-22  9:11 ` [PATCH 40/48] perf tools: Enable overwrite settings Wang Nan
2016-02-22  9:11 ` [PATCH 41/48] perf tools: Set write_backward attribut bit for overwrite events Wang Nan
2016-02-22  9:11 ` [PATCH 42/48] perf tools: Record fd into perf_mmap Wang Nan
2016-02-22  9:11 ` [PATCH 43/48] perf tools: Add API to pause a channel Wang Nan
2016-02-22  9:11 ` [PATCH 44/48] perf record: Toggle overwrite ring buffer for reading Wang Nan
2016-02-22  9:11 ` [PATCH 45/48] perf record: Rename variable to make code clear Wang Nan
2016-02-22  9:11 ` [PATCH 46/48] perf record: Read from backward ring buffer Wang Nan
2016-02-22  9:11 ` [PATCH 47/48] perf record: Allow generate tracking events at the end of output Wang Nan
2016-02-22  9:11 ` [PATCH 48/48] perf tools: Don't warn about out of order event if write_backward is used Wang Nan

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=tip-066dacbf2a32defb4de23ea4c1af9e77578b5ac2@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=ast@kernel.org \
    --cc=brendan.d.gregg@gmail.com \
    --cc=dev@codyps.com \
    --cc=hekuang@huawei.com \
    --cc=hpa@zytor.com \
    --cc=jeremie.galarneau@efficios.com \
    --cc=jolsa@kernel.org \
    --cc=kirr@nexedi.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=wangnan0@huawei.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