diff options
-rw-r--r-- | include/linux/perf_event.h | 5 | ||||
-rw-r--r-- | kernel/perf_event.c | 30 |
2 files changed, 16 insertions, 19 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index cdbc2aa64a0b..c6f812e4d058 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -565,6 +565,10 @@ typedef void (*perf_overflow_handler_t)(struct perf_event *, int, | |||
565 | struct perf_sample_data *, | 565 | struct perf_sample_data *, |
566 | struct pt_regs *regs); | 566 | struct pt_regs *regs); |
567 | 567 | ||
568 | enum perf_group_flag { | ||
569 | PERF_GROUP_SOFTWARE = 0x1, | ||
570 | }; | ||
571 | |||
568 | /** | 572 | /** |
569 | * struct perf_event - performance event kernel representation: | 573 | * struct perf_event - performance event kernel representation: |
570 | */ | 574 | */ |
@@ -574,6 +578,7 @@ struct perf_event { | |||
574 | struct list_head event_entry; | 578 | struct list_head event_entry; |
575 | struct list_head sibling_list; | 579 | struct list_head sibling_list; |
576 | int nr_siblings; | 580 | int nr_siblings; |
581 | int group_flags; | ||
577 | struct perf_event *group_leader; | 582 | struct perf_event *group_leader; |
578 | struct perf_event *output; | 583 | struct perf_event *output; |
579 | const struct pmu *pmu; | 584 | const struct pmu *pmu; |
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 | */ | ||
706 | static 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 | */ |
723 | static int group_can_go_on(struct perf_event *event, | 715 | static 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 |