2009-04-06 09:48:54

by Peter Zijlstra

[permalink] [raw]
Subject: [PATCH 13/15] perf_counter: rework the task clock software counter

Rework the task clock software counter to use the context time instead
of the task runtime clock, this removes the last such user.

Signed-off-by: Peter Zijlstra <[email protected]>
---
kernel/perf_counter.c | 42 ++++++++++++------------------------------
1 file changed, 12 insertions(+), 30 deletions(-)

Index: linux-2.6/kernel/perf_counter.c
===================================================================
--- linux-2.6.orig/kernel/perf_counter.c
+++ linux-2.6/kernel/perf_counter.c
@@ -974,9 +974,6 @@ int perf_counter_task_disable(void)
curr_rq_lock_irq_save(&flags);
cpu = smp_processor_id();

- /* force the update of the task clock: */
- __task_delta_exec(curr, 1);
-
perf_counter_task_sched_out(curr, cpu);

spin_lock(&ctx->lock);
@@ -1017,9 +1014,6 @@ int perf_counter_task_enable(void)
curr_rq_lock_irq_save(&flags);
cpu = smp_processor_id();

- /* force the update of the task clock: */
- __task_delta_exec(curr, 1);
-
perf_counter_task_sched_out(curr, cpu);

spin_lock(&ctx->lock);
@@ -2347,38 +2341,28 @@ static const struct hw_perf_counter_ops
* Software counter: task time clock
*/

-/*
- * Called from within the scheduler:
- */
-static u64 task_clock_perf_counter_val(struct perf_counter *counter, int update)
-{
- struct task_struct *curr = counter->task;
- u64 delta;
-
- delta = __task_delta_exec(curr, update);
-
- return curr->se.sum_exec_runtime + delta;
-}
-
-static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now)
+static void task_clock_perf_counter_update(struct perf_counter *counter)
{
- u64 prev;
+ u64 prev, now;
s64 delta;

- prev = atomic64_read(&counter->hw.prev_count);
-
- atomic64_set(&counter->hw.prev_count, now);
+ update_context_time(counter->ctx);
+ now = counter->ctx->time;

+ prev = atomic64_xchg(&counter->hw.prev_count, now);
delta = now - prev;
-
atomic64_add(delta, &counter->count);
}

