lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <tip-fb0459d75c1d0a4ba3cafdd2c754e7486968a676@git.kernel.org> Date: Sat, 21 Nov 2009 13:36:23 GMT From: tip-bot for Arjan van de Ven <arjan@...radead.org> To: linux-tip-commits@...r.kernel.org Cc: acme@...hat.com, mingo@...hat.com, stern@...land.harvard.edu, efault@....de, peterz@...radead.org, jirislaby@...il.com, fweisbec@...il.com, rostedt@...dmis.org, tglx@...utronix.de, mhiramat@...hat.com, linux-kernel@...r.kernel.org, hpa@...or.com, paulus@...ba.org, arjan@...ux.intel.com, lizf@...fujitsu.com, jan.kiszka@....de, lethal@...ux-sh.org, jan.kiszka@...mens.com, arjan@...radead.org, prasad@...ux.vnet.ibm.com, mingo@...e.hu, avi@...hat.com Subject: [tip:perf/core] perf/core: Provide a kernel-internal interface to get to performance counters Commit-ID: fb0459d75c1d0a4ba3cafdd2c754e7486968a676 Gitweb: http://git.kernel.org/tip/fb0459d75c1d0a4ba3cafdd2c754e7486968a676 Author: Arjan van de Ven <arjan@...radead.org> AuthorDate: Fri, 25 Sep 2009 12:25:56 +0200 Committer: Frederic Weisbecker <fweisbec@...il.com> CommitDate: Tue, 3 Nov 2009 18:04:17 +0100 perf/core: Provide a kernel-internal interface to get to performance counters There are reasons for kernel code to ask for, and use, performance counters. For example, in CPU freq governors this tends to be a good idea, but there are other examples possible as well of course. This patch adds the needed bits to do enable this functionality; they have been tested in an experimental cpufreq driver that I'm working on, and the changes are all that I needed to access counters properly. [fweisbec@...il.com: added pid to perf_event_create_kernel_counter so that we can profile a particular task too TODO: Have a better error reporting, don't just return NULL in fail case.] v2: Remove the wrong comment about the fact perf_event_create_kernel_counter must be called from a kernel thread. Signed-off-by: Arjan van de Ven <arjan@...ux.intel.com> Acked-by: Peter Zijlstra <peterz@...radead.org> Cc: "K.Prasad" <prasad@...ux.vnet.ibm.com> Cc: Alan Stern <stern@...land.harvard.edu> Cc: Arnaldo Carvalho de Melo <acme@...hat.com> Cc: Steven Rostedt <rostedt@...dmis.org> Cc: Ingo Molnar <mingo@...e.hu> Cc: Jan Kiszka <jan.kiszka@...mens.com> Cc: Jiri Slaby <jirislaby@...il.com> Cc: Li Zefan <lizf@...fujitsu.com> Cc: Avi Kivity <avi@...hat.com> Cc: Paul Mackerras <paulus@...ba.org> Cc: Mike Galbraith <efault@....de> Cc: Masami Hiramatsu <mhiramat@...hat.com> Cc: Paul Mundt <lethal@...ux-sh.org> Cc: Jan Kiszka <jan.kiszka@....de> Cc: Avi Kivity <avi@...hat.com> LKML-Reference: <20090925122556.2f8bd939@...radead.org> Signed-off-by: Frederic Weisbecker <fweisbec@...il.com> --- include/linux/perf_event.h | 6 +++ kernel/perf_event.c | 75 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index df9d964..fa151d4 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -744,6 +744,12 @@ extern int hw_perf_group_sched_in(struct perf_event *group_leader, struct perf_cpu_context *cpuctx, struct perf_event_context *ctx, int cpu); extern void perf_event_update_userpage(struct perf_event *event); +extern int perf_event_release_kernel(struct perf_event *event); +extern struct perf_event * +perf_event_create_kernel_counter(struct perf_event_attr *attr, + int cpu, + pid_t pid); +extern u64 perf_event_read_value(struct perf_event *event); struct perf_sample_data { u64 type; diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 12b5ec3..02d4ff0 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -1725,6 +1725,26 @@ static int perf_release(struct inode *inode, struct file *file) return 0; } +int perf_event_release_kernel(struct perf_event *event) +{ + struct perf_event_context *ctx = event->ctx; + + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + perf_event_remove_from_context(event); + mutex_unlock(&ctx->mutex); + + mutex_lock(&event->owner->perf_event_mutex); + list_del_init(&event->owner_entry); + mutex_unlock(&event->owner->perf_event_mutex); + put_task_struct(event->owner); + + free_event(event); + + return 0; +} +EXPORT_SYMBOL_GPL(perf_event_release_kernel); + static int perf_event_read_size(struct perf_event *event) { int entry = sizeof(u64); /* value */ @@ -1750,7 +1770,7 @@ static int perf_event_read_size(struct perf_event *event) return size; } -static u64 perf_event_read_value(struct perf_event *event) +u64 perf_event_read_value(struct perf_event *event) { struct perf_event *child; u64 total = 0; @@ -1761,6 +1781,7 @@ static u64 perf_event_read_value(struct perf_event *event) return total; } +EXPORT_SYMBOL_GPL(perf_event_read_value); static int perf_event_read_entry(struct perf_event *event, u64 read_format, char __user *buf) @@ -4638,6 +4659,58 @@ err_put_context: return err; } +/** + * perf_event_create_kernel_counter + * + * @attr: attributes of the counter to create + * @cpu: cpu in which the counter is bound + * @pid: task to profile + */ +struct perf_event * +perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, + pid_t pid) +{ + struct perf_event *event; + struct perf_event_context *ctx; + int err; + + /* + * Get the target context (task or percpu): + */ + + ctx = find_get_context(pid, cpu); + if (IS_ERR(ctx)) + return NULL ; + + event = perf_event_alloc(attr, cpu, ctx, NULL, + NULL, GFP_KERNEL); + err = PTR_ERR(event); + if (IS_ERR(event)) + goto err_put_context; + + event->filp = NULL; + WARN_ON_ONCE(ctx->parent_ctx); + mutex_lock(&ctx->mutex); + perf_install_in_context(ctx, event, cpu); + ++ctx->generation; + mutex_unlock(&ctx->mutex); + + event->owner = current; + get_task_struct(current); + mutex_lock(¤t->perf_event_mutex); + list_add_tail(&event->owner_entry, ¤t->perf_event_list); + mutex_unlock(¤t->perf_event_mutex); + + return event; + +err_put_context: + if (err < 0) + put_ctx(ctx); + + return NULL; +} +EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); + /* * inherit a event from parent task to child task: */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists