From patchwork Fri Apr 3 03:34:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 46741 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9EB98216D1 for ; Fri, 3 Apr 2015 03:35:03 +0000 (UTC) Received: by wiaa2 with SMTP id a2sf22384071wia.1 for ; Thu, 02 Apr 2015 20:35:02 -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=dr3OcCTu6YZOTHpffZLWW+f7yY0sFa5mcFgo5mFpiTA=; b=MWt4vZy/C56hZNDI68yBDtL4VdGHQVZBOyhOoRfmeo0uEvW/jqn4SfaFFQPmB/HVfE I4mCmWCrRfZgy1qVFxoRD4hAFgzdj2bmzuMuHkynVRpVELDhSlYRvTgnt+Ntltp/SBlH 47aqgnr8BsW4FYD5d8nWUV954z8/BHjJTstMisA+wPyT0MOhj5HvXQyebuZ7JUl4gruu Ke1mKZOpaIDVLHfSAUkcmYDROtpysUMaaKfB1YZg45qnTFmuQhWKieykGVkkUdlZJ6Ew Z0mhn0gDR5paaa+5AyIHZmpB1+jtT0HoHsw6cyTlsQ2/H+69l+yLoURAiRM0xZnzKF4d czQA== X-Gm-Message-State: ALoCoQmBtGDetLNvgvc48DfIGf4/D2XtcHaiZd9MwDogueDRkzlo5wZPN1bx3cNbxa+gtxM1OJ3e X-Received: by 10.194.236.196 with SMTP id uw4mr114071wjc.5.1428032102859; Thu, 02 Apr 2015 20:35:02 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.21.130 with SMTP id v2ls232728lae.98.gmail; Thu, 02 Apr 2015 20:35:02 -0700 (PDT) X-Received: by 10.152.170.164 with SMTP id an4mr414645lac.9.1428032102663; Thu, 02 Apr 2015 20:35:02 -0700 (PDT) Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com. [209.85.217.171]) by mx.google.com with ESMTPS id bh7si5695631lbc.116.2015.04.02.20.35.02 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Apr 2015 20:35:02 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) client-ip=209.85.217.171; Received: by lbdc10 with SMTP id c10so71844960lbd.2 for ; Thu, 02 Apr 2015 20:35:02 -0700 (PDT) X-Received: by 10.112.8.101 with SMTP id q5mr396731lba.19.1428032102515; Thu, 02 Apr 2015 20:35:02 -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 k9csp1714761lbq; Thu, 2 Apr 2015 20:35:01 -0700 (PDT) X-Received: by 10.70.45.227 with SMTP id q3mr899092pdm.22.1428032099997; Thu, 02 Apr 2015 20:34:59 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id pk6si10032377pbc.162.2015.04.02.20.34.59; Thu, 02 Apr 2015 20:34:59 -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 S1753153AbbDCDeu (ORCPT + 27 others); Thu, 2 Apr 2015 23:34:50 -0400 Received: from mail-pd0-f171.google.com ([209.85.192.171]:35226 "EHLO mail-pd0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751249AbbDCDep (ORCPT ); Thu, 2 Apr 2015 23:34:45 -0400 Received: by pddn5 with SMTP id n5so108945228pdd.2 for ; Thu, 02 Apr 2015 20:34:45 -0700 (PDT) X-Received: by 10.70.89.237 with SMTP id br13mr788415pdb.135.1428032085103; Thu, 02 Apr 2015 20:34:45 -0700 (PDT) Received: from localhost ([122.167.118.120]) by mx.google.com with ESMTPSA id eh4sm6580465pbd.69.2015.04.02.20.34.43 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 02 Apr 2015 20:34:44 -0700 (PDT) From: Viresh Kumar To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra Cc: linaro-kernel@lists.linaro.org, linux-kernel@vger.kernel.org, Frederic Weisbecker , Kevin Hilman , Daniel Lezcano , Preeti U Murthy , Viresh Kumar Subject: [PATCH V2 1/2] clockevents: Introduce CLOCK_EVT_STATE_ONESHOT_STOPPED state Date: Fri, 3 Apr 2015 09:04:04 +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.171 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. Reviewed-by: Preeti U. Murthy 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 caeca76d7b32..ee63865d3cd7 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -49,12 +49,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, CLOCK_EVT_STATE_SHUTDOWN, CLOCK_EVT_STATE_PERIODIC, CLOCK_EVT_STATE_ONESHOT, + CLOCK_EVT_STATE_ONESHOT_STOPPED, }; /* @@ -102,6 +105,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 @@ -133,11 +137,12 @@ 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 7af614829da1..49ed2ea4294c 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 e878c2e0ba45..fbc902ccd72a 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);