perf: Carve out cgroup-related code
RFC PATCH 1/1 perf: Carve out cgroup-related code
Hi guys,
here's a first prototype carving out cgroup perf code. It builds fine with both CONFIG_CGROUP_PERF enabled and disabled. Please take a look while I do the same with the callchain stuff and let me know whether I should do something differently.
Thanks.
---
Move cgroup perf support into a different compilation module - kernel/events/cgroup.c - thus slimming perf_event.c some more.
While at it,
* push some oneliners into perf_event.h now that they're used in multiple .c files.
* drop is_cgroup_event() check for perf_cgroup_defer_enabled() at its callsite in __perf_event_enable since the latter does the check anyway.
No functional change.
--- include/linux/perf_event.h | 138 ++++++++++++- kernel/events/Makefile | 1 + kernel/events/cgroup.c | 324 +++++++++++++++++++++++++++++ kernel/events/core.c | 496 +------------------------------------------- 4 files changed, 473 insertions(+), 486 deletions(-) create mode 100644 kernel/events/cgroup.c
include/linux/perf_event.h +137 -1
@@ -954,8 +954,15 @@ struct perf_output_handle {int sample; }; +enum event_type_t { +EVENT_FLEXIBLE =0x1 , +EVENT_PINNED =0x2 , +EVENT_ALL =EVENT_FLEXIBLE |EVENT_PINNED , +}; +#ifdef CONFIG_PERF_EVENTS +extern struct list_head pmus;extern int perf_pmu_register (struct pmu *pmu,char *name,int type);extern void perf_pmu_unregister (struct pmu *pmu);
@@ -1153,6 +1160,47 @@ extern void perf_swevent_put_recursion_context(int rctx);extern void perf_event_enable (struct perf_event *event);extern void perf_event_disable (struct perf_event *event);extern void perf_event_task_tick (void ); + +static inline struct perf_cpu_context * +__get_cpu_context (struct perf_event_context *ctx) +{ +return this_cpu_ptr (ctx->pmu->pmu_cpu_context); +} + +static inline u64 perf_clock (void ) +{ +return local_clock (); +} + +extern void ctx_sched_out (struct perf_event_context *ctx, +struct perf_cpu_context *cpuctx, +enum event_type_t event_type); +/* +* Called with IRQs disabled +*/ +static inline void cpu_ctx_sched_out (struct perf_cpu_context *cpuctx, +enum event_type_t event_type) +{ +ctx_sched_out (&cpuctx->ctx, cpuctx, event_type); +} + +extern void ctx_sched_in (struct perf_event_context *ctx, +struct perf_cpu_context *cpuctx, +enum event_type_t event_type, +struct task_struct *task); + +static inline void cpu_ctx_sched_in (struct perf_cpu_context *cpuctx, +enum event_type_t event_type, +struct task_struct *task) +{ +struct perf_event_context *ctx = &cpuctx->ctx; + +ctx_sched_in (ctx, cpuctx, event_type, task); +} + +extern int +task_function_call (struct task_struct *p,int (*func) (void *info),void *info); +extern u64 perf_event_time (struct perf_event *event);#else static inline void perf_event_task_sched_in (struct task_struct *task) { }
@@ -1187,7 +1235,95 @@ static inline void perf_swevent_put_recursion_context(int rctx) { }static inline void perf_event_enable (struct perf_event *event) { }static inline void perf_event_disable (struct perf_event *event) { }static inline void perf_event_task_tick (void ) { } -#endif +static inline void ctx_sched_out (struct perf_event_context *ctx, +struct perf_cpu_context *cpuctx, +enum event_type_t event_type) { } + +static void ctx_sched_in (struct perf_event_context *ctx, +struct perf_cpu_context *cpuctx, +enum event_type_t event_type, +struct task_struct *task) { } +static inline int +task_function_call (struct task_struct *p, +int (*func) (void *info),void *info) {return -EINVAL ; } +static inline u64 perf_event_time (struct perf_event *event) {return 0 ; } +#endif /* CONFIG_PERF_EVENTS */ + +#ifdef CONFIG_CGROUP_PERF +extern struct perf_cgroup * +perf_cgroup_from_task (struct task_struct *task); +extern bool perf_cgroup_match (struct perf_event *event); +extern int +perf_cgroup_connect (pid_t pid,struct perf_event *event, +struct perf_event_attr *attr, +struct perf_event *group_leader); +extern void perf_detach_cgroup (struct perf_event *event); + +static inline int is_cgroup_event (struct perf_event *event) +{ +return event->cgrp !=NULL ; +} + +extern u64 perf_cgroup_event_time (struct perf_event *event); +extern void update_cgrp_time_from_event (struct perf_event *event); +extern void +update_cgrp_time_from_cpuctx (struct perf_cpu_context *cpuctx); +extern void +perf_cgroup_set_timestamp (struct task_struct *task, +struct perf_event_context *ctx); + +extern void perf_cgroup_sched_out (struct task_struct *task); +extern void perf_cgroup_sched_in (struct task_struct *task); + +static inline void +perf_cgroup_set_shadow_time (struct perf_event *event,u64 now) +{ +struct perf_cgroup_info *t; + t =per_cpu_ptr (event->cgrp->info, event->cpu); + event->shadow_ctx_time = now - t->timestamp; +} + +static inline void +perf_cgroup_defer_enabled (struct perf_event *event) +{ +/* +* when the current task's perf cgroup does not match +* the event's, we need to remember to call the +* perf_mark_enable() function the first time a task with +* a matching perf cgroup is scheduled in. +*/ +if (is_cgroup_event (event) && !perf_cgroup_match (event)) + event->cgrp_defer_enabled =1 ; +} +extern inline void +perf_cgroup_mark_enabled (struct perf_event *event, +struct perf_event_context *ctx); +#else +static inline struct perf_cgroup * +perf_cgroup_from_task (struct task_struct *task) {return NULL ; } +static inline bool perf_cgroup_match (struct perf_event *event) {return true; } +static inline int +perf_cgroup_connect (pid_t pid,struct perf_event *event, +struct perf_event_attr *attr, +struct perf_event *group_leader) {return -EINVAL ; } +static inline void perf_detach_cgroup (struct perf_event *event) { } +static inline int is_cgroup_event (struct perf_event *event) {return 0 ; } +static inline u64 perf_cgroup_event_time (struct perf_event *event) {return 0 ; } +static inline void update_cgrp_time_from_event (struct perf_event *e) { } +static inline void +update_cgrp_time_from_cpuctx (struct perf_cpu_context *cpuctx) { } +static inline void +perf_cgroup_set_timestamp (struct task_struct *task, +struct perf_event_context *ctx) { } +static inline void perf_cgroup_sched_out (struct task_struct *task) { } +static inline void perf_cgroup_sched_in (struct task_struct *task) { } +static inline void +perf_cgroup_set_shadow_time (struct perf_event *event,u64 now) { } +static inline void perf_cgroup_defer_enabled (struct perf_event *event) { } +static inline void +perf_cgroup_mark_enabled (struct perf_event *event, +struct perf_event_context *ctx) { } +#endif /* CONFIG_CGROUP_PERF */ #define perf_output_put (handle, x) perf_output_copy((handle), &(x), sizeof(x))
kernel/events/Makefile +1 -0
@@ -4,3 +4,4 @@ endif obj-y := core.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o +obj-$(CONFIG_CGROUP_PERF) += cgroup.o
kernel/events/cgroup.c new file +324 -0
324 lines not on this page · raw message
kernel/events/core.c +11 -485
566 lines not on this page · raw message
Signature · 12 lines
1.7.4.rc2 -- Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-
I don't like exposing all that in a kernel wide header.. should we maybe have kernel/events/internal.h?
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-I don't like exposing all that in a kernel wide header.. should we maybe have
kernel/events/internal.h?
Sounds prudent. Maybe add a patch ontop that moves all perf_event.h exports which are shared _only_ between kernel/events/*.c compilation units to an internal.h header? Ingo?
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 10 lines · Borislav Petkov
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-I don't like exposing all that in a kernel wide header.. should we maybe have
kernel/events/internal.h?Sounds prudent. Maybe add a patch ontop that moves all
perf_event.hexports which are shared _only_ betweenkernel/events/*.ccompilation units to aninternal.hheader? Ingo?
There's not that many that are in perf_event.h and are only used in kernel/event/core.c.
Below is a generated list of all exported functions and their usage sites. Out of 40 functions 7 should not be exported:
__perf_sw_event()
perf_swevent_put_recursion_context()
perf_pmu_unregister()
perf_output_copy()
__perf_event_task_sched_in()
__perf_event_task_sched_out()
perf_event_read_value()
Thanks,
Ingo
perf_bp_event():arch/arm/kernel/hw_breakpoint.carch/powerpc/kernel/hw_breakpoint.carch/sh/kernel/hw_breakpoint.carch/x86/kernel/hw_breakpoint.cinclude/linux/perf_event.hkernel/events/core.c
perf_callchain_kernel():arch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_callchain.carch/sh/kernel/perf_callchain.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.c
perf_callchain_user():arch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_callchain.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.c
perf_event_comm():fs/exec.cinclude/linux/perf_event.hkernel/events/core.c
perf_event_delayed_put():include/linux/perf_event.hkernel/events/core.ckernel/exit.c
perf_event_disable():arch/powerpc/kernel/hw_breakpoint.cinclude/linux/perf_event.hkernel/events/core.ckernel/events/hw_breakpoint.ckernel/watchdog.c
perf_event_enable():include/linux/perf_event.hkernel/events/core.ckernel/events/hw_breakpoint.ckernel/watchdog.c
perf_event_exit_task():fs/exec.cinclude/linux/perf_event.hkernel/events/core.ckernel/exit.c
perf_event_fork():include/linux/perf_event.hkernel/events/core.ckernel/fork.c
perf_event_free_task():include/linux/perf_event.hkernel/events/core.ckernel/fork.c
perf_event_init():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/mips/kernel/perf_event_mipsxx.carch/sh/kernel/perf_event.cinclude/linux/perf_event.hinit/main.ckernel/events/core.ckernel/fork.ctools/perf/design.txt
perf_event_init_task():include/linux/perf_event.hkernel/events/core.ckernel/fork.c
perf_event_mmap():include/linux/perf_event.hkernel/events/core.cmm/mmap.cmm/mprotect.ctools/perf/design.txttools/perf/perf.htools/perf/util/event.c
perf_event_overflow():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event_v6.carch/arm/kernel/perf_event_v7.carch/arm/kernel/perf_event_xscale.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_event.carch/powerpc/kernel/perf_event_fsl_emb.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.carch/x86/kernel/cpu/perf_event_intel.carch/x86/kernel/cpu/perf_event_intel_ds.carch/x86/kernel/cpu/perf_event_p4.cinclude/linux/perf_event.hkernel/events/core.c
perf_event_print_debug():arch/alpha/kernel/perf_event.carch/powerpc/kernel/perf_event.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.carch/x86/kernel/cpu/perf_event_intel.cdrivers/tty/sysrq.cinclude/linux/perf_event.hkernel/events/core.c
perf_event_read_value():include/linux/perf_event.hkernel/events/core.c
perf_event_release_kernel():drivers/oprofile/oprofile_perf.cinclude/linux/perf_event.hkernel/events/core.ckernel/events/hw_breakpoint.ckernel/watchdog.c
perf_event_task_disable():include/linux/perf_event.hkernel/events/core.ckernel/sys.c
perf_event_task_enable():include/linux/perf_event.hkernel/events/core.ckernel/sys.c
__perf_event_task_sched_in():include/linux/perf_event.hkernel/events/core.c
__perf_event_task_sched_out():include/linux/perf_event.hkernel/events/core.c
perf_event_task_tick():include/linux/perf_event.hkernel/events/core.ckernel/sched.c
perf_event_update_userpage():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_event.carch/powerpc/kernel/perf_event_fsl_emb.carch/sh/kernel/perf_event.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.c
perf_num_counters():arch/arm/kernel/perf_event.carch/sh/kernel/perf_event.carch/sh/oprofile/common.cdrivers/oprofile/oprofile_perf.cinclude/linux/perf_event.h
perf_output_begin():arch/x86/kernel/cpu/perf_event_intel_ds.cinclude/linux/perf_event.hkernel/events/core.c
perf_output_copy():include/linux/perf_event.hkernel/events/core.c
perf_output_end():arch/x86/kernel/cpu/perf_event_intel_ds.cinclude/linux/perf_event.hkernel/events/core.c
perf_output_sample():arch/x86/kernel/cpu/perf_event_intel_ds.cinclude/linux/perf_event.hkernel/events/core.c
perf_pmu_disable():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_event.carch/powerpc/kernel/perf_event_fsl_emb.carch/sh/kernel/perf_event.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.c
perf_pmu_enable():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event.carch/mips/kernel/perf_event.carch/powerpc/kernel/perf_event.carch/powerpc/kernel/perf_event_fsl_emb.carch/sh/kernel/perf_event.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.c
perf_pmu_register():arch/alpha/kernel/perf_event.carch/arm/kernel/perf_event.carch/mips/kernel/perf_event_mipsxx.carch/powerpc/kernel/perf_event.carch/powerpc/kernel/perf_event_fsl_emb.carch/sh/kernel/perf_event.carch/sparc/kernel/perf_event.carch/x86/kernel/cpu/perf_event.cinclude/linux/perf_event.hkernel/events/core.ckernel/events/hw_breakpoint.c
perf_pmu_unregister():include/linux/perf_event.hkernel/events/core.c
perf_prepare_sample():arch/x86/kernel/cpu/perf_event_intel_ds.cinclude/linux/perf_event.hkernel/events/core.c
perf_proc_update_handler():include/linux/perf_event.hkernel/events/core.ckernel/sysctl.c
perf_register_guest_info_callbacks():arch/x86/kvm/x86.cinclude/linux/perf_event.hkernel/events/core.c
__perf_sw_event():include/linux/perf_event.hkernel/events/core.c
perf_swevent_get_recursion_context():include/linux/perf_event.hkernel/events/core.ckernel/trace/trace_event_perf.c
perf_swevent_put_recursion_context():include/linux/perf_event.hkernel/events/core.c
perf_tp_event():include/linux/ftrace_event.hinclude/linux/perf_event.hinclude/trace/ftrace.hkernel/events/core.c
perf_unregister_guest_info_callbacks():arch/x86/kvm/x86.cinclude/linux/perf_event.hkernel/events/core.c
Quoted 20 lines · Ingo Molnar
Quoted 10 lines · Borislav Petkov
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-I don't like exposing all that in a kernel wide header.. should we maybe have
kernel/events/internal.h?Sounds prudent. Maybe add a patch ontop that moves all
perf_event.hexports which are shared _only_ betweenkernel/events/*.ccompilation units to aninternal.hheader? Ingo?There's not that many that are in
perf_event.hand are only used inkernel/event/core.c.Below is a generated list of all exported functions and their usage sites. Out of 40 functions 7 should not be exported:
Quoted 7 lines
__perf_sw_event()
perf_swevent_put_recursion_context()
perf_pmu_unregister()
perf_output_copy()
__perf_event_task_sched_in()
__perf_event_task_sched_out()
perf_event_read_value()
Right, but splitting perf_event.c further would cause a bunch more of them to go up in the header since they're being shared among kernel/events/*.c files. But in the end, this is a judgement call - I mean, even the polluting ones have a clearly defined namespace starting their names with {_-,}perf_*. If you asked me, I'd do an internal.h header from the get-go so that all is kept as clean as possible.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 29 lines · Borislav Petkov
Quoted 20 lines · Ingo Molnar
Quoted 10 lines · Borislav Petkov
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-I don't like exposing all that in a kernel wide header.. should we maybe have
kernel/events/internal.h?Sounds prudent. Maybe add a patch ontop that moves all
perf_event.hexports which are shared _only_ betweenkernel/events/*.ccompilation units to aninternal.hheader? Ingo?There's not that many that are in
perf_event.hand are only used inkernel/event/core.c.Below is a generated list of all exported functions and their usage sites. Out of 40 functions 7 should not be exported:
Quoted 7 lines
__perf_sw_event()
perf_swevent_put_recursion_context()
perf_pmu_unregister()
perf_output_copy()
__perf_event_task_sched_in()
__perf_event_task_sched_out()
perf_event_read_value()
Quoted 6 lines
Right, but splitting
perf_event.cfurther would cause a bunch more of them to go up in the header since they're being shared amongkernel/events/*.cfiles. But in the end, this is a judgement call - I mean, even the polluting ones have a clearly defined namespace starting their names with {_-,}perf_*. If you asked me, I'd do aninternal.hheader from the get-go so that all is kept as clean as possible.
We seem to be in wild agreement wrt. internal.h!
Thanks,
Ingo
On Wed, May 11, 2011 at 11:21:56AM -0400, Ingo Molnar wrote:
[..]
Quoted 14 lines
Quoted 14 lines
Quoted 13 lines
There's not that many that are in
perf_event.hand are only used inkernel/event/core.c.Below is a generated list of all exported functions and their usage sites. Out of 40 functions 7 should not be exported:
__perf_sw_event()
perf_swevent_put_recursion_context()
perf_pmu_unregister()
perf_output_copy()
__perf_event_task_sched_in()
__perf_event_task_sched_out()
perf_event_read_value()
Quoted 8 lines
Quoted 6 lines
Right, but splitting
perf_event.cfurther would cause a bunch more of them to go up in the header since they're being shared amongkernel/events/*.cfiles. But in the end, this is a judgement call - I mean, even the polluting ones have a clearly defined namespace starting their names with {_-,}perf_*. If you asked me, I'd do aninternal.hheader from the get-go so that all is kept as clean as possible.We seem to be in wild agreement wrt.
internal.h!
Done, patch below. I've moved all exports local to kernel/events/* to internal.h. Branch at
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git perf-split
also updated.
--
From: Borislav Petkov <[email protected]>
Date: Wed, 11 May 2011 19:02:10 +0200
Subject: [PATCH] perf: Cleanup namespace
Add an internal header containing all function declarations used only by kernel/events/* compilation units. Drop declarations used in one .c file only.
No functionality change.
--- include/linux/perf_event.h | 132 -------------------------------------------- kernel/events/callchain.c | 3 + kernel/events/cgroup.c | 2 + kernel/events/core.c | 2 + kernel/events/internal.h | 129 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 132 deletions(-) create mode 100644 kernel/events/internal.h
include/linux/perf_event.h +0 -132
@@ -963,7 +963,6 @@ enum event_type_t {#ifdef CONFIG_PERF_EVENTS extern struct list_head pmus;extern int perf_pmu_register (struct pmu *pmu,char *name,int type); -extern void perf_pmu_unregister (struct pmu *pmu);extern int perf_num_counters (void );extern const char *perf_pmu_name (void );
@@ -985,8 +984,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,int cpu, struct task_struct *task, perf_overflow_handler_t callback); -extern u64 perf_event_read_value (struct perf_event *event, -u64 *enabled,u64 *running);struct perf_sample_data {u64 type;
@@ -1152,60 +1149,10 @@ extern int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample);extern void perf_output_end (struct perf_output_handle *handle); -extern void perf_output_copy (struct perf_output_handle *handle, -const void *buf,unsigned int len);extern int perf_swevent_get_recursion_context (void ); -extern void perf_swevent_put_recursion_context (int rctx);extern void perf_event_enable (struct perf_event *event);extern void perf_event_disable (struct perf_event *event);extern void perf_event_task_tick (void ); - -static inline struct perf_cpu_context * -__get_cpu_context (struct perf_event_context *ctx) -{ -return this_cpu_ptr (ctx->pmu->pmu_cpu_context); -} - -static inline u64 perf_clock (void ) -{ -return local_clock (); -} - -extern void ctx_sched_out (struct perf_event_context *ctx, -struct perf_cpu_context *cpuctx, -enum event_type_t event_type); -/* -* Called with IRQs disabled -*/ -static inline void cpu_ctx_sched_out (struct perf_cpu_context *cpuctx, -enum event_type_t event_type) -{ -ctx_sched_out (&cpuctx->ctx, cpuctx, event_type); -} - -extern void ctx_sched_in (struct perf_event_context *ctx, -struct perf_cpu_context *cpuctx, -enum event_type_t event_type, -struct task_struct *task); - -static inline void cpu_ctx_sched_in (struct perf_cpu_context *cpuctx, -enum event_type_t event_type, -struct task_struct *task) -{ -struct perf_event_context *ctx = &cpuctx->ctx; - -ctx_sched_in (ctx, cpuctx, event_type, task); -} - -extern int -task_function_call (struct task_struct *p,int (*func) (void *info),void *info); -extern u64 perf_event_time (struct perf_event *event); - -extern int get_recursion_context (int *recursion); -extern inline void put_recursion_context (int *recursion,int rctx); -extern void put_callchain_buffers (void ); -extern struct perf_callchain_entry *perf_callchain (struct pt_regs *regs); -extern int get_callchain_buffers (void );#else static inline void perf_event_task_sched_in (struct task_struct *task) { }
@@ -1236,90 +1183,11 @@ static inline void perf_event_comm(struct task_struct *tsk) { }static inline void perf_event_fork (struct task_struct *tsk) { }static inline void perf_event_init (void ) { }static inline int perf_swevent_get_recursion_context (void ) {return -1 ; } -static inline void perf_swevent_put_recursion_context (int rctx) { }static inline void perf_event_enable (struct perf_event *event) { }static inline void perf_event_disable (struct perf_event *event) { }static inline void perf_event_task_tick (void ) { }#endif /* CONFIG_PERF_EVENTS */ -#ifdef CONFIG_CGROUP_PERF -extern struct perf_cgroup * -perf_cgroup_from_task (struct task_struct *task); -extern bool perf_cgroup_match (struct perf_event *event); -extern int -perf_cgroup_connect (pid_t pid,struct perf_event *event, -struct perf_event_attr *attr, -struct perf_event *group_leader); -extern void perf_detach_cgroup (struct perf_event *event); - -static inline int is_cgroup_event (struct perf_event *event) -{ -return event->cgrp !=NULL ; -} - -extern u64 perf_cgroup_event_time (struct perf_event *event); -extern void update_cgrp_time_from_event (struct perf_event *event); -extern void -update_cgrp_time_from_cpuctx (struct perf_cpu_context *cpuctx); -extern void -perf_cgroup_set_timestamp (struct task_struct *task, -struct perf_event_context *ctx); - -extern void perf_cgroup_sched_out (struct task_struct *task); -extern void perf_cgroup_sched_in (struct task_struct *task); - -static inline void -perf_cgroup_set_shadow_time (struct perf_event *event,u64 now) -{ -struct perf_cgroup_info *t; - t =per_cpu_ptr (event->cgrp->info, event->cpu); - event->shadow_ctx_time = now - t->timestamp; -} - -static inline void -perf_cgroup_defer_enabled (struct perf_event *event) -{ -/* -* when the current task's perf cgroup does not match -* the event's, we need to remember to call the -* perf_mark_enable() function the first time a task with -* a matching perf cgroup is scheduled in. -*/ -if (is_cgroup_event (event) && !perf_cgroup_match (event)) - event->cgrp_defer_enabled =1 ; -} -extern inline void -perf_cgroup_mark_enabled (struct perf_event *event, -struct perf_event_context *ctx); -#else -static inline struct perf_cgroup * -perf_cgroup_from_task (struct task_struct *task) {return NULL ; } -static inline bool perf_cgroup_match (struct perf_event *event) {return true; } -static inline int -perf_cgroup_connect (pid_t pid,struct perf_event *event, -struct perf_event_attr *attr, -struct perf_event *group_leader) {return -EINVAL ; } -static inline void perf_detach_cgroup (struct perf_event *event) { } -static inline int is_cgroup_event (struct perf_event *event) {return 0 ; } -static inline u64 perf_cgroup_event_time (struct perf_event *event) {return 0 ; } -static inline void update_cgrp_time_from_event (struct perf_event *e) { } -static inline void -update_cgrp_time_from_cpuctx (struct perf_cpu_context *cpuctx) { } -static inline void -perf_cgroup_set_timestamp (struct task_struct *task, -struct perf_event_context *ctx) { } -static inline void perf_cgroup_sched_out (struct task_struct *task) { } -static inline void perf_cgroup_sched_in (struct task_struct *task) { } -static inline void -perf_cgroup_set_shadow_time (struct perf_event *event,u64 now) { } -static inline void perf_cgroup_defer_enabled (struct perf_event *event) { } -static inline void -perf_cgroup_mark_enabled (struct perf_event *event, -struct perf_event_context *ctx) { } -#endif /* CONFIG_CGROUP_PERF */ - -#define perf_output_put (handle, x) perf_output_copy((handle), &(x), sizeof(x)) -/* * This has to have a higher priority than migration_notifier in sched.c. */
kernel/events/callchain.c +3 -0
@@ -1,6 +1,9 @@#include <linux/slab.h> #include <linux/hardirq.h> #include <linux/perf_event.h> + +#include "internal.h" +/* * Callchain support */
kernel/events/cgroup.c +2 -0
@@ -2,6 +2,8 @@#include <linux/slab.h> #include <linux/perf_event.h> +#include "internal.h" +/* * Must ensure cgroup is pinned (css_get) before calling * this function. In other words, we cannot call this function
kernel/events/core.c +2 -0
@@ -38,6 +38,8 @@#include <asm/irq_regs.h> +#include "internal.h" +struct remote_function_call {struct task_struct *p;int (*func)(void *info);
kernel/events/internal.h new file +129 -0
129 lines not on this page · raw message
Signature · 13 lines
1.7.4.rc2 -- Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
On Wed, 2011-05-11 at 19:09 +0200, Borislav Petkov wrote:
I can't really say I like this move stuff into perf_event.h and then move it out again dance. Makes it exceedingly hard for me to tell wth actually happened.
Quoted 1 line
include/linux/perf_event.h | 132 --------------------------------------------
Compared with:
include/linux/perf_event.h | 126 +++++++++++- include/linux/perf_event.h | 7 +-
Its very hard to tell if this undoes the exact damage you did earlier.
Quoted 12 lines
kernel/events/callchain.c | 3 + kernel/events/cgroup.c | 2 + kernel/events/core.c | 2 + kernel/events/internal.h | 129 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 132 deletions(-) create mode 100644 kernel/events/internal.hinclude/linux/perf_event.h +0
-0
include/linux/perf_event.h enum event_type_t { · line 966
Quoted 4 lines
include/linux/perf_event.h +0
-1@@ -963,7 +963,6 @@ enum event_type_t {#ifdef CONFIG_PERF_EVENTS extern struct list_head pmus;extern int perf_pmu_register (struct pmu *pmu,char *name,int type); -extern void perf_pmu_unregister (struct pmu *pmu);
That just doesn't make any sense. If we publish one side of the API we should also publish the other side.
include/linux/perf_event.h perf_event_create_kernel_counter(struct perf_event_attr *attr, · line 989
Quoted 8 lines
include/linux/perf_event.h +0
-2extern int perf_num_counters (void );extern const char *perf_pmu_name (void );@@ -985,8 +984,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,int cpu, struct task_struct *task, perf_overflow_handler_t callback); -extern u64 perf_event_read_value (struct perf_event *event, -u64 *enabled,u64 *running);
While not used, that is a valid part of the API.
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1156
Quoted 9 lines
include/linux/perf_event.h +0
-2struct perf_sample_data {u64 type;@@ -1152,60 +1149,10 @@ extern int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample);extern void perf_output_end (struct perf_output_handle *handle); -extern void perf_output_copy (struct perf_output_handle *handle, -const void *buf,unsigned int len);
idem
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1158
Quoted 2 lines
include/linux/perf_event.h +0
-1extern int perf_swevent_get_recursion_context (void ); -extern void perf_swevent_put_recursion_context (int rctx);
Again, creating asymmetry.
Quoted 3 lines
include/linux/perf_event.h +0
-0extern void perf_event_enable (struct perf_event *event);extern void perf_event_disable (struct perf_event *event);extern void perf_event_task_tick (void );
Peter Zijlstra
maintainerQuoted 1 line · Peter Zijlstra
On Wed, 2011-05-11 at 19:09 +0200, Borislav Petkov wrote:
Also please don't cross-post to bouncy lists like this weird amd list you included.
Quoted 6 lines · Peter Zijlstra
On Wed, 2011-05-11 at 19:09 +0200, Borislav Petkov wrote:
I can't really say I like this move stuff into
perf_event.hand then move it out again dance. Makes it exceedingly hard for me to tell wth actually happened.
Quoted 8 lines
Quoted 1 line
include/linux/perf_event.h | 132 --------------------------------------------Compared with:
include/linux/perf_event.h | 126 +++++++++++- include/linux/perf_event.h | 7 +-Its very hard to tell if this undoes the exact damage you did earlier.
The right thing to do would be to redo the patches again with internal.h in mind.
Quoted 7 lines
Quoted 7 lines
kernel/events/callchain.c | 3 + kernel/events/cgroup.c | 2 + kernel/events/core.c | 2 + kernel/events/internal.h | 129 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 132 deletions(-) create mode 100644 kernel/events/internal.h
Quoted 12 lines
include/linux/perf_event.h enum event_type_t { · line 966
Quoted 9 lines
include/linux/perf_event.h +0
-1@@ -963,7 +963,6 @@ enum event_type_t {#ifdef CONFIG_PERF_EVENTS extern struct list_head pmus;extern int perf_pmu_register (struct pmu *pmu,char *name,int type); -extern void perf_pmu_unregister (struct pmu *pmu);That just doesn't make any sense. If we publish one side of the API we should also publish the other side.
Fair enough. It was unused, therefore I removed it.
Quoted 10 lines
include/linux/perf_event.h perf_event_create_kernel_counter(struct perf_event_attr *attr, · line 989
Quoted 8 lines
include/linux/perf_event.h +0
-2extern int perf_num_counters (void );extern const char *perf_pmu_name (void );@@ -985,8 +984,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,int cpu, struct task_struct *task, perf_overflow_handler_t callback); -extern u64 perf_event_read_value (struct perf_event *event, -u64 *enabled,u64 *running);While not used, that is a valid part of the API.
Yep, ditto.
Quoted 12 lines
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1156
Quoted 9 lines
include/linux/perf_event.h +0
-2struct perf_sample_data {u64 type;@@ -1152,60 +1149,10 @@ extern int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample);extern void perf_output_end (struct perf_output_handle *handle); -extern void perf_output_copy (struct perf_output_handle *handle, -const void *buf,unsigned int len);idem
Quoted 4 lines
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1158
Quoted 2 lines
include/linux/perf_event.h +0
-1extern int perf_swevent_get_recursion_context (void ); -extern void perf_swevent_put_recursion_context (int rctx);Again, creating asymmetry.
Ok, I won't be able to redo the patches before Mo. due to travel. Also, I think that you should do the splitting, as I suggested so at the beginning!
It is only natural since it is your code, only you know exactly what you want to do with it, how to split, what to export and before we do a couple of iterations back and forth of me sending patches and you suggesting what needs to be changed, we could save us a bunch of trouble and time if you did the split the "right" way :).
Btw, feel free to reuse any of my stuff if you feel like it.
P.S. Sorry for the bouncy ML, we're fixing it.
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 66 lines · Borislav Petkov
Quoted 6 lines · Peter Zijlstra
On Wed, 2011-05-11 at 19:09 +0200, Borislav Petkov wrote:
I can't really say I like this move stuff into
perf_event.hand then move it out again dance. Makes it exceedingly hard for me to tell wth actually happened.Quoted 8 lines
Quoted 1 line
include/linux/perf_event.h | 132 --------------------------------------------Compared with:
include/linux/perf_event.h | 126 +++++++++++- include/linux/perf_event.h | 7 +-Its very hard to tell if this undoes the exact damage you did earlier.
The right thing to do would be to redo the patches again with
internal.hin mind.Quoted 7 lines
Quoted 7 lines
kernel/events/callchain.c | 3 + kernel/events/cgroup.c | 2 + kernel/events/core.c | 2 + kernel/events/internal.h | 129 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 132 deletions(-) create mode 100644 kernel/events/internal.hQuoted 12 lines
include/linux/perf_event.h enum event_type_t { · line 966
Quoted 9 lines
include/linux/perf_event.h +0
-1@@ -963,7 +963,6 @@ enum event_type_t {#ifdef CONFIG_PERF_EVENTS extern struct list_head pmus;extern int perf_pmu_register (struct pmu *pmu,char *name,int type); -extern void perf_pmu_unregister (struct pmu *pmu);That just doesn't make any sense. If we publish one side of the API we should also publish the other side.
Fair enough. It was unused, therefore I removed it.
Quoted 10 lines
include/linux/perf_event.h perf_event_create_kernel_counter(struct perf_event_attr *attr, · line 989
Quoted 8 lines
include/linux/perf_event.h +0
-2extern int perf_num_counters (void );extern const char *perf_pmu_name (void );@@ -985,8 +984,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,int cpu, struct task_struct *task, perf_overflow_handler_t callback); -extern u64 perf_event_read_value (struct perf_event *event, -u64 *enabled,u64 *running);While not used, that is a valid part of the API.
Yep, ditto.
Quoted 12 lines
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1156
Quoted 9 lines
include/linux/perf_event.h +0
-2struct perf_sample_data {u64 type;@@ -1152,60 +1149,10 @@ extern int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample);extern void perf_output_end (struct perf_output_handle *handle); -extern void perf_output_copy (struct perf_output_handle *handle, -const void *buf,unsigned int len);idem
Quoted 8 lines
Quoted 4 lines
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1158
Quoted 2 lines
include/linux/perf_event.h +0
-1extern int perf_swevent_get_recursion_context (void ); -extern void perf_swevent_put_recursion_context (int rctx);Again, creating asymmetry.
Ok, I won't be able to redo the patches before Mo. due to travel. Also, I think that you should do the splitting, as I suggested so at the beginning!
I can take it if you want. I'm currently splitting the buffer part so I can try to relay the rest as well :)
Quoted 70 lines · Frederic Weisbecker
Quoted 69 lines · Borislav Petkov
Quoted 6 lines · Peter Zijlstra
On Wed, 2011-05-11 at 19:09 +0200, Borislav Petkov wrote:
I can't really say I like this move stuff into
perf_event.hand then move it out again dance. Makes it exceedingly hard for me to tell wth actually happened.Quoted 8 lines
Quoted 1 line
include/linux/perf_event.h | 132 --------------------------------------------
Compared with:
include/linux/perf_event.h | 126 +++++++++++-
include/linux/perf_event.h | 7 +-Its very hard to tell if this undoes the exact damage you did earlier.
The right thing to do would be to redo the patches again with
internal.hin mind.Quoted 7 lines
Quoted 7 lines
kernel/events/callchain.c | 3 +
kernel/events/cgroup.c | 2 +
kernel/events/core.c | 2 +
kernel/events/internal.h | 129 +++++++++++++++++++++++++++++++++++++++++++5 files changed, 136 insertions(+), 132 deletions(-)create mode 100644
kernel/events/internal.hQuoted 12 lines
include/linux/perf_event.h enum event_type_t { · line 966
Quoted 9 lines
include/linux/perf_event.h +0
-1@@ -963,7 +963,6 @@ enum event_type_t { #ifdef CONFIG_PERF_EVENTS extern struct list_head pmus; extern int perf_pmu_register(struct pmu *pmu, char *name, int type); -extern void perf_pmu_unregister (struct pmu *pmu);That just doesn't make any sense. If we publish one side of the API we should also publish the other side.
Fair enough. It was unused, therefore I removed it.
Quoted 10 lines
include/linux/perf_event.h perf_event_create_kernel_counter(struct perf_event_attr *attr, · line 989
Quoted 8 lines
include/linux/perf_event.h +0
-2extern int perf_num_counters(void); extern const char *perf_pmu_name(void);@@ -985,8 +984,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, struct task_struct *task, perf_overflow_handler_t callback); -extern u64 perf_event_read_value (struct perf_event *event, - u64 *enabled, u64 *running);While not used, that is a valid part of the API.
Yep, ditto.
Quoted 15 lines
include/linux/perf_event.h extern int perf_output_begin(struct perf_output_handle *handle, · line 1156
Quoted 9 lines
include/linux/perf_event.h +0
-2struct perf_sample_data { u64 type;@@ -1152,60 +1149,10 @@ extern int perf_output_begin(struct perf_output_handle *handle, struct perf_event *event, unsigned int size, int nmi, int sample); extern void perf_output_end(struct perf_output_handle *handle); -extern void perf_output_copy (struct perf_output_handle *handle, - const void *buf, unsigned int len);idem
Quoted 2 lines
include/linux/perf_event.h +0
-1extern int perf_swevent_get_recursion_context(void); -extern void perf_swevent_put_recursion_context (int rctx);
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Again, creating asymmetry.
Ok, I won't be able to redo the patches before Mo. due to travel. Also, I think that you should do the splitting, as I suggested so at the beginning!
I can take it if you want. I'm currently splitting the buffer part so I can try to relay the rest as well :)
Another split could be to split the software pmus out. perf_swevent, perf_cpu_clock and perf_task_clock.
Signature · 1 line
Lin Ming -- Intel Open Source Technology Center
Quoted 6 lines · Frederic Weisbecker
Quoted 3 lines
Ok, I won't be able to redo the patches before Mo. due to travel. Also, I think that you should do the splitting, as I suggested so at the beginning!
I can take it if you want. I'm currently splitting the buffer part so I can try to relay the rest as well :)
Hey Frederic,
yeah, sure, go ahead.
I can take over your preso at LinuxTag instead, if you'd like :)
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 5 lines · Borislav Petkov
Quoted 4 lines · Frederic Weisbecker
Quoted 3 lines
Ok, I won't be able to redo the patches before Mo. due to travel. Also, I think that you should do the splitting, as I suggested so at the beginning!
Quoted 8 lines
Quoted 2 lines
I can take it if you want. I'm currently splitting the buffer part so I can try to relay the rest as well :)
Hey Frederic,
yeah, sure, go ahead.
I can take over your preso at LinuxTag instead, if you'd like :)
Sure, please do ;)
Quoted 4 lines · Borislav Petkov
Done, patch below. I've moved all exports local to
kernel/events/*tointernal.h. Branch at
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.gitperf-split
Beyond the things Peter noticed, there's also this new bit in perf_event.h:
enum event_type_t {
EVENT_FLEXIBLE = 0x1,
EVENT_PINNED = 0x2,
EVENT_ALL = EVENT_FLEXIBLE | EVENT_PINNED,
};this got there from core.c, albeit it's only core.c that uses it.
If then this should move to internal.h - or stay local to core.c.
Thanks,
Ingo
Quoted 16 lines · Ingo Molnar
Quoted 4 lines · Borislav Petkov
Done, patch below. I've moved all exports local to
kernel/events/*tointernal.h. Branch at
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.gitperf-splitBeyond the things Peter noticed, there's also this new bit in
perf_event.h:enum event_type_t { EVENT_FLEXIBLE = 0x1, EVENT_PINNED = 0x2, EVENT_ALL = EVENT_FLEXIBLE | EVENT_PINNED, };
Quoted 3 lines
this got there from
core.c, albeit it's onlycore.cthat uses it.If then this should move to
internal.h- or stay local tocore.c.
event_type_t gets pulled by pushing
ctx_sched_out(..., enum event_type_t event_type)
up into the header since otherwise gcc complains of not seeing the definition of the third argument.
And yes, it should go to internal.h.
Thanks.
Signature · 8 lines
Regards/Gruss, Boris. Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach General Managers: Alberto Bozzo, Andrew Bowd Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
Quoted 21 lines · Borislav Petkov
Quoted 16 lines · Ingo Molnar
Quoted 4 lines · Borislav Petkov
Done, patch below. I've moved all exports local to
kernel/events/*tointernal.h. Branch at
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.gitperf-splitBeyond the things Peter noticed, there's also this new bit in
perf_event.h:enum event_type_t { EVENT_FLEXIBLE = 0x1, EVENT_PINNED = 0x2, EVENT_ALL = EVENT_FLEXIBLE | EVENT_PINNED, };Quoted 3 lines
this got there from
core.c, albeit it's onlycore.cthat uses it.If then this should move to
internal.h- or stay local tocore.c.
Quoted 8 lines
event_type_tgets pulled by pushing
ctx_sched_out(..., enum event_type_t event_type)up into the header since otherwise gcc complains of not seeing the definition of the third argument.
And yes, it should go to
internal.h.
yeah.
Thanks,
Ingo
Quoted 5 lines · Peter Zijlstra
Quoted 1 line · Borislav Petkov
include/linux/perf_event.h | 138 ++++++++++++-I don't like exposing all that in a kernel wide header.. should we maybe have
kernel/events/internal.h?
Yeah.
We could eventually avoid exposing much of struct perf_event as well: arch PMU drivers need the struct perf_event_attr, struct hw_perf_event and not much else.
Thanks,
Ingo