Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169691
b: refs/heads/master
c: fb0459d
h: refs/heads/master
i:
  169689: 0647e1f
  169687: cadaa5b
v: v3
  • Loading branch information
Arjan van de Ven authored and Frederic Weisbecker committed Nov 3, 2009
1 parent a61f520 commit 91cc679
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f8f86c7bdd1c954fbe153af437a0d91a6c5721a
refs/heads/master: fb0459d75c1d0a4ba3cafdd2c754e7486968a676
6 changes: 6 additions & 0 deletions trunk/include/linux/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
75 changes: 74 additions & 1 deletion trunk/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -4638,6 +4659,58 @@ SYSCALL_DEFINE5(perf_event_open,
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(&current->perf_event_mutex);
list_add_tail(&event->owner_entry, &current->perf_event_list);
mutex_unlock(&current->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:
*/
Expand Down

0 comments on commit 91cc679

Please sign in to comment.