Re: [PATCH] simplify update_times (avoid jiffies/jiffies_64aliasing problem)

From: Atsushi Nemoto
Date: Thu Mar 02 2006 - 21:42:23 EST


>>>>> On Thu, 2 Mar 2006 11:09:16 -0800 (PST), Christoph Lameter <clameter@xxxxxxxxxxxx> said:
>> In kernel 2.6, update_times() is called directly in timer
>> interrupt, so there is no point calculating ticks here. This also
>> get rid of difference of jiffies and jiffies_64 due to compiler's
>> optimization (which was reported previously with subject
>> "jiffies_64 vs. jiffies").

clameter> If update_wall_time() and calc_load() are always called with
clameter> the constant one then you may be able to optimize these two
clameter> functions as well.

Sure. I tried to do only one thing at a time, but it might be better
to clean them up together. Patch revised.


In kernel 2.6, update_times() is called directly in timer interrupt,
so there is no point calculating ticks here. Then update_wall_time()
and calc_load() can also be optimized. This also get rid of
difference of jiffies and jiffies_64 due to compiler's optimization
(which was reported previously with subject "jiffies_64 vs. jiffies").

Also adjust x86_64 timer interrupt handler with this change.

Signed-off-by: Atsushi Nemoto <anemo@xxxxxxxxxxxxx>

diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 3080f84..7a1d790 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -423,7 +423,8 @@ void main_timer_handler(struct pt_regs *

if (lost > 0) {
handle_lost_ticks(lost, regs);
- jiffies += lost;
+ while (lost--)
+ do_timer(regs);
}

/*
diff --git a/kernel/timer.c b/kernel/timer.c
index fc6646f..54544a7 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -787,24 +787,14 @@ u64 current_tick_length(void)
return ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj;
}

-/*
- * Using a loop looks inefficient, but "ticks" is
- * usually just one (we shouldn't be losing ticks,
- * we're doing this this way mainly for interrupt
- * latency reasons, not because we think we'll
- * have lots of lost timer ticks
- */
-static void update_wall_time(unsigned long ticks)
+static void update_wall_time(void)
{
- do {
- ticks--;
- update_wall_time_one_tick();
- if (xtime.tv_nsec >= 1000000000) {
- xtime.tv_nsec -= 1000000000;
- xtime.tv_sec++;
- second_overflow();
- }
- } while (ticks);
+ update_wall_time_one_tick();
+ if (xtime.tv_nsec >= 1000000000) {
+ xtime.tv_nsec -= 1000000000;
+ xtime.tv_sec++;
+ second_overflow();
+ }
}

/*
@@ -849,15 +839,15 @@ unsigned long avenrun[3];
EXPORT_SYMBOL(avenrun);

/*
- * calc_load - given tick count, update the avenrun load estimates.
+ * calc_load - update the avenrun load estimates.
* This is called while holding a write_lock on xtime_lock.
*/
-static inline void calc_load(unsigned long ticks)
+static inline void calc_load(void)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;

- count -= ticks;
+ count--;
if (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
@@ -906,14 +896,9 @@ void run_local_timers(void)
*/
static inline void update_times(void)
{
- unsigned long ticks;
-
- ticks = jiffies - wall_jiffies;
- if (ticks) {
- wall_jiffies += ticks;
- update_wall_time(ticks);
- }
- calc_load(ticks);
+ wall_jiffies++;
+ update_wall_time();
+ calc_load();
}

/*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/