diff options
author | Namhyung Kim <namhyung@kernel.org> | 2016-03-07 14:44:43 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-03-08 04:11:18 -0500 |
commit | 4b633eba14627bcb1ef5c7a498e7dc308cd6a5d6 (patch) | |
tree | 7463ff9328454b2f37dc91cf68417bb43286dc89 | |
parent | a23f96ee4d51ebd50b83ce0dbb5d04898fb8e3cb (diff) |
perf hists: Add level field to struct perf_hpp_fmt
The level field is to distinguish levels in the hierarchy mode.
Currently each column (perf_hpp_fmt) has a different level.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1457103582-28396-2-git-send-email-namhyung@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/perf/util/hist.h | 1 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 74 |
2 files changed, 42 insertions, 33 deletions
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index da5e50586bfd..f4ef513527ba 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -233,6 +233,7 @@ struct perf_hpp_fmt { | |||
233 | int len; | 233 | int len; |
234 | int user_len; | 234 | int user_len; |
235 | int idx; | 235 | int idx; |
236 | int level; | ||
236 | }; | 237 | }; |
237 | 238 | ||
238 | struct perf_hpp_list { | 239 | struct perf_hpp_list { |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 4380a2858802..ab6eb7ca8c60 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -1544,7 +1544,7 @@ static void hse_free(struct perf_hpp_fmt *fmt) | |||
1544 | } | 1544 | } |
1545 | 1545 | ||
1546 | static struct hpp_sort_entry * | 1546 | static struct hpp_sort_entry * |
1547 | __sort_dimension__alloc_hpp(struct sort_dimension *sd) | 1547 | __sort_dimension__alloc_hpp(struct sort_dimension *sd, int level) |
1548 | { | 1548 | { |
1549 | struct hpp_sort_entry *hse; | 1549 | struct hpp_sort_entry *hse; |
1550 | 1550 | ||
@@ -1572,6 +1572,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) | |||
1572 | hse->hpp.elide = false; | 1572 | hse->hpp.elide = false; |
1573 | hse->hpp.len = 0; | 1573 | hse->hpp.len = 0; |
1574 | hse->hpp.user_len = 0; | 1574 | hse->hpp.user_len = 0; |
1575 | hse->hpp.level = level; | ||
1575 | 1576 | ||
1576 | return hse; | 1577 | return hse; |
1577 | } | 1578 | } |
@@ -1581,7 +1582,8 @@ static void hpp_free(struct perf_hpp_fmt *fmt) | |||
1581 | free(fmt); | 1582 | free(fmt); |
1582 | } | 1583 | } |
1583 | 1584 | ||
1584 | static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd) | 1585 | static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd, |
1586 | int level) | ||
1585 | { | 1587 | { |
1586 | struct perf_hpp_fmt *fmt; | 1588 | struct perf_hpp_fmt *fmt; |
1587 | 1589 | ||
@@ -1590,6 +1592,7 @@ static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd) | |||
1590 | INIT_LIST_HEAD(&fmt->list); | 1592 | INIT_LIST_HEAD(&fmt->list); |
1591 | INIT_LIST_HEAD(&fmt->sort_list); | 1593 | INIT_LIST_HEAD(&fmt->sort_list); |
1592 | fmt->free = hpp_free; | 1594 | fmt->free = hpp_free; |
1595 | fmt->level = level; | ||
1593 | } | 1596 | } |
1594 | 1597 | ||
1595 | return fmt; | 1598 | return fmt; |
@@ -1611,9 +1614,9 @@ int hist_entry__filter(struct hist_entry *he, int type, const void *arg) | |||
1611 | return hse->se->se_filter(he, type, arg); | 1614 | return hse->se->se_filter(he, type, arg); |
1612 | } | 1615 | } |
1613 | 1616 | ||
1614 | static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd) | 1617 | static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd, int level) |
1615 | { | 1618 | { |
1616 | struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd); | 1619 | struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, level); |
1617 | 1620 | ||
1618 | if (hse == NULL) | 1621 | if (hse == NULL) |
1619 | return -1; | 1622 | return -1; |
@@ -1625,7 +1628,7 @@ static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd) | |||
1625 | static int __sort_dimension__add_hpp_output(struct perf_hpp_list *list, | 1628 | static int __sort_dimension__add_hpp_output(struct perf_hpp_list *list, |
1626 | struct sort_dimension *sd) | 1629 | struct sort_dimension *sd) |
1627 | { | 1630 | { |
1628 | struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd); | 1631 | struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, 0); |
1629 | 1632 | ||
1630 | if (hse == NULL) | 1633 | if (hse == NULL) |
1631 | return -1; | 1634 | return -1; |
@@ -1868,7 +1871,8 @@ static void hde_free(struct perf_hpp_fmt *fmt) | |||
1868 | } | 1871 | } |
1869 | 1872 | ||
1870 | static struct hpp_dynamic_entry * | 1873 | static struct hpp_dynamic_entry * |
1871 | __alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field) | 1874 | __alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field, |
1875 | int level) | ||
1872 | { | 1876 | { |
1873 | struct hpp_dynamic_entry *hde; | 1877 | struct hpp_dynamic_entry *hde; |
1874 | 1878 | ||
@@ -1899,6 +1903,7 @@ __alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field) | |||
1899 | hde->hpp.elide = false; | 1903 | hde->hpp.elide = false; |
1900 | hde->hpp.len = 0; | 1904 | hde->hpp.len = 0; |
1901 | hde->hpp.user_len = 0; | 1905 | hde->hpp.user_len = 0; |
1906 | hde->hpp.level = level; | ||
1902 | 1907 | ||
1903 | return hde; | 1908 | return hde; |
1904 | } | 1909 | } |
@@ -1974,11 +1979,11 @@ static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_nam | |||
1974 | 1979 | ||
1975 | static int __dynamic_dimension__add(struct perf_evsel *evsel, | 1980 | static int __dynamic_dimension__add(struct perf_evsel *evsel, |
1976 | struct format_field *field, | 1981 | struct format_field *field, |
1977 | bool raw_trace) | 1982 | bool raw_trace, int level) |
1978 | { | 1983 | { |
1979 | struct hpp_dynamic_entry *hde; | 1984 | struct hpp_dynamic_entry *hde; |
1980 | 1985 | ||
1981 | hde = __alloc_dynamic_entry(evsel, field); | 1986 | hde = __alloc_dynamic_entry(evsel, field, level); |
1982 | if (hde == NULL) | 1987 | if (hde == NULL) |
1983 | return -ENOMEM; | 1988 | return -ENOMEM; |
1984 | 1989 | ||
@@ -1988,14 +1993,14 @@ static int __dynamic_dimension__add(struct perf_evsel *evsel, | |||
1988 | return 0; | 1993 | return 0; |
1989 | } | 1994 | } |
1990 | 1995 | ||
1991 | static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace) | 1996 | static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace, int level) |
1992 | { | 1997 | { |
1993 | int ret; | 1998 | int ret; |
1994 | struct format_field *field; | 1999 | struct format_field *field; |
1995 | 2000 | ||
1996 | field = evsel->tp_format->format.fields; | 2001 | field = evsel->tp_format->format.fields; |
1997 | while (field) { | 2002 | while (field) { |
1998 | ret = __dynamic_dimension__add(evsel, field, raw_trace); | 2003 | ret = __dynamic_dimension__add(evsel, field, raw_trace, level); |
1999 | if (ret < 0) | 2004 | if (ret < 0) |
2000 | return ret; | 2005 | return ret; |
2001 | 2006 | ||
@@ -2004,7 +2009,8 @@ static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace) | |||
2004 | return 0; | 2009 | return 0; |
2005 | } | 2010 | } |
2006 | 2011 | ||
2007 | static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace) | 2012 | static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace, |
2013 | int level) | ||
2008 | { | 2014 | { |
2009 | int ret; | 2015 | int ret; |
2010 | struct perf_evsel *evsel; | 2016 | struct perf_evsel *evsel; |
@@ -2013,7 +2019,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace) | |||
2013 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) | 2019 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) |
2014 | continue; | 2020 | continue; |
2015 | 2021 | ||
2016 | ret = add_evsel_fields(evsel, raw_trace); | 2022 | ret = add_evsel_fields(evsel, raw_trace, level); |
2017 | if (ret < 0) | 2023 | if (ret < 0) |
2018 | return ret; | 2024 | return ret; |
2019 | } | 2025 | } |
@@ -2021,7 +2027,7 @@ static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace) | |||
2021 | } | 2027 | } |
2022 | 2028 | ||
2023 | static int add_all_matching_fields(struct perf_evlist *evlist, | 2029 | static int add_all_matching_fields(struct perf_evlist *evlist, |
2024 | char *field_name, bool raw_trace) | 2030 | char *field_name, bool raw_trace, int level) |
2025 | { | 2031 | { |
2026 | int ret = -ESRCH; | 2032 | int ret = -ESRCH; |
2027 | struct perf_evsel *evsel; | 2033 | struct perf_evsel *evsel; |
@@ -2035,14 +2041,15 @@ static int add_all_matching_fields(struct perf_evlist *evlist, | |||
2035 | if (field == NULL) | 2041 | if (field == NULL) |
2036 | continue; | 2042 | continue; |
2037 | 2043 | ||
2038 | ret = __dynamic_dimension__add(evsel, field, raw_trace); | 2044 | ret = __dynamic_dimension__add(evsel, field, raw_trace, level); |
2039 | if (ret < 0) | 2045 | if (ret < 0) |
2040 | break; | 2046 | break; |
2041 | } | 2047 | } |
2042 | return ret; | 2048 | return ret; |
2043 | } | 2049 | } |
2044 | 2050 | ||
2045 | static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok) | 2051 | static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok, |
2052 | int level) | ||
2046 | { | 2053 | { |
2047 | char *str, *event_name, *field_name, *opt_name; | 2054 | char *str, *event_name, *field_name, *opt_name; |
2048 | struct perf_evsel *evsel; | 2055 | struct perf_evsel *evsel; |
@@ -2072,12 +2079,12 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok) | |||
2072 | } | 2079 | } |
2073 | 2080 | ||
2074 | if (!strcmp(field_name, "trace_fields")) { | 2081 | if (!strcmp(field_name, "trace_fields")) { |
2075 | ret = add_all_dynamic_fields(evlist, raw_trace); | 2082 | ret = add_all_dynamic_fields(evlist, raw_trace, level); |
2076 | goto out; | 2083 | goto out; |
2077 | } | 2084 | } |
2078 | 2085 | ||
2079 | if (event_name == NULL) { | 2086 | if (event_name == NULL) { |
2080 | ret = add_all_matching_fields(evlist, field_name, raw_trace); | 2087 | ret = add_all_matching_fields(evlist, field_name, raw_trace, level); |
2081 | goto out; | 2088 | goto out; |
2082 | } | 2089 | } |
2083 | 2090 | ||
@@ -2095,7 +2102,7 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok) | |||
2095 | } | 2102 | } |
2096 | 2103 | ||
2097 | if (!strcmp(field_name, "*")) { | 2104 | if (!strcmp(field_name, "*")) { |
2098 | ret = add_evsel_fields(evsel, raw_trace); | 2105 | ret = add_evsel_fields(evsel, raw_trace, level); |
2099 | } else { | 2106 | } else { |
2100 | field = pevent_find_any_field(evsel->tp_format, field_name); | 2107 | field = pevent_find_any_field(evsel->tp_format, field_name); |
2101 | if (field == NULL) { | 2108 | if (field == NULL) { |
@@ -2104,7 +2111,7 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok) | |||
2104 | return -ENOENT; | 2111 | return -ENOENT; |
2105 | } | 2112 | } |
2106 | 2113 | ||
2107 | ret = __dynamic_dimension__add(evsel, field, raw_trace); | 2114 | ret = __dynamic_dimension__add(evsel, field, raw_trace, level); |
2108 | } | 2115 | } |
2109 | 2116 | ||
2110 | out: | 2117 | out: |
@@ -2112,12 +2119,12 @@ out: | |||
2112 | return ret; | 2119 | return ret; |
2113 | } | 2120 | } |
2114 | 2121 | ||
2115 | static int __sort_dimension__add(struct sort_dimension *sd) | 2122 | static int __sort_dimension__add(struct sort_dimension *sd, int level) |
2116 | { | 2123 | { |
2117 | if (sd->taken) | 2124 | if (sd->taken) |
2118 | return 0; | 2125 | return 0; |
2119 | 2126 | ||
2120 | if (__sort_dimension__add_hpp_sort(sd) < 0) | 2127 | if (__sort_dimension__add_hpp_sort(sd, level) < 0) |
2121 | return -1; | 2128 | return -1; |
2122 | 2129 | ||
2123 | if (sd->entry->se_collapse) | 2130 | if (sd->entry->se_collapse) |
@@ -2128,14 +2135,14 @@ static int __sort_dimension__add(struct sort_dimension *sd) | |||
2128 | return 0; | 2135 | return 0; |
2129 | } | 2136 | } |
2130 | 2137 | ||
2131 | static int __hpp_dimension__add(struct hpp_dimension *hd) | 2138 | static int __hpp_dimension__add(struct hpp_dimension *hd, int level) |
2132 | { | 2139 | { |
2133 | struct perf_hpp_fmt *fmt; | 2140 | struct perf_hpp_fmt *fmt; |
2134 | 2141 | ||
2135 | if (hd->taken) | 2142 | if (hd->taken) |
2136 | return 0; | 2143 | return 0; |
2137 | 2144 | ||
2138 | fmt = __hpp_dimension__alloc_hpp(hd); | 2145 | fmt = __hpp_dimension__alloc_hpp(hd, level); |
2139 | if (!fmt) | 2146 | if (!fmt) |
2140 | return -1; | 2147 | return -1; |
2141 | 2148 | ||
@@ -2165,7 +2172,7 @@ static int __hpp_dimension__add_output(struct perf_hpp_list *list, | |||
2165 | if (hd->taken) | 2172 | if (hd->taken) |
2166 | return 0; | 2173 | return 0; |
2167 | 2174 | ||
2168 | fmt = __hpp_dimension__alloc_hpp(hd); | 2175 | fmt = __hpp_dimension__alloc_hpp(hd, 0); |
2169 | if (!fmt) | 2176 | if (!fmt) |
2170 | return -1; | 2177 | return -1; |
2171 | 2178 | ||
@@ -2180,8 +2187,8 @@ int hpp_dimension__add_output(unsigned col) | |||
2180 | return __hpp_dimension__add_output(&perf_hpp_list, &hpp_sort_dimensions[col]); | 2187 | return __hpp_dimension__add_output(&perf_hpp_list, &hpp_sort_dimensions[col]); |
2181 | } | 2188 | } |
2182 | 2189 | ||
2183 | static int sort_dimension__add(const char *tok, | 2190 | static int sort_dimension__add(const char *tok, struct perf_evlist *evlist, |
2184 | struct perf_evlist *evlist __maybe_unused) | 2191 | int level) |
2185 | { | 2192 | { |
2186 | unsigned int i; | 2193 | unsigned int i; |
2187 | 2194 | ||
@@ -2220,7 +2227,7 @@ static int sort_dimension__add(const char *tok, | |||
2220 | sort__has_thread = 1; | 2227 | sort__has_thread = 1; |
2221 | } | 2228 | } |
2222 | 2229 | ||
2223 | return __sort_dimension__add(sd); | 2230 | return __sort_dimension__add(sd, level); |
2224 | } | 2231 | } |
2225 | 2232 | ||
2226 | for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) { | 2233 | for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) { |
@@ -2229,7 +2236,7 @@ static int sort_dimension__add(const char *tok, | |||
2229 | if (strncasecmp(tok, hd->name, strlen(tok))) | 2236 | if (strncasecmp(tok, hd->name, strlen(tok))) |
2230 | continue; | 2237 | continue; |
2231 | 2238 | ||
2232 | return __hpp_dimension__add(hd); | 2239 | return __hpp_dimension__add(hd, level); |
2233 | } | 2240 | } |
2234 | 2241 | ||
2235 | for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { | 2242 | for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { |
@@ -2244,7 +2251,7 @@ static int sort_dimension__add(const char *tok, | |||
2244 | if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) | 2251 | if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) |
2245 | sort__has_sym = 1; | 2252 | sort__has_sym = 1; |
2246 | 2253 | ||
2247 | __sort_dimension__add(sd); | 2254 | __sort_dimension__add(sd, level); |
2248 | return 0; | 2255 | return 0; |
2249 | } | 2256 | } |
2250 | 2257 | ||
@@ -2260,11 +2267,11 @@ static int sort_dimension__add(const char *tok, | |||
2260 | if (sd->entry == &sort_mem_daddr_sym) | 2267 | if (sd->entry == &sort_mem_daddr_sym) |
2261 | sort__has_sym = 1; | 2268 | sort__has_sym = 1; |
2262 | 2269 | ||
2263 | __sort_dimension__add(sd); | 2270 | __sort_dimension__add(sd, level); |
2264 | return 0; | 2271 | return 0; |
2265 | } | 2272 | } |
2266 | 2273 | ||
2267 | if (!add_dynamic_entry(evlist, tok)) | 2274 | if (!add_dynamic_entry(evlist, tok, level)) |
2268 | return 0; | 2275 | return 0; |
2269 | 2276 | ||
2270 | return -ESRCH; | 2277 | return -ESRCH; |
@@ -2274,10 +2281,11 @@ static int setup_sort_list(char *str, struct perf_evlist *evlist) | |||
2274 | { | 2281 | { |
2275 | char *tmp, *tok; | 2282 | char *tmp, *tok; |
2276 | int ret = 0; | 2283 | int ret = 0; |
2284 | int level = 0; | ||
2277 | 2285 | ||
2278 | for (tok = strtok_r(str, ", ", &tmp); | 2286 | for (tok = strtok_r(str, ", ", &tmp); |
2279 | tok; tok = strtok_r(NULL, ", ", &tmp)) { | 2287 | tok; tok = strtok_r(NULL, ", ", &tmp)) { |
2280 | ret = sort_dimension__add(tok, evlist); | 2288 | ret = sort_dimension__add(tok, evlist, level++); |
2281 | if (ret == -EINVAL) { | 2289 | if (ret == -EINVAL) { |
2282 | error("Invalid --sort key: `%s'", tok); | 2290 | error("Invalid --sort key: `%s'", tok); |
2283 | break; | 2291 | break; |
@@ -2667,7 +2675,7 @@ int setup_sorting(struct perf_evlist *evlist) | |||
2667 | return err; | 2675 | return err; |
2668 | 2676 | ||
2669 | if (parent_pattern != default_parent_pattern) { | 2677 | if (parent_pattern != default_parent_pattern) { |
2670 | err = sort_dimension__add("parent", evlist); | 2678 | err = sort_dimension__add("parent", evlist, -1); |
2671 | if (err < 0) | 2679 | if (err < 0) |
2672 | return err; | 2680 | return err; |
2673 | } | 2681 | } |