Hello, First of all, altough I added Patch in the subject and post it here, I don't think that this patch should be applied to rt tree... Read the rest of the email to see why... On my ARM SoC with a marvell orion chip I get weird cpu usage values in top when I load my kernel module (different processes shows very high cpu usage). My kernel module sends ethernet frames every 200us. Therefor I use hrtimers and send this network frames in the callback method of the timer. I use 2.6.29.1-rt9. All the involved processes (IRQ-21 (irq of the network interface), sirq-net-rx, sirq-hrtimer) gets randomly high cpu usage. Sometimes I get no cpu usage at all. Its different each time I load my module. Sometimes IRQ-21 gets high cpu load, sometimes sirq-net-rx... Load average seems to show realistic values (~0.6). This have a unpleasant side effect: Due to the limited runtime for rt tasks (in /proc/sys/kernel/sched_rt_runtime_us), i get a delay of 50ms once every second. When i disable the limit (echo -1 >/proc/sys/kernel/sched_rt_runtime_us) i don't get this delay. However, it would be great if the cpu usage per process would be fixed anyway.... Therefor I implemented a sched_clock implementation for my orion platform (see attached patch). I tested the values that sched_clock returns, it should be ok! But it still doesn't work... Any ideas? Thanks Stefan aka falstaff
From 9ab3c6030dc01ffe4065c334cac1a07c0ff6af5d Mon Sep 17 00:00:00 2001 From: Stefan Agner <stefan.agner@xxxxxxxxx> Date: Mon, 27 Apr 2009 11:11:18 +0200 Subject: [PATCH] sched_clock implementation for orion platforms --- arch/arm/plat-orion/time.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 6fa2923..f873f67 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -17,6 +17,8 @@ #include <linux/irq.h> #include <asm/mach/time.h> #include <mach/hardware.h> +#include <linux/sched.h> +#include <linux/cnt32_to_63.h> /* * Number of timer ticks per jiffy. @@ -39,6 +41,35 @@ static u32 ticks_per_jiffy; /* + * Orion's sched_clock implementation. It has a resolution + * of at least 7.5ns (133MHz TCLK) and a maximum value of + * 32 seconds. + */ +#define ORIONCLK2NS_SCALE_FACTOR 20 + +static unsigned long orion2ns_scale; + +static void __init set_orion2ns_scale(unsigned long orion_rate) +{ + unsigned long long v = ((unsigned long long)NSEC_PER_SEC) << ORIONCLK2NS_SCALE_FACTOR; + do_div(v, orion_rate); + /* + * We want an even value to automatically clear the top bit + * returned by cnt32_to_63() without an additional run time + * instruction. So if the LSB is 1 then round it up. + */ + if(v & 1) + v++; + orion2ns_scale = v; +} + +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(0xffffffff - readl(TIMER0_VAL)); + return (v * orion2ns_scale) >> ORIONCLK2NS_SCALE_FACTOR; +} + +/* * Clocksource handling. */ static cycle_t orion_clksrc_read(void) @@ -176,6 +207,10 @@ void __init orion_time_init(unsigned int irq, unsigned int tclk) ticks_per_jiffy = (tclk + HZ/2) / HZ; + /* + * Set scale for sched_clock + */ + set_orion2ns_scale(tclk); /* * Setup free-running clocksource timer (interrupts -- 1.5.6.3