From patchwork Mon May 4 08:02:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mason X-Patchwork-Id: 6323631 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D84C59F32B for ; Mon, 4 May 2015 08:05:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A6A9B202D1 for ; Mon, 4 May 2015 08:05:23 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2F26A202A1 for ; Mon, 4 May 2015 08:05:22 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YpBLQ-0005f8-PN; Mon, 04 May 2015 08:03:16 +0000 Received: from smtp2-g21.free.fr ([2a01:e0c:1:1599::11]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YpBLM-0005WM-AT for linux-arm-kernel@lists.infradead.org; Mon, 04 May 2015 08:03:14 +0000 Received: from [172.27.0.114] (unknown [83.142.147.193]) (Authenticated sender: shill) by smtp2-g21.free.fr (Postfix) with ESMTPSA id E6BCF4B02BA; Mon, 4 May 2015 10:02:08 +0200 (CEST) Message-ID: <554727A0.3040601@free.fr> Date: Mon, 04 May 2015 10:02:40 +0200 From: Mason User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0 SeaMonkey/2.32.1 MIME-Version: 1.0 To: Linux ARM Subject: High-resolution timers not supported when using smp_twd on Cortex A9 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150504_010312_694097_9804D411 X-CRM114-Status: GOOD ( 14.12 ) X-Spam-Score: -0.7 (/) Cc: Catalin Marinas , Thomas Gleixner , John Stultz , Santosh Shilimkar X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP [ Resending to LAKML, add clocksource description ] Hello, I wanted to enable high-resolution timers on this Cortex A9 system, but it seems there is more to it than just enabling CONFIG_HIGH_RES_TIMERS=y (The system is limited to jiffy resolution.) # # Timers subsystem # CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ_COMMON=y # CONFIG_HZ_PERIODIC is not set CONFIG_NO_HZ_IDLE=y # CONFIG_NO_HZ_FULL is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_HZ=300 /proc/timer_list output attached I'm using the TWD block (private timer and watchdog) for clock events. Registered with twd_local_timer_register(&tangox_twd); "4.1 About the private timer and watchdog blocks The private timer and watchdog blocks have the following features: - a 32-bit counter that generates an interrupt when it reaches zero - an eight-bit prescaler value to qualify the clock period - configurable single-shot or auto-reload modes - configurable starting values for the counter - the clock for these blocks is PERIPHCLK." arch/arm/kernel/smp_twd.c http://elinux.org/High_Resolution_Timers states > 2. Check the event_handler for the Tick Device. If the event handlers > is 'hrtimer_interrupt' then the clock is set up for high resolution > handling. If the event handler is 'tick_handle_periodic', then the > device is set up for regular tick-based handling. And indeed: Tick Device: mode: 0 Per CPU device: 0 Clock Event Device: local_timer max_delta_ns: 8598533124 min_delta_ns: 1000 mult: 2145336164 shift: 32 mode: 2 next_event: 9223372036854775807 nsecs set_next_event: twd_set_next_event set_mode: twd_set_mode event_handler: tick_handle_periodic retries: 0 clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; clk->rating = 350; clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event; clk->irq = twd_ppi; clk->cpumask = cpumask_of(cpu); /* * x86(64) specific misfeatures: * * - Clockevent source stops in C3 State and needs broadcast support. */ #define CLOCK_EVT_FEAT_C3STOP 0x000008 $ git show 5388a6b2 arch/arm/kernel/smp_twd.c commit 5388a6b266e9c3357353332ba0cd5549082887f1 Author: Russell King Date: Mon Jul 26 13:19:43 2010 +0100 ARM: SMP: Always enable clock event broadcast support The TWD local timers are unable to wake up the CPU when it is placed into a low power mode, eg. C3. Therefore, we need to adapt things such that the TWD code can cope with this. We do this by always providing a broadcast tick function, and marking the fact that the TWD local timer will stop in low power modes. This means that when the CPU is placed into a low power mode, the core timer code marks this fact, and allows an IPI to be given to the core. Tested-by: Santosh Shilimkar Signed-off-by: Russell King Cc: Catalin Marinas Cc: Thomas Gleixner (The system's clocksource is a 27 MHz 32-bit counter.) If I remove the CLOCK_EVT_FEAT_C3STOP flag, then hrtimers are enabled, but I assume I would then run into problems in low-power mode, going by Russell's commit message. Do I have to use a platform-specific clockevent source if I want high-resolution timers on the system? Regards. Timer List Version: v0.7 HRTIMER_MAX_CLOCK_BASES: 4 now at 12676030854 nsecs cpu: 0 clock 0: .base: e7ae51e8 .index: 0 .resolution: 3333333 nsecs .get_time: ktime_get .offset: 0 nsecs active timers: #0: sched_clock_timer, sched_clock_poll, S:01 # expires at 139188754399-139188754399 nsecs [in 126512723545 to 126512723545 nsecs] clock 1: .base: e7ae5220 .index: 1 .resolution: 3333333 nsecs .get_time: ktime_get_real .offset: 0 nsecs active timers: clock 2: .base: e7ae5258 .index: 2 .resolution: 3333333 nsecs .get_time: ktime_get_boottime .offset: 0 nsecs active timers: clock 3: .base: e7ae5290 .index: 3 .resolution: 3333333 nsecs .get_time: ktime_get_clocktai .offset: 0 nsecs active timers: .expires_next : 9223372036854775807 nsecs .hres_active : 0 .nr_events : 0 .nr_retries : 0 .nr_hangs : 0 .max_hang_time : 0 nsecs .nohz_mode : 0 .last_tick : 0 nsecs .tick_stopped : 0 .idle_jiffies : 0 .idle_calls : 0 .idle_sleeps : 0 .idle_entrytime : 12674854298 nsecs .idle_waketime : 0 nsecs .idle_exittime : 0 nsecs .idle_sleeptime : 10273031792 nsecs .iowait_sleeptime: 10232749 nsecs .last_jiffies : 0 .next_jiffies : 0 .idle_expires : 0 nsecs jiffies: 4294880982 cpu: 1 clock 0: .base: e7aed1e8 .index: 0 .resolution: 3333333 nsecs .get_time: ktime_get .offset: 0 nsecs active timers: clock 1: .base: e7aed220 .index: 1 .resolution: 3333333 nsecs .get_time: ktime_get_real .offset: 0 nsecs active timers: clock 2: .base: e7aed258 .index: 2 .resolution: 3333333 nsecs .get_time: ktime_get_boottime .offset: 0 nsecs active timers: clock 3: .base: e7aed290 .index: 3 .resolution: 3333333 nsecs .get_time: ktime_get_clocktai .offset: 0 nsecs active timers: .expires_next : 9223372036854775807 nsecs .hres_active : 0 .nr_events : 0 .nr_retries : 0 .nr_hangs : 0 .max_hang_time : 0 nsecs .nohz_mode : 0 .last_tick : 0 nsecs .tick_stopped : 0 .idle_jiffies : 0 .idle_calls : 0 .idle_sleeps : 0 .idle_entrytime : 12673422372 nsecs .idle_waketime : 0 nsecs .idle_exittime : 0 nsecs .idle_sleeptime : 12455789892 nsecs .iowait_sleeptime: 15649739 nsecs .last_jiffies : 0 .next_jiffies : 0 .idle_expires : 0 nsecs jiffies: 4294880982 Tick Device: mode: 0 Broadcast device Clock Event Device: tick_broadcast_mask: 00000000 tick_broadcast_oneshot_mask: 00000000 Tick Device: mode: 0 Per CPU device: 0 Clock Event Device: local_timer max_delta_ns: 8598533124 min_delta_ns: 1000 mult: 2145336164 shift: 32 mode: 2 next_event: 9223372036854775807 nsecs set_next_event: twd_set_next_event set_mode: twd_set_mode event_handler: tick_handle_periodic retries: 0 Tick Device: mode: 0 Per CPU device: 1 Clock Event Device: local_timer max_delta_ns: 8598533124 min_delta_ns: 1000 mult: 2145336164 shift: 32 mode: 2 next_event: 9223372036854775807 nsecs set_next_event: twd_set_next_event set_mode: twd_set_mode event_handler: tick_handle_periodic retries: 0 diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 7c5f0c0..35882fb 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -132,7 +132,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) twd_calibrate_rate(); clk->name = "local_timer"; - clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_C3STOP; clk->rating = 350; clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event;