|
@@ -1475,8 +1475,7 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
|
|
|
if (event->group_leader == event) {
|
|
|
struct list_head *list;
|
|
|
|
|
|
- if (is_software_event(event))
|
|
|
- event->group_flags |= PERF_GROUP_SOFTWARE;
|
|
|
+ event->group_caps = event->event_caps;
|
|
|
|
|
|
list = ctx_group_list(event, ctx);
|
|
|
list_add_tail(&event->group_entry, list);
|
|
@@ -1630,9 +1629,7 @@ static void perf_group_attach(struct perf_event *event)
|
|
|
|
|
|
WARN_ON_ONCE(group_leader->ctx != event->ctx);
|
|
|
|
|
|
- if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
|
|
|
- !is_software_event(event))
|
|
|
- group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
|
|
|
+ group_leader->group_caps &= event->event_caps;
|
|
|
|
|
|
list_add_tail(&event->group_entry, &group_leader->sibling_list);
|
|
|
group_leader->nr_siblings++;
|
|
@@ -1723,7 +1720,7 @@ static void perf_group_detach(struct perf_event *event)
|
|
|
sibling->group_leader = sibling;
|
|
|
|
|
|
/* Inherit group flags from the previous leader */
|
|
|
- sibling->group_flags = event->group_flags;
|
|
|
+ sibling->group_caps = event->group_caps;
|
|
|
|
|
|
WARN_ON_ONCE(sibling->ctx != event->ctx);
|
|
|
}
|
|
@@ -2149,7 +2146,7 @@ static int group_can_go_on(struct perf_event *event,
|
|
|
/*
|
|
|
* Groups consisting entirely of software events can always go on.
|
|
|
*/
|
|
|
- if (event->group_flags & PERF_GROUP_SOFTWARE)
|
|
|
+ if (event->group_caps & PERF_EV_CAP_SOFTWARE)
|
|
|
return 1;
|
|
|
/*
|
|
|
* If an exclusive group is already on, no other hardware
|
|
@@ -9490,6 +9487,9 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
|
goto err_alloc;
|
|
|
}
|
|
|
|
|
|
+ if (pmu->task_ctx_nr == perf_sw_context)
|
|
|
+ event->event_caps |= PERF_EV_CAP_SOFTWARE;
|
|
|
+
|
|
|
if (group_leader &&
|
|
|
(is_software_event(event) != is_software_event(group_leader))) {
|
|
|
if (is_software_event(event)) {
|
|
@@ -9503,7 +9503,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
|
*/
|
|
|
pmu = group_leader->pmu;
|
|
|
} else if (is_software_event(group_leader) &&
|
|
|
- (group_leader->group_flags & PERF_GROUP_SOFTWARE)) {
|
|
|
+ (group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) {
|
|
|
/*
|
|
|
* In case the group is a pure software group, and we
|
|
|
* try to add a hardware event, move the whole group to
|