From patchwork Fri Mar 27 17:14:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 46431 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f72.google.com (mail-wg0-f72.google.com [74.125.82.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D5F5521585 for ; Fri, 27 Mar 2015 17:16:00 +0000 (UTC) Received: by wgfh4 with SMTP id h4sf12315897wgf.1 for ; Fri, 27 Mar 2015 10:16:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=CMM8KprD8wBUsHdUUSRH93I0kaahX6De2dAdqt7E5E4=; b=IQqOKM6TdBc6TYd1qwU2d2uN6f8sp/dyfiGYXG8plOM8j4KY5DLST0yD2T7OZQRfVY dv9W2QrxYj0L39QEQPxFPmOlGJXzGM8J995gely+vXl9+dTRCRpXhhaTGhnXYAOttS0g n6qfc2sFVGV9hDplVzT7pqAlKGNBKXhPXOFdLCBlrOpPdPVu9LoEwmSV65yi6/MyHzfs WDrC3/hD85Lagx8WezyVIU2i5KVlMxafZCtkOa+ZOIJXw22M5bnW1lWpZYz/Pk6g4x3B YJiGbXaEFFDxcqUfSPQ2Au0UArJGmc6ixuvPKc0eCQEF7jj0ORSkowSl/T10sjaRISdo 3WJg== X-Gm-Message-State: ALoCoQmvwiUM854ZVXlb2j3es4m8rHRoPK67sphnI84kK61bL4iFqyaGhMffEFJaSCMETGuR7Swc X-Received: by 10.152.20.41 with SMTP id k9mr4907115lae.10.1427476560057; Fri, 27 Mar 2015 10:16:00 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.20.201 with SMTP id p9ls219019lae.4.gmail; Fri, 27 Mar 2015 10:15:59 -0700 (PDT) X-Received: by 10.152.87.233 with SMTP id bb9mr9990749lab.30.1427476559817; Fri, 27 Mar 2015 10:15:59 -0700 (PDT) Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com. [209.85.217.177]) by mx.google.com with ESMTPS id wp8si1020334lbb.74.2015.03.27.10.15.59 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 27 Mar 2015 10:15:59 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) client-ip=209.85.217.177; Received: by lbcmq2 with SMTP id mq2so68387677lbc.0 for ; Fri, 27 Mar 2015 10:15:59 -0700 (PDT) X-Received: by 10.152.5.72 with SMTP id q8mr1282624laq.73.1427476559673; Fri, 27 Mar 2015 10:15:59 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.57.201 with SMTP id k9csp9571lbq; Fri, 27 Mar 2015 10:15:58 -0700 (PDT) X-Received: by 10.68.90.132 with SMTP id bw4mr36694772pbb.102.1427476557721; Fri, 27 Mar 2015 10:15:57 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5si3645293pda.134.2015.03.27.10.15.27; Fri, 27 Mar 2015 10:15:57 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753481AbbC0RPB (ORCPT + 27 others); Fri, 27 Mar 2015 13:15:01 -0400 Received: from mail-pa0-f52.google.com ([209.85.220.52]:36160 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753095AbbC0RO5 (ORCPT ); Fri, 27 Mar 2015 13:14:57 -0400 Received: by padcy3 with SMTP id cy3so101193801pad.3 for ; Fri, 27 Mar 2015 10:14:57 -0700 (PDT) X-Received: by 10.70.18.97 with SMTP id v1mr36845638pdd.152.1427476497128; Fri, 27 Mar 2015 10:14:57 -0700 (PDT) Received: from localhost ([122.167.118.120]) by mx.google.com with ESMTPSA id ra10sm2724605pbb.24.2015.03.27.10.14.55 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 27 Mar 2015 10:14:56 -0700 (PDT) From: Viresh Kumar To: Ingo Molnar , Peter Zijlstra , Thomas Gleixner Cc: linaro-kernel@lists.linaro.org, linux-kernel@vger.kernel.org, Kevin Hilman , Daniel Lezcano , Preeti U Murthy , Frederic Weisbecker , Viresh Kumar Subject: [PATCH 1/3] clockevents: Introduce CLOCK_EVT_STATE_ONESHOT_STOPPED state Date: Fri, 27 Mar 2015 22:44:27 +0530 Message-Id: X-Mailer: git-send-email 2.3.0.rc0.44.ga94655d In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When no timers/hrtimers are pending, the expiry time is set to a special value: 'KTIME_MAX'. This normally happens with NO_HZ_{IDLE|FULL} in both LOWRES/HIGHRES modes. When 'expiry == KTIME_MAX', we either cancel the 'tick-sched' hrtimer (NOHZ_MODE_HIGHRES) or skip reprogramming clockevent device (NOHZ_MODE_LOWRES). But, the clockevent device is already reprogrammed from the tick-handler for next tick. As the clock event device is programmed in ONESHOT mode it will at least fire one more time (unnecessarily). Timers on few implementations (like arm_arch_timer, etc.) only support PERIODIC mode and their drivers emulate ONESHOT over that. Which means that on these platforms we will get spurious interrupts periodically (at last programmed interval rate, normally tick rate). In order to avoid spurious interrupts, the clockevent device should be stopped or its interrupts should be masked. A simple (yet hacky) solution to get this fixed could be: update hrtimer_force_reprogram() to always reprogram clockevent device and update clockevent drivers to STOP generating events (or delay it to max time) when 'expires' is set to KTIME_MAX. But the drawback here is that every clockevent driver has to be hacked for this particular case and its very easy for new ones to miss this. However, Thomas suggested to add an optional state ONESHOT_STOPPED to solve this problem: lkml.org/lkml/2014/5/9/508. This patch adds support for ONESHOT_STOPPED state in clockevents core. It will only be available to drivers that implement the state-specific callbacks instead of the legacy ->set_mode() callback. Signed-off-by: Viresh Kumar --- include/linux/clockchips.h | 7 ++++++- kernel/time/clockevents.c | 14 +++++++++++++- kernel/time/timer_list.c | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index e20232c3320a..33ad247f8662 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -51,12 +51,15 @@ enum clock_event_mode { * reached from DETACHED or SHUTDOWN. * ONESHOT: Device is programmed to generate event only once. Can be reached * from DETACHED or SHUTDOWN. + * ONESHOT_STOPPED: Device was programmed in ONESHOT mode and is temporarily + * stopped. */ enum clock_event_state { CLOCK_EVT_STATE_DETACHED = 0, CLOCK_EVT_STATE_SHUTDOWN, CLOCK_EVT_STATE_PERIODIC, CLOCK_EVT_STATE_ONESHOT, + CLOCK_EVT_STATE_ONESHOT_STOPPED, }; /* @@ -103,6 +106,7 @@ enum clock_event_state { * @set_mode: legacy set mode function, only for modes <= CLOCK_EVT_MODE_RESUME. * @set_state_periodic: switch state to periodic, if !set_mode * @set_state_oneshot: switch state to oneshot, if !set_mode + * @set_state_oneshot_stopped: switch state to oneshot_stopped, if !set_mode * @set_state_shutdown: switch state to shutdown, if !set_mode * @tick_resume: resume clkevt device, if !set_mode * @broadcast: function to broadcast events @@ -136,12 +140,13 @@ struct clock_event_device { * State transition callback(s): Only one of the two groups should be * defined: * - set_mode(), only for modes <= CLOCK_EVT_MODE_RESUME. - * - set_state_{shutdown|periodic|oneshot}(), tick_resume(). + * - set_state_{shutdown|periodic|oneshot|oneshot_stopped}(), tick_resume(). */ void (*set_mode)(enum clock_event_mode mode, struct clock_event_device *); int (*set_state_periodic)(struct clock_event_device *); int (*set_state_oneshot)(struct clock_event_device *); + int (*set_state_oneshot_stopped)(struct clock_event_device *); int (*set_state_shutdown)(struct clock_event_device *); int (*tick_resume)(struct clock_event_device *); diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 73689df1e4b8..04f6c3433f8e 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -138,6 +138,17 @@ static int __clockevents_set_state(struct clock_event_device *dev, return -ENOSYS; return dev->set_state_oneshot(dev); + case CLOCK_EVT_STATE_ONESHOT_STOPPED: + /* Core internal bug */ + if (WARN_ONCE(dev->state != CLOCK_EVT_STATE_ONESHOT, + "Current state: %d\n", dev->state)) + return -EINVAL; + + if (dev->set_state_oneshot_stopped) + return dev->set_state_oneshot_stopped(dev); + else + return -ENOSYS; + default: return -ENOSYS; } @@ -449,7 +460,8 @@ static int clockevents_sanity_check(struct clock_event_device *dev) if (dev->set_mode) { /* We shouldn't be supporting new modes now */ WARN_ON(dev->set_state_periodic || dev->set_state_oneshot || - dev->set_state_shutdown || dev->tick_resume); + dev->set_state_shutdown || dev->tick_resume || + dev->set_state_oneshot_stopped); BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); return 0; diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 05aa5590106a..98d77969ba85 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -251,6 +251,12 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu) SEQ_printf(m, "\n"); } + if (dev->set_state_oneshot_stopped) { + SEQ_printf(m, " oneshot stopped: "); + print_name_offset(m, dev->set_state_oneshot_stopped); + SEQ_printf(m, "\n"); + } + if (dev->tick_resume) { SEQ_printf(m, " resume: "); print_name_offset(m, dev->tick_resume);