static int task_clock_perf_counter_enable(struct perf_counter *counter)
{
struct hw_perf_counter *hwc = &counter->hw;
+ u64 now;
+
+ update_context_time(counter->ctx);
+ now = counter->ctx->time;

- atomic64_set(&hwc->prev_count, task_clock_perf_counter_val(counter, 0));
+ atomic64_set(&hwc->prev_count, now);
hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hwc->hrtimer.function = perf_swcounter_hrtimer;
if (hwc->irq_period) {
@@ -2393,14 +2377,12 @@ static int task_clock_perf_counter_enabl
static void task_clock_perf_counter_disable(struct perf_counter *counter)
{
hrtimer_cancel(&counter->hw.hrtimer);
- task_clock_perf_counter_update(counter,
- task_clock_perf_counter_val(counter, 0));
+ task_clock_perf_counter_update(counter);
}

static void task_clock_perf_counter_read(struct perf_counter *counter)
{
- task_clock_perf_counter_update(counter,
- task_clock_perf_counter_val(counter, 1));
+ task_clock_perf_counter_update(counter);
}

static const struct hw_perf_counter_ops perf_ops_task_clock = {

--


2009-04-07 09:11:57

by Peter Zijlstra

[permalink] [raw]
Subject: [tip:perfcounters/core] perf_counter: rework the task clock software counter

Commit-ID: a39d6f2556c4a19f58f538c6aa28bf8faca4fcb8
Gitweb: http://git.kernel.org/tip/a39d6f2556c4a19f58f538c6aa28bf8faca4fcb8
Author: Peter Zijlstra <[email protected]>
AuthorDate: Mon, 6 Apr 2009 11:45:11 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 7 Apr 2009 10:49:00 +0200

perf_counter: rework the task clock software counter

Rework the task clock software counter to use the context time instead
of the task runtime clock, this removes the last such user.

Signed-off-by: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Corey Ashford <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
kernel/perf_counter.c | 42 ++++++++++++------------------------------
1 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 84d85ab..56b7eb5 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -974,9 +974,6 @@ int perf_counter_task_disable(void)
curr_rq_lock_irq_save(&flags);
cpu = smp_processor_id();

- /* force the update of the task clock: */
- __task_delta_exec(curr, 1);
-
perf_counter_task_sched_out(curr, cpu);

spin_lock(&ctx->lock);
@@ -1017,9 +1014,6 @@ int perf_counter_task_enable(void)
curr_rq_lock_irq_save(&flags);
cpu = smp_processor_id();

- /* force the update of the task clock: */
- __task_delta_exec(curr, 1);
-
perf_counter_task_sched_out(curr, cpu);

spin_lock(&ctx->lock);
@@ -2347,38 +2341,28 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = {
* Software counter: task time clock
*/

-/*
- * Called from within the scheduler:
- */
-static u64 task_clock_perf_counter_val(struct perf_counter *counter, int update)
-{
- struct task_struct *curr = counter->task;
- u64 delta;
-
- delta = __task_delta_exec(curr, update);
-
- return curr->se.sum_exec_runtime + delta;
-}
-
-static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now)
+static void task_clock_perf_counter_update(struct perf_counter *counter)
{
- u64 prev;
+ u64 prev, now;
s64 delta;

- prev = atomic64_read(&counter->hw.prev_count);
-
- atomic64_set(&counter->hw.prev_count, now);
+ update_context_time(counter->ctx);
+ now = counter->ctx->time;

+ prev = atomic64_xchg(&counter->hw.prev_count, now);
delta = now - prev;
-
atomic64_add(delta, &counter->count);
}

static int task_clock_perf_counter_enable(struct perf_counter *counter)
{
struct hw_perf_counter *hwc = &counter->hw;
+ u64 now;
+
+ update_context_time(counter->ctx);
+ now = counter->ctx->time;

- atomic64_set(&hwc->prev_count, task_clock_perf_counter_val(counter, 0));
+ atomic64_set(&hwc->prev_count, now);
hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hwc->hrtimer.function = perf_swcounter_hrtimer;
if (hwc->irq_period) {
@@ -2393,14 +2377,12 @@ static int task_clock_perf_counter_enable(struct perf_counter *counter)
static void task_clock_perf_counter_disable(struct perf_counter *counter)
{
hrtimer_cancel(&counter->hw.hrtimer);
- task_clock_perf_counter_update(counter,
- task_clock_perf_counter_val(counter, 0));
+ task_clock_perf_counter_update(counter);
}

static void task_clock_perf_counter_read(struct perf_counter *counter)
{
- task_clock_perf_counter_update(counter,
- task_clock_perf_counter_val(counter, 1));
+ task_clock_perf_counter_update(counter);
}

static const struct hw_perf_counter_ops perf_ops_task_clock = {

2009-04-07 09:37:39

by Ingo Molnar

[permalink] [raw]
Subject: [tip:perfcounters/core] x86, perfcounters: add atomic64_xchg()

Commit-ID: b226fa12991d6ee9b6b13a7e1de88ec5d25f5007
Gitweb: http://git.kernel.org/tip/b226fa12991d6ee9b6b13a7e1de88ec5d25f5007
Author: Ingo Molnar <[email protected]>
AuthorDate: Tue, 7 Apr 2009 11:30:17 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 7 Apr 2009 11:32:43 +0200

x86, perfcounters: add atomic64_xchg()

Complete atomic64_t support on the 32-bit side by adding atomic64_xch().

Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
arch/x86/include/asm/atomic_32.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
index 977250e..a9fef6c 100644
--- a/arch/x86/include/asm/atomic_32.h
+++ b/arch/x86/include/asm/atomic_32.h
@@ -306,6 +306,12 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
} while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
}

+static inline void
+atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
+{
+ atomic64_set(ptr, new_val);
+}
+
/**
* atomic64_read - read atomic64 variable
* @ptr: pointer to type atomic64_t

2009-04-07 10:08:32

by Ingo Molnar

[permalink] [raw]
Subject: [tip:perfcounters/core] x86, perfcounters: add atomic64_xchg()

Commit-ID: 98c2aaf8be5baf7193be37fb28bce8e7327158bc
Gitweb: http://git.kernel.org/tip/98c2aaf8be5baf7193be37fb28bce8e7327158bc
Author: Ingo Molnar <[email protected]>
AuthorDate: Tue, 7 Apr 2009 11:30:17 +0200
Committer: Ingo Molnar <[email protected]>
CommitDate: Tue, 7 Apr 2009 12:02:41 +0200

x86, perfcounters: add atomic64_xchg()

Complete atomic64_t support on the 32-bit side by adding atomic64_xch().

Cc: Peter Zijlstra <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>


---
arch/x86/include/asm/atomic_32.h | 24 +++++++++++++++++++++---
1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
index 977250e..aff9f1f 100644
--- a/arch/x86/include/asm/atomic_32.h
+++ b/arch/x86/include/asm/atomic_32.h
@@ -291,19 +291,37 @@ atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val,
}

/**
- * atomic64_set - set atomic64 variable
+ * atomic64_xchg - xchg atomic64 variable
* @ptr: pointer to type atomic64_t
* @new_val: value to assign
+ * @old_val: old value that was there
*
- * Atomically sets the value of @ptr to @new_val.
+ * Atomically xchgs the value of @ptr to @new_val and returns
+ * the old value.
*/
-static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
+
+static inline unsigned long long
+atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
{
unsigned long long old_val;

do {
old_val = atomic_read(ptr);
} while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
+
+ return old_val;
+}
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
+ *
+ * Atomically sets the value of @ptr to @new_val.
+ */
+static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
+{
+ atomic64_xchg(ptr, new_val);
}

/**

2009-04-07 11:19:57

by Paul Mackerras

[permalink] [raw]
Subject: Re: [tip:perfcounters/core] x86, perfcounters: add atomic64_xchg()

Ingo Molnar writes:

> Complete atomic64_t support on the 32-bit side by adding atomic64_xch().
>
> Cc: Peter Zijlstra <[email protected]>
> LKML-Reference: <[email protected]>
> Signed-off-by: Ingo Molnar <[email protected]>
>
>
> ---
> arch/x86/include/asm/atomic_32.h | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
> index 977250e..a9fef6c 100644
> --- a/arch/x86/include/asm/atomic_32.h
> +++ b/arch/x86/include/asm/atomic_32.h
> @@ -306,6 +306,12 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
> } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
> }
>
> +static inline void
> +atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
> +{
> + atomic64_set(ptr, new_val);
> +}

Umm, I don't know much about x86, but that doesn't look like an
exchange operation to me... Shouldn't it return a value, for a start?

Paul.

2009-04-07 13:28:50

by Ingo Molnar

[permalink] [raw]
Subject: Re: [tip:perfcounters/core] x86, perfcounters: add atomic64_xchg()


* Paul Mackerras <[email protected]> wrote:

> Ingo Molnar writes:
>
> > Complete atomic64_t support on the 32-bit side by adding atomic64_xch().
> >
> > Cc: Peter Zijlstra <[email protected]>
> > LKML-Reference: <[email protected]>
> > Signed-off-by: Ingo Molnar <[email protected]>
> >
> >
> > ---
> > arch/x86/include/asm/atomic_32.h | 6 ++++++
> > 1 files changed, 6 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
> > index 977250e..a9fef6c 100644
> > --- a/arch/x86/include/asm/atomic_32.h
> > +++ b/arch/x86/include/asm/atomic_32.h
> > @@ -306,6 +306,12 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
> > } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
> > }
> >
> > +static inline void
> > +atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
> > +{
> > + atomic64_set(ptr, new_val);
> > +}
>
> Umm, I don't know much about x86, but that doesn't look like an
> exchange operation to me... Shouldn't it return a value, for a
> start?

Yes, indeed :) Fixed it.

/me officially loves commit notifications

Ingo