Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 147328
b: refs/heads/master
c: f6c7d5f
h: refs/heads/master
v: v3
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Apr 7, 2009
1 parent db52352 commit f3d1d36
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 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: b6276f353bf490add62dcf7db0ebd75baa3e1a37
refs/heads/master: f6c7d5fe58b4846ee0cb4b98b6042489705eced4
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/kernel/perf_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ static void record_and_restart(struct perf_counter *counter, long val,
* Finally record data if requested.
*/
if (record)
perf_counter_output(counter, 1, regs);
perf_counter_overflow(counter, 1, regs);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/x86/kernel/cpu/perf_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,8 @@ static int __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi)
continue;

perf_save_and_restart(counter);
perf_counter_output(counter, nmi, regs);
if (perf_counter_overflow(counter, nmi, regs))
__pmc_generic_disable(counter, &counter->hw, bit);
}

hw_perf_ack_status(ack);
Expand Down
4 changes: 2 additions & 2 deletions trunk/include/linux/perf_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,8 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader,
struct perf_counter_context *ctx, int cpu);
extern void perf_counter_update_userpage(struct perf_counter *counter);

extern void perf_counter_output(struct perf_counter *counter,
int nmi, struct pt_regs *regs);
extern int perf_counter_overflow(struct perf_counter *counter,
int nmi, struct pt_regs *regs);
/*
* Return 1 for a software counter, 0 for a hardware counter
*/
Expand Down
29 changes: 23 additions & 6 deletions trunk/kernel/perf_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1800,8 +1800,8 @@ static void perf_output_end(struct perf_output_handle *handle)
rcu_read_unlock();
}

void perf_counter_output(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
static void perf_counter_output(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
{
int ret;
u64 record_type = counter->hw_event.record_type;
Expand Down Expand Up @@ -2033,6 +2033,17 @@ void perf_counter_munmap(unsigned long addr, unsigned long len,
perf_counter_mmap_event(&mmap_event);
}

/*
* Generic counter overflow handling.
*/

int perf_counter_overflow(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
{
perf_counter_output(counter, nmi, regs);
return 0;
}

/*
* Generic software counter infrastructure
*/
Expand Down Expand Up @@ -2077,6 +2088,7 @@ static void perf_swcounter_set_period(struct perf_counter *counter)

static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
{
enum hrtimer_restart ret = HRTIMER_RESTART;
struct perf_counter *counter;
struct pt_regs *regs;

Expand All @@ -2092,20 +2104,25 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
!counter->hw_event.exclude_user)
regs = task_pt_regs(current);

if (regs)
perf_counter_output(counter, 0, regs);
if (regs) {
if (perf_counter_overflow(counter, 0, regs))
ret = HRTIMER_NORESTART;
}

hrtimer_forward_now(hrtimer, ns_to_ktime(counter->hw.irq_period));

return HRTIMER_RESTART;
return ret;
}

static void perf_swcounter_overflow(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
{
perf_swcounter_update(counter);
perf_swcounter_set_period(counter);
perf_counter_output(counter, nmi, regs);
if (perf_counter_overflow(counter, nmi, regs))
/* soft-disable the counter */
;

}

static int perf_swcounter_match(struct perf_counter *counter,
Expand Down

0 comments on commit f3d1d36

Please sign in to comment.