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