diff options
-rw-r--r-- | kernel/events/core.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 1d1ec6453a08..feb1329ca331 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -5419,6 +5419,9 @@ struct swevent_htable { | |||
5419 | 5419 | ||
5420 | /* Recursion avoidance in each contexts */ | 5420 | /* Recursion avoidance in each contexts */ |
5421 | int recursion[PERF_NR_CONTEXTS]; | 5421 | int recursion[PERF_NR_CONTEXTS]; |
5422 | |||
5423 | /* Keeps track of cpu being initialized/exited */ | ||
5424 | bool online; | ||
5422 | }; | 5425 | }; |
5423 | 5426 | ||
5424 | static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); | 5427 | static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); |
@@ -5665,8 +5668,14 @@ static int perf_swevent_add(struct perf_event *event, int flags) | |||
5665 | hwc->state = !(flags & PERF_EF_START); | 5668 | hwc->state = !(flags & PERF_EF_START); |
5666 | 5669 | ||
5667 | head = find_swevent_head(swhash, event); | 5670 | head = find_swevent_head(swhash, event); |
5668 | if (WARN_ON_ONCE(!head)) | 5671 | if (!head) { |
5672 | /* | ||
5673 | * We can race with cpu hotplug code. Do not | ||
5674 | * WARN if the cpu just got unplugged. | ||
5675 | */ | ||
5676 | WARN_ON_ONCE(swhash->online); | ||
5669 | return -EINVAL; | 5677 | return -EINVAL; |
5678 | } | ||
5670 | 5679 | ||
5671 | hlist_add_head_rcu(&event->hlist_entry, head); | 5680 | hlist_add_head_rcu(&event->hlist_entry, head); |
5672 | 5681 | ||
@@ -7845,6 +7854,7 @@ static void perf_event_init_cpu(int cpu) | |||
7845 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); | 7854 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
7846 | 7855 | ||
7847 | mutex_lock(&swhash->hlist_mutex); | 7856 | mutex_lock(&swhash->hlist_mutex); |
7857 | swhash->online = true; | ||
7848 | if (swhash->hlist_refcount > 0) { | 7858 | if (swhash->hlist_refcount > 0) { |
7849 | struct swevent_hlist *hlist; | 7859 | struct swevent_hlist *hlist; |
7850 | 7860 | ||
@@ -7902,6 +7912,7 @@ static void perf_event_exit_cpu(int cpu) | |||
7902 | perf_event_exit_cpu_context(cpu); | 7912 | perf_event_exit_cpu_context(cpu); |
7903 | 7913 | ||
7904 | mutex_lock(&swhash->hlist_mutex); | 7914 | mutex_lock(&swhash->hlist_mutex); |
7915 | swhash->online = false; | ||
7905 | swevent_hlist_release(swhash); | 7916 | swevent_hlist_release(swhash); |
7906 | mutex_unlock(&swhash->hlist_mutex); | 7917 | mutex_unlock(&swhash->hlist_mutex); |
7907 | } | 7918 | } |