Skip to content

Commit 47ef839

Browse files
Jin Yaoacmel
authored andcommitted
perf streams: Compare two streams
Stream is the branch history which is aggregated by the branch records from perf samples. Now we support the callchain as stream. If the callchain entries of one stream are fully matched with the callchain entries of another stream, we think two streams are matched. For example, cycles: 1, hits: 26.80% cycles: 1, hits: 27.30% ----------------------- ----------------------- main div.c:39 main div.c:39 main div.c:44 main div.c:44 Above two streams are matched (we don't consider the case that source code is changed). The matching logic is, compare the chain string first. If it's not matched, fallback to dso address comparison. Signed-off-by: Jin Yao <yao.jin@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20201009022845.13141-4-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent dd1d841 commit 47ef839

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

tools/perf/util/callchain.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,3 +1613,57 @@ void callchain_param_setup(u64 sample_type)
16131613
callchain_param.record_mode = CALLCHAIN_FP;
16141614
}
16151615
}
1616+
1617+
static bool chain_match(struct callchain_list *base_chain,
1618+
struct callchain_list *pair_chain)
1619+
{
1620+
enum match_result match;
1621+
1622+
match = match_chain_strings(base_chain->srcline,
1623+
pair_chain->srcline);
1624+
if (match != MATCH_ERROR)
1625+
return match == MATCH_EQ;
1626+
1627+
match = match_chain_dso_addresses(base_chain->ms.map,
1628+
base_chain->ip,
1629+
pair_chain->ms.map,
1630+
pair_chain->ip);
1631+
1632+
return match == MATCH_EQ;
1633+
}
1634+
1635+
bool callchain_cnode_matched(struct callchain_node *base_cnode,
1636+
struct callchain_node *pair_cnode)
1637+
{
1638+
struct callchain_list *base_chain, *pair_chain;
1639+
bool match = false;
1640+
1641+
pair_chain = list_first_entry(&pair_cnode->val,
1642+
struct callchain_list,
1643+
list);
1644+
1645+
list_for_each_entry(base_chain, &base_cnode->val, list) {
1646+
if (&pair_chain->list == &pair_cnode->val)
1647+
return false;
1648+
1649+
if (!base_chain->srcline || !pair_chain->srcline) {
1650+
pair_chain = list_next_entry(pair_chain, list);
1651+
continue;
1652+
}
1653+
1654+
match = chain_match(base_chain, pair_chain);
1655+
if (!match)
1656+
return false;
1657+
1658+
pair_chain = list_next_entry(pair_chain, list);
1659+
}
1660+
1661+
/*
1662+
* Say chain1 is ABC, chain2 is ABCD, we consider they are
1663+
* not fully matched.
1664+
*/
1665+
if (pair_chain && (&pair_chain->list != &pair_cnode->val))
1666+
return false;
1667+
1668+
return match;
1669+
}

tools/perf/util/callchain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,8 @@ int callchain_branch_counts(struct callchain_root *root,
298298
u64 *abort_count, u64 *cycles_count);
299299

300300
void callchain_param_setup(u64 sample_type);
301+
302+
bool callchain_cnode_matched(struct callchain_node *base_cnode,
303+
struct callchain_node *pair_cnode);
304+
301305
#endif /* __PERF_CALLCHAIN_H */

0 commit comments

Comments
 (0)