Commit a42548a1 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Ingo Molnar

cputime: Optimize jiffies_to_cputime(1)

For powerpc with CONFIG_VIRT_CPU_ACCOUNTING
jiffies_to_cputime(1) is not compile time constant and run time
calculations are quite expensive. To optimize we use
precomputed value. For all other architectures is is
preprocessor definition.
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
LKML-Reference: <1248862529-6063-5-git-send-email-sgruszka@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent d1e3b6d1
...@@ -30,6 +30,7 @@ typedef u64 cputime_t; ...@@ -30,6 +30,7 @@ typedef u64 cputime_t;
typedef u64 cputime64_t; typedef u64 cputime64_t;
#define cputime_zero ((cputime_t)0) #define cputime_zero ((cputime_t)0)
#define cputime_one_jiffy jiffies_to_cputime(1)
#define cputime_max ((~((cputime_t)0) >> 1) - 1) #define cputime_max ((~((cputime_t)0) >> 1) - 1)
#define cputime_add(__a, __b) ((__a) + (__b)) #define cputime_add(__a, __b) ((__a) + (__b))
#define cputime_sub(__a, __b) ((__a) - (__b)) #define cputime_sub(__a, __b) ((__a) - (__b))
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#ifndef CONFIG_VIRT_CPU_ACCOUNTING #ifndef CONFIG_VIRT_CPU_ACCOUNTING
#include <asm-generic/cputime.h> #include <asm-generic/cputime.h>
#ifdef __KERNEL__
static inline void setup_cputime_one_jiffy(void) { }
#endif
#else #else
#include <linux/types.h> #include <linux/types.h>
...@@ -48,6 +51,11 @@ typedef u64 cputime64_t; ...@@ -48,6 +51,11 @@ typedef u64 cputime64_t;
#ifdef __KERNEL__ #ifdef __KERNEL__
/*
* One jiffy in timebase units computed during initialization
*/
extern cputime_t cputime_one_jiffy;
/* /*
* Convert cputime <-> jiffies * Convert cputime <-> jiffies
*/ */
...@@ -89,6 +97,11 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif) ...@@ -89,6 +97,11 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif)
return ct; return ct;
} }
static inline void setup_cputime_one_jiffy(void)
{
cputime_one_jiffy = jiffies_to_cputime(1);
}
static inline cputime64_t jiffies64_to_cputime64(const u64 jif) static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
{ {
cputime_t ct; cputime_t ct;
......
...@@ -193,6 +193,8 @@ EXPORT_SYMBOL(__cputime_clockt_factor); ...@@ -193,6 +193,8 @@ EXPORT_SYMBOL(__cputime_clockt_factor);
DEFINE_PER_CPU(unsigned long, cputime_last_delta); DEFINE_PER_CPU(unsigned long, cputime_last_delta);
DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta); DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
cputime_t cputime_one_jiffy;
static void calc_cputime_factors(void) static void calc_cputime_factors(void)
{ {
struct div_result res; struct div_result res;
...@@ -500,6 +502,7 @@ static int __init iSeries_tb_recal(void) ...@@ -500,6 +502,7 @@ static int __init iSeries_tb_recal(void)
tb_to_xs = divres.result_low; tb_to_xs = divres.result_low;
vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
vdso_data->tb_to_xs = tb_to_xs; vdso_data->tb_to_xs = tb_to_xs;
setup_cputime_one_jiffy();
} }
else { else {
printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
...@@ -945,6 +948,7 @@ void __init time_init(void) ...@@ -945,6 +948,7 @@ void __init time_init(void)
tb_ticks_per_usec = ppc_tb_freq / 1000000; tb_ticks_per_usec = ppc_tb_freq / 1000000;
tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
calc_cputime_factors(); calc_cputime_factors();
setup_cputime_one_jiffy();
/* /*
* Calculate the length of each tick in ns. It will not be * Calculate the length of each tick in ns. It will not be
......
...@@ -42,6 +42,7 @@ __div(unsigned long long n, unsigned int base) ...@@ -42,6 +42,7 @@ __div(unsigned long long n, unsigned int base)
#endif /* __s390x__ */ #endif /* __s390x__ */
#define cputime_zero (0ULL) #define cputime_zero (0ULL)
#define cputime_one_jiffy jiffies_to_cputime(1)
#define cputime_max ((~0UL >> 1) - 1) #define cputime_max ((~0UL >> 1) - 1)
#define cputime_add(__a, __b) ((__a) + (__b)) #define cputime_add(__a, __b) ((__a) + (__b))
#define cputime_sub(__a, __b) ((__a) - (__b)) #define cputime_sub(__a, __b) ((__a) - (__b))
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
typedef unsigned long cputime_t; typedef unsigned long cputime_t;
#define cputime_zero (0UL) #define cputime_zero (0UL)
#define cputime_one_jiffy jiffies_to_cputime(1)
#define cputime_max ((~0UL >> 1) - 1) #define cputime_max ((~0UL >> 1) - 1)
#define cputime_add(__a, __b) ((__a) + (__b)) #define cputime_add(__a, __b) ((__a) + (__b))
#define cputime_sub(__a, __b) ((__a) - (__b)) #define cputime_sub(__a, __b) ((__a) - (__b))
......
...@@ -64,7 +64,7 @@ static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, ...@@ -64,7 +64,7 @@ static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
if (cputime_le(cval, t)) if (cputime_le(cval, t))
/* about to fire */ /* about to fire */
cval = jiffies_to_cputime(1); cval = cputime_one_jiffy;
else else
cval = cputime_sub(cval, t); cval = cputime_sub(cval, t);
} }
...@@ -161,7 +161,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id, ...@@ -161,7 +161,7 @@ static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
if (!cputime_eq(cval, cputime_zero) || if (!cputime_eq(cval, cputime_zero) ||
!cputime_eq(nval, cputime_zero)) { !cputime_eq(nval, cputime_zero)) {
if (cputime_gt(nval, cputime_zero)) if (cputime_gt(nval, cputime_zero))
nval = cputime_add(nval, jiffies_to_cputime(1)); nval = cputime_add(nval, cputime_one_jiffy);
set_process_cpu_timer(tsk, clock_id, &nval, &cval); set_process_cpu_timer(tsk, clock_id, &nval, &cval);
} }
it->expires = nval; it->expires = nval;
......
...@@ -1086,7 +1086,7 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it, ...@@ -1086,7 +1086,7 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
it->error += it->incr_error; it->error += it->incr_error;
if (it->error >= onecputick) { if (it->error >= onecputick) {
it->expires = cputime_sub(it->expires, it->expires = cputime_sub(it->expires,
jiffies_to_cputime(1)); cputime_one_jiffy);
it->error -= onecputick; it->error -= onecputick;
} }
} else } else
...@@ -1461,7 +1461,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx, ...@@ -1461,7 +1461,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
if (!cputime_eq(*oldval, cputime_zero)) { if (!cputime_eq(*oldval, cputime_zero)) {
if (cputime_le(*oldval, now.cpu)) { if (cputime_le(*oldval, now.cpu)) {
/* Just about to fire. */ /* Just about to fire. */
*oldval = jiffies_to_cputime(1); *oldval = cputime_one_jiffy;
} else { } else {
*oldval = cputime_sub(*oldval, now.cpu); *oldval = cputime_sub(*oldval, now.cpu);
} }
...@@ -1712,7 +1712,7 @@ static __init int init_posix_cpu_timers(void) ...@@ -1712,7 +1712,7 @@ static __init int init_posix_cpu_timers(void)
register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process); register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread); register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread);
cputime_to_timespec(jiffies_to_cputime(1), &ts); cputime_to_timespec(cputime_one_jiffy, &ts);
onecputick = ts.tv_nsec; onecputick = ts.tv_nsec;
WARN_ON(ts.tv_sec != 0); WARN_ON(ts.tv_sec != 0);
......
...@@ -5031,17 +5031,16 @@ void account_idle_time(cputime_t cputime) ...@@ -5031,17 +5031,16 @@ void account_idle_time(cputime_t cputime)
*/ */
void account_process_tick(struct task_struct *p, int user_tick) void account_process_tick(struct task_struct *p, int user_tick)
{ {
cputime_t one_jiffy = jiffies_to_cputime(1); cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy);
cputime_t one_jiffy_scaled = cputime_to_scaled(one_jiffy);
struct rq *rq = this_rq(); struct rq *rq = this_rq();
if (user_tick) if (user_tick)
account_user_time(p, one_jiffy, one_jiffy_scaled); account_user_time(p, cputime_one_jiffy, one_jiffy_scaled);
else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET))
account_system_time(p, HARDIRQ_OFFSET, one_jiffy, account_system_time(p, HARDIRQ_OFFSET, cputime_one_jiffy,
one_jiffy_scaled); one_jiffy_scaled);
else else
account_idle_time(one_jiffy); account_idle_time(cputime_one_jiffy);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment