diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-10 06:33:23 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-11 09:45:48 -0500 |
commit | 9f66a3810fe0d4100972db84290f3ae4a4d77025 (patch) | |
tree | 2101d0d14aecf9d3e406544711e7336e3ea6b3af /kernel/perf_counter.c | |
parent | dfa7c899b401d7dc5d85aca416aee64ac82812f2 (diff) |
perf counters: restructure the API
Impact: clean up new API
Thorough cleanup of the new perf counters API, we now get clean separation
of the various concepts:
- introduce perf_counter_hw_event to separate out the event source details
- move special type flags into separate attributes: PERF_COUNT_NMI,
PERF_COUNT_RAW
- extend the type to u64 and reserve it fully to the architecture in the
raw type case.
And make use of all these changes in the core and x86 perfcounters code.
Also change the syscall signature to:
asmlinkage int sys_perf_counter_open(
struct perf_counter_hw_event *hw_event_uptr __user,
pid_t pid,
int cpu,
int group_fd);
( Note that group_fd is unused for now - it's reserved for the counter
groups abstraction. )
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 2557c670a3bb..0d323ceda3a4 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -669,7 +669,7 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
669 | { | 669 | { |
670 | struct perf_counter *counter = file->private_data; | 670 | struct perf_counter *counter = file->private_data; |
671 | 671 | ||
672 | switch (counter->record_type) { | 672 | switch (counter->hw_event.record_type) { |
673 | case PERF_RECORD_SIMPLE: | 673 | case PERF_RECORD_SIMPLE: |
674 | return perf_read_hw(counter, buf, count); | 674 | return perf_read_hw(counter, buf, count); |
675 | 675 | ||
@@ -707,7 +707,7 @@ static const struct file_operations perf_fops = { | |||
707 | * Allocate and initialize a counter structure | 707 | * Allocate and initialize a counter structure |
708 | */ | 708 | */ |
709 | static struct perf_counter * | 709 | static struct perf_counter * |
710 | perf_counter_alloc(struct perf_counter_event *event, int cpu, u32 record_type) | 710 | perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu) |
711 | { | 711 | { |
712 | struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); | 712 | struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); |
713 | 713 | ||
@@ -718,31 +718,37 @@ perf_counter_alloc(struct perf_counter_event *event, int cpu, u32 record_type) | |||
718 | INIT_LIST_HEAD(&counter->list); | 718 | INIT_LIST_HEAD(&counter->list); |
719 | init_waitqueue_head(&counter->waitq); | 719 | init_waitqueue_head(&counter->waitq); |
720 | 720 | ||
721 | counter->irqdata = &counter->data[0]; | 721 | counter->irqdata = &counter->data[0]; |
722 | counter->usrdata = &counter->data[1]; | 722 | counter->usrdata = &counter->data[1]; |
723 | counter->cpu = cpu; | 723 | counter->cpu = cpu; |
724 | counter->record_type = record_type; | 724 | counter->hw_event = *hw_event; |
725 | counter->event = *event; | 725 | counter->wakeup_pending = 0; |
726 | counter->wakeup_pending = 0; | ||
727 | 726 | ||
728 | return counter; | 727 | return counter; |
729 | } | 728 | } |
730 | 729 | ||
731 | /** | 730 | /** |
732 | * sys_perf_task_open - open a performance counter associate it to a task | 731 | * sys_perf_task_open - open a performance counter, associate it to a task/cpu |
733 | * @hw_event_type: event type for monitoring/sampling... | 732 | * |
733 | * @hw_event_uptr: event type attributes for monitoring/sampling | ||
734 | * @pid: target pid | 734 | * @pid: target pid |
735 | * @cpu: target cpu | ||
736 | * @group_fd: group leader counter fd | ||
735 | */ | 737 | */ |
736 | asmlinkage int | 738 | asmlinkage int sys_perf_counter_open( |
737 | sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, | 739 | |
738 | pid_t pid, int cpu, int masterfd) | 740 | struct perf_counter_hw_event *hw_event_uptr __user, |
741 | pid_t pid, | ||
742 | int cpu, | ||
743 | int group_fd) | ||
744 | |||
739 | { | 745 | { |
740 | struct perf_counter_context *ctx; | 746 | struct perf_counter_context *ctx; |
741 | struct perf_counter_event event; | 747 | struct perf_counter_hw_event hw_event; |
742 | struct perf_counter *counter; | 748 | struct perf_counter *counter; |
743 | int ret; | 749 | int ret; |
744 | 750 | ||
745 | if (copy_from_user(&event, uevent, sizeof(event)) != 0) | 751 | if (copy_from_user(&hw_event, hw_event_uptr, sizeof(hw_event)) != 0) |
746 | return -EFAULT; | 752 | return -EFAULT; |
747 | 753 | ||
748 | ctx = find_get_context(pid, cpu); | 754 | ctx = find_get_context(pid, cpu); |
@@ -750,7 +756,7 @@ sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, | |||
750 | return PTR_ERR(ctx); | 756 | return PTR_ERR(ctx); |
751 | 757 | ||
752 | ret = -ENOMEM; | 758 | ret = -ENOMEM; |
753 | counter = perf_counter_alloc(&event, cpu, record_type); | 759 | counter = perf_counter_alloc(&hw_event, cpu); |
754 | if (!counter) | 760 | if (!counter) |
755 | goto err_put_context; | 761 | goto err_put_context; |
756 | 762 | ||