aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/perf_event.h
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2010-04-05 09:35:57 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2010-04-14 12:20:33 -0400
commit76e1d9047e4edefb8ada20aa90d5762306082bd6 (patch)
tree60384bd206878d2c440e07b33d97b1bb00a103dc /include/linux/perf_event.h
parentc05556421742eb47f80301767653a4bcb19de9de (diff)
perf: Store active software events in a hashlist
Each time a software event triggers, we need to walk through the entire list of events from the current cpu and task contexts to retrieve a running perf event that matches. We also need to check a matching perf event is actually counting. This walk is wasteful and makes the event fast path scaling down with a growing number of events running on the same contexts. To solve this, we store the running perf events in a hashlist to get an immediate access to them against their type:event_id when they trigger. v2: - Fix SWEVENT_HLIST_SIZE definition (and re-learn some basic maths along the way) - Only allocate hlist for online cpus, but keep track of the refcount on offline possible cpus too, so that we allocate it if needed when it becomes online. - Drop the kref use as it's not adapted to our tricks anymore. v3: - Fix bad refcount check (address instead of value). Thanks to Eric Dumazet who spotted this. - While exiting cpu, move the hlist release out of the IPI path to lock the hlist mutex sanely. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/perf_event.h')
-rw-r--r--include/linux/perf_event.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 6e96cc8225d4..bf896d0b2e9c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -589,6 +589,14 @@ enum perf_group_flag {
589 PERF_GROUP_SOFTWARE = 0x1, 589 PERF_GROUP_SOFTWARE = 0x1,
590}; 590};
591 591
592#define SWEVENT_HLIST_BITS 8
593#define SWEVENT_HLIST_SIZE (1 << SWEVENT_HLIST_BITS)
594
595struct swevent_hlist {
596 struct hlist_head heads[SWEVENT_HLIST_SIZE];
597 struct rcu_head rcu_head;
598};
599
592/** 600/**
593 * struct perf_event - performance event kernel representation: 601 * struct perf_event - performance event kernel representation:
594 */ 602 */
@@ -597,6 +605,7 @@ struct perf_event {
597 struct list_head group_entry; 605 struct list_head group_entry;
598 struct list_head event_entry; 606 struct list_head event_entry;
599 struct list_head sibling_list; 607 struct list_head sibling_list;
608 struct hlist_node hlist_entry;
600 int nr_siblings; 609 int nr_siblings;
601 int group_flags; 610 int group_flags;
602 struct perf_event *group_leader; 611 struct perf_event *group_leader;
@@ -744,6 +753,9 @@ struct perf_cpu_context {
744 int active_oncpu; 753 int active_oncpu;
745 int max_pertask; 754 int max_pertask;
746 int exclusive; 755 int exclusive;
756 struct swevent_hlist *swevent_hlist;
757 struct mutex hlist_mutex;
758 int hlist_refcount;
747 759
748 /* 760 /*
749 * Recursion avoidance: 761 * Recursion avoidance: