aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index bbebe2832639..eae6ff693604 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -315,9 +315,16 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
315 if (group_leader == event) { 315 if (group_leader == event) {
316 struct list_head *list; 316 struct list_head *list;
317 317
318 if (is_software_event(event))
319 event->group_flags |= PERF_GROUP_SOFTWARE;
320
318 list = ctx_group_list(event, ctx); 321 list = ctx_group_list(event, ctx);
319 list_add_tail(&event->group_entry, list); 322 list_add_tail(&event->group_entry, list);
320 } else { 323 } else {
324 if (group_leader->group_flags & PERF_GROUP_SOFTWARE &&
325 !is_software_event(event))
326 group_leader->group_flags &= ~PERF_GROUP_SOFTWARE;
327
321 list_add_tail(&event->group_entry, &group_leader->sibling_list); 328 list_add_tail(&event->group_entry, &group_leader->sibling_list);
322 group_leader->nr_siblings++; 329 group_leader->nr_siblings++;
323 } 330 }
@@ -372,6 +379,9 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
372 list = ctx_group_list(event, ctx); 379 list = ctx_group_list(event, ctx);
373 list_move_tail(&sibling->group_entry, list); 380 list_move_tail(&sibling->group_entry, list);
374 sibling->group_leader = sibling; 381 sibling->group_leader = sibling;
382
383 /* Inherit group flags from the previous leader */
384 sibling->group_flags = event->group_flags;
375 } 385 }
376} 386}
377 387
@@ -700,24 +710,6 @@ group_error:
700} 710}
701 711
702/* 712/*
703 * Return 1 for a group consisting entirely of software events,
704 * 0 if the group contains any hardware events.
705 */
706static int is_software_only_group(struct perf_event *leader)
707{
708 struct perf_event *event;
709
710 if (!is_software_event(leader))
711 return 0;
712
713 list_for_each_entry(event, &leader->sibling_list, group_entry)
714 if (!is_software_event(event))
715 return 0;
716
717 return 1;
718}
719
720/*
721 * Work out whether we can put this event group on the CPU now. 713 * Work out whether we can put this event group on the CPU now.
722 */ 714 */
723static int group_can_go_on(struct perf_event *event, 715static int group_can_go_on(struct perf_event *event,
@@ -727,7 +719,7 @@ static int group_can_go_on(struct perf_event *event,
727 /* 719 /*
728 * Groups consisting entirely of software events can always go on. 720 * Groups consisting entirely of software events can always go on.
729 */ 721 */
730 if (is_software_only_group(event)) 722 if (event->group_flags & PERF_GROUP_SOFTWARE)
731 return 1; 723 return 1;
732 /* 724 /*
733 * If an exclusive group is already on, no other hardware 725 * If an exclusive group is already on, no other hardware