From patchwork Fri Apr 4 08:35:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 27787 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ig0-f200.google.com (mail-ig0-f200.google.com [209.85.213.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5923720490 for ; Fri, 4 Apr 2014 08:36:21 +0000 (UTC) Received: by mail-ig0-f200.google.com with SMTP id l13sf1425791iga.7 for ; Fri, 04 Apr 2014 01:36:20 -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=+GoP/+BArvyAH3DzX1FIoaAiUewzaY7R4W/e2S8kA9U=; b=g/92hrKOOSQd8TzSZ2jua7881D1uFiy82QPucvUuceBp4+iDT+b10ufgZMqknMDoCE vtd/EZkYatDnWCO5CmSXJEzRczHjymqhx10mDieaiN7yU8JnJVDvYEFNaeGj3VGdH0KL T9OBCQS3xBbbmePuAzmJGBRxHWJ1qFBRgxz7xubBkU1M2eBEh/nq8w9cDv/mrTMhdRzz A3M/zBGjtETPwe06V7TBTBEWvZo5GdU3HR+8qc4yb71ZRJE0e6vTXgCTVpgJ5dzVPmWC 6tFhiMqbqtragrH2vCuPRZFrA0d0h7xpYdygBxFhEXM40yCWBSBIBHAlHAUg/4atboIV VUWQ== X-Gm-Message-State: ALoCoQksuSqCeMOpxxEBToMWR6HYAb9x0HNQIF4GwMQRTKasr5uMk3z6uU4LB6zwKNz2hMcnSYVc X-Received: by 10.42.115.129 with SMTP id k1mr6730064icq.25.1396600580800; Fri, 04 Apr 2014 01:36:20 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.109.101 with SMTP id k92ls950350qgf.64.gmail; Fri, 04 Apr 2014 01:36:20 -0700 (PDT) X-Received: by 10.52.119.197 with SMTP id kw5mr10133411vdb.5.1396600580709; Fri, 04 Apr 2014 01:36:20 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id cb3si1684737vdc.23.2014.04.04.01.36.20 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 04 Apr 2014 01:36:20 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id il7so2856342vcb.4 for ; Fri, 04 Apr 2014 01:36:20 -0700 (PDT) X-Received: by 10.58.107.65 with SMTP id ha1mr4081444veb.1.1396600580606; Fri, 04 Apr 2014 01:36:20 -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.220.12.8 with SMTP id v8csp95545vcv; Fri, 4 Apr 2014 01:36:19 -0700 (PDT) X-Received: by 10.66.177.168 with SMTP id cr8mr13664206pac.128.1396600577941; Fri, 04 Apr 2014 01:36:17 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s8si75405pas.303.2014.04.04.01.36.17; Fri, 04 Apr 2014 01:36:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752331AbaDDIgG (ORCPT + 27 others); Fri, 4 Apr 2014 04:36:06 -0400 Received: from mail-wi0-f173.google.com ([209.85.212.173]:43490 "EHLO mail-wi0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751799AbaDDIgB (ORCPT ); Fri, 4 Apr 2014 04:36:01 -0400 Received: by mail-wi0-f173.google.com with SMTP id z2so772490wiv.0 for ; Fri, 04 Apr 2014 01:36:00 -0700 (PDT) X-Received: by 10.180.39.175 with SMTP id q15mr2652251wik.4.1396600559951; Fri, 04 Apr 2014 01:35:59 -0700 (PDT) Received: from localhost ([213.122.173.131]) by mx.google.com with ESMTPSA id w6sm11402127wjq.29.2014.04.04.01.35.54 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 04 Apr 2014 01:35:59 -0700 (PDT) From: Viresh Kumar To: tglx@linutronix.de, fweisbec@gmail.com, peterz@infradead.org, mingo@kernel.org, tj@kernel.org, lizefan@huawei.com Cc: linaro-kernel@lists.linaro.org, linaro-networking@linaro.org, Arvind.Chauhan@arm.com, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, Viresh Kumar Subject: [PATCH V2 1/8] timer: track pinned timers with TIMER_PINNED flag Date: Fri, 4 Apr 2014 14:05:28 +0530 Message-Id: <7236b1fccb011d9863403b544e8272171446b4fe.1396599474.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e 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=neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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: , In order to quiesce a CPU on which Isolation might be required, we need to move away all the timers queued on that CPU. There are two types of timers queued on any CPU: ones that are pinned to that CPU and others can run on any CPU but are queued on CPU in question. And we need to migrate only the second type of timers away from the CPU entering quiesce state. For this we need some basic infrastructure in timer core to identify which timers are pinned and which are not. Hence, this patch adds another flag bit TIMER_PINNED which will be set only for the timers which are pinned to a CPU. It also removes 'pinned' parameter of __mod_timer() as it is no more required. NOTE: One functional change worth mentioning Existing Behavior: add_timer_on() followed by multiple mod_timer() wouldn't pin the timer on CPU mentioned in add_timer_on().. New Behavior: add_timer_on() followed by multiple mod_timer() would pin the timer on CPU running mod_timer(). I didn't gave much attention to this as we should call mod_timer_on() for the timers queued with add_timer_on(). Though if required we can simply clear the TIMER_PINNED flag in mod_timer(). Signed-off-by: Viresh Kumar --- include/linux/timer.h | 10 ++++++---- kernel/timer.c | 27 ++++++++++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/linux/timer.h b/include/linux/timer.h index 8c5a197..2962403 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -49,7 +49,7 @@ extern struct tvec_base boot_tvec_bases; #endif /* - * Note that all tvec_bases are at least 4 byte aligned and lower two bits + * Note that all tvec_bases are at least 8 byte aligned and lower three bits * of base in timer_list is guaranteed to be zero. Use them for flags. * * A deferrable timer will work normally when the system is busy, but @@ -61,14 +61,18 @@ extern struct tvec_base boot_tvec_bases; * the completion of the running instance from IRQ handlers, for example, * by calling del_timer_sync(). * + * A pinned timer is allowed to run only on the cpu mentioned and shouldn't be + * migrated to any other CPU. + * * Note: The irq disabled callback execution is a special case for * workqueue locking issues. It's not meant for executing random crap * with interrupts disabled. Abuse is monitored! */ #define TIMER_DEFERRABLE 0x1LU #define TIMER_IRQSAFE 0x2LU +#define TIMER_PINNED 0x4LU -#define TIMER_FLAG_MASK 0x3LU +#define TIMER_FLAG_MASK 0x7LU #define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \ .entry = { .prev = TIMER_ENTRY_STATIC }, \ @@ -179,8 +183,6 @@ extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires); extern void set_timer_slack(struct timer_list *time, int slack_hz); -#define TIMER_NOT_PINNED 0 -#define TIMER_PINNED 1 /* * The jiffies value which is added to now, when there is no timer * in the timer wheel: diff --git a/kernel/timer.c b/kernel/timer.c index d13eb56..e8bcaff 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -104,6 +104,11 @@ static inline unsigned int tbase_get_irqsafe(struct tvec_base *base) return ((unsigned int)(unsigned long)base & TIMER_IRQSAFE); } +static inline unsigned int tbase_get_pinned(struct tvec_base *base) +{ + return ((unsigned int)(unsigned long)base & TIMER_PINNED); +} + static inline struct tvec_base *tbase_get_base(struct tvec_base *base) { return ((struct tvec_base *)((unsigned long)base & ~TIMER_FLAG_MASK)); @@ -117,6 +122,13 @@ timer_set_base(struct timer_list *timer, struct tvec_base *new_base) timer->base = (struct tvec_base *)((unsigned long)(new_base) | flags); } +static inline void +timer_set_flags(struct timer_list *timer, unsigned int flags) +{ + timer->base = (struct tvec_base *)((unsigned long)(timer->base) | + flags); +} + static unsigned long round_jiffies_common(unsigned long j, int cpu, bool force_up) { @@ -742,8 +754,7 @@ static struct tvec_base *lock_timer_base(struct timer_list *timer, } static inline int -__mod_timer(struct timer_list *timer, unsigned long expires, - bool pending_only, int pinned) +__mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only) { struct tvec_base *base, *new_base; unsigned long flags; @@ -760,7 +771,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, debug_activate(timer, expires); - cpu = get_nohz_timer_target(pinned); + cpu = get_nohz_timer_target(tbase_get_pinned(timer->base)); new_base = per_cpu(tvec_bases, cpu); if (base != new_base) { @@ -802,7 +813,7 @@ out_unlock: */ int mod_timer_pending(struct timer_list *timer, unsigned long expires) { - return __mod_timer(timer, expires, true, TIMER_NOT_PINNED); + return __mod_timer(timer, expires, true); } EXPORT_SYMBOL(mod_timer_pending); @@ -877,7 +888,7 @@ int mod_timer(struct timer_list *timer, unsigned long expires) if (timer_pending(timer) && timer->expires == expires) return 1; - return __mod_timer(timer, expires, false, TIMER_NOT_PINNED); + return __mod_timer(timer, expires, false); } EXPORT_SYMBOL(mod_timer); @@ -905,7 +916,8 @@ int mod_timer_pinned(struct timer_list *timer, unsigned long expires) if (timer->expires == expires && timer_pending(timer)) return 1; - return __mod_timer(timer, expires, false, TIMER_PINNED); + timer_set_flags(timer, TIMER_PINNED); + return __mod_timer(timer, expires, false); } EXPORT_SYMBOL(mod_timer_pinned); @@ -944,6 +956,7 @@ void add_timer_on(struct timer_list *timer, int cpu) timer_stats_timer_set_start_info(timer); BUG_ON(timer_pending(timer) || !timer->function); + timer_set_flags(timer, TIMER_PINNED); spin_lock_irqsave(&base->lock, flags); timer_set_base(timer, base); debug_activate(timer, timer->expires); @@ -1493,7 +1506,7 @@ signed long __sched schedule_timeout(signed long timeout) expire = timeout + jiffies; setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); - __mod_timer(&timer, expire, false, TIMER_NOT_PINNED); + __mod_timer(&timer, expire, false); schedule(); del_singleshot_timer_sync(&timer);