tickless kernel works with PIT+TSC on the OLPC boards (2.6.20-rc1-rt4)

Marcelo Tosatti marcelo at kvack.org
Mon Dec 25 19:01:01 EST 2006


Hi,

2.6.20-rc1-rt4 works on the Geode with the PIT on aperiodic mode
(CONFIG_NO_HZ, aka tickless).

Thomas disabled usage of the TSC as a clock source for high resolution
timers on the mainline kernel because of:

1) frequency scaling 
2) TSC stops counting when CPU is halted
3) SMP synchronization issues?

>From what I can tell the Geode can safely use the TSC for highres, since:

1) Does not support frequency scaling, 
2) The TSC _does_ count when the CPU is halted. Furthermore, the Geode
supports a mode called "suspension on halt", where Suspend mode (which
interacts with the power management states) is entered. TSC counting
during suspend mode is controlled by bit 8 of the Bus Controller
Configuration Register #0 (thanks Tom!).
3) no SMP :)

So the attached patch on top of 2.6.20-rc1-rt4 checks if "RTSC counts
during suspension", enabling the "is_continuous" flag required by the
highres timers subsystem. Comments?

Running a kernel with CONFIG_HZ=100, runlevel 3, I see an average of 50
timer interrupts per second. 

There's a bunch of badly behaving timers which should be
investigated/tuned (note that this is not a realistic workload). dhcdbd
and some still unknown continuous USB URB submission show as the top
offenders (along with the framebuffer console cursor, which should not
show up on real scenarios).

-bash-3.1# echo 1 > timer_stats ; sleep 5s ; cat timer_stats
Timer Stats Version: v0.1
Sample period: 5.014 s
   2,     0 swapper          hrtimer_restart_sched_tick (hrtimer_sched_tick)
  25,     1 swapper          fbcon_add_cursor_timer (cursor_timer_handler)
  84,     0 swapper          hrtimer_stop_sched_tick (hrtimer_sched_tick)
  24,   935 dhcdbd           schedule_timeout (process_timeout)
  19,     1 swapper          usb_hcd_submit_urb (rh_timer_func)
   5,     1 swapper          init_tsc_clocksource (verify_tsc_freq)
   1,     1 init             schedule_timeout (process_timeout)
   2,     1 swapper          schedule_delayed_work_on (delayed_work_timer_fn)
   1,     1 swapper          neigh_table_init_no_netlink (neigh_periodic_timer)
   1,     0 swapper          page_writeback_init (wb_timer_fn)
   1,  1128 sleep            do_nanosleep (hrtimer_wakeup)
165 total events, 33.32 events/sec

format: nr_events	pid taskname	setupfn (handlerfn)

Thomas, great work! 

--- ./arch/i386/kernel/tsc.c.orig	2006-12-25 20:28:15.000000000 -0200
+++ ./arch/i386/kernel/tsc.c	2006-12-25 21:04:40.000000000 -0200
@@ -16,6 +16,7 @@
 #include <asm/delay.h>
 #include <asm/tsc.h>
 #include <asm/io.h>
+#include <asm/msr.h>
 
 #include "mach_timer.h"
 
@@ -478,6 +479,17 @@
  	return num_possible_cpus() > 1;
 }
 
+static void check_geode_tsc_reliable(void) 
+{
+	unsigned long val;
+
+#define RTSC_SUSP 0x100 /* RTSC counts during suspend */
+
+	rdmsrl(MSR_GEODE_BUSCONT_CONF0, val);
+	if ((val & RTSC_SUSP))
+		clocksource_tsc.is_continuous = 1;
+}
+
 static int __init init_tsc_clocksource(void)
 {
 
@@ -507,6 +519,8 @@
 		if (!pmtmr_ioport || !clocksource_tsc.rating)
 			clocksource_tsc.is_continuous = 0;
 
+		check_geode_tsc_reliable();
+
 		pm_multiplier = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
 
 		init_timer(&verify_tsc_freq_timer);
--- ./include/asm-i386/msr.h.orig	2006-12-25 20:15:34.000000000 -0200
+++ ./include/asm-i386/msr.h	2006-12-25 20:20:44.000000000 -0200
@@ -307,4 +307,7 @@
 #define MSR_CORE_PERF_GLOBAL_CTRL	0x38f
 #define MSR_CORE_PERF_GLOBAL_OVF_CTRL	0x390
 
+/* Geode GX defined MSRs */
+#define MSR_GEODE_BUSCONT_CONF0		0x1900
+
 #endif /* __ASM_MSR_H */



More information about the Devel mailing list