From patchwork Fri May 1 22:41:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 47914 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f69.google.com (mail-wg0-f69.google.com [74.125.82.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 72C962121F for ; Fri, 1 May 2015 22:41:39 +0000 (UTC) Received: by wgin8 with SMTP id n8sf31911284wgi.0 for ; Fri, 01 May 2015 15:41:38 -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:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=BwGmB1g1LMVQ2sxu7VCp99OOFFK87IpwIJPIFq2hJFo=; b=DTSK96m15TMydWjxsR3ZcYjlJPVLfRmHD1pcq9Bu1fJKchrZXRKwohYQViliT2D6X7 Nvbvm85mbFWbmbpca4D9DyrZz6vI0MJJ8F/Q2mol7oTiXjxDpS/cE6goaSk6M1z+uULF /keoeuYPBGaA/71g9k41ZWfSrbDcGoe71vMZ0WfwcyXElpSW4U6DEY31NHoAzlRJTcVQ 7gBxwxtfV8yqXOyJgW8XBOOi8ZMb8DZY5RgZE3ajmaN2qUPhU/8ctVJa3DBYOuopXLF0 I1+BXeymCNiRlWceWnm1l9CJW2C76UnIFGnMZUeoS8XnE6oGtHrlxYi/dveSjUYkDWjI 0YkA== X-Gm-Message-State: ALoCoQnACxC+qHKuN6lIXsY+KO2BZT7WhHEsv6zThmRBrT14K/IBMEawsgRjfgPQWLA9DRBHpe9Z X-Received: by 10.180.86.226 with SMTP id s2mr1565327wiz.0.1430520098749; Fri, 01 May 2015 15:41:38 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.26.232 with SMTP id o8ls588647lag.39.gmail; Fri, 01 May 2015 15:41:38 -0700 (PDT) X-Received: by 10.112.171.101 with SMTP id at5mr10027564lbc.66.1430520098587; Fri, 01 May 2015 15:41:38 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id w7si4824206lae.160.2015.05.01.15.41.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 May 2015 15:41:38 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by lbbuc2 with SMTP id uc2so72687209lbb.2 for ; Fri, 01 May 2015 15:41:38 -0700 (PDT) X-Received: by 10.152.27.1 with SMTP id p1mr9783134lag.112.1430520098446; Fri, 01 May 2015 15:41:38 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.67.65 with SMTP id l1csp526393lbt; Fri, 1 May 2015 15:41:37 -0700 (PDT) X-Received: by 10.66.222.103 with SMTP id ql7mr21320224pac.144.1430520096539; Fri, 01 May 2015 15:41:36 -0700 (PDT) Received: from mail-pd0-f173.google.com (mail-pd0-f173.google.com. [209.85.192.173]) by mx.google.com with ESMTPS id ia5si9642805pbc.172.2015.05.01.15.41.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 May 2015 15:41:36 -0700 (PDT) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 209.85.192.173 as permitted sender) client-ip=209.85.192.173; Received: by pdbnk13 with SMTP id nk13so104678241pdb.0 for ; Fri, 01 May 2015 15:41:35 -0700 (PDT) X-Received: by 10.68.173.66 with SMTP id bi2mr21349528pbc.5.1430520095577; Fri, 01 May 2015 15:41:35 -0700 (PDT) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id ry2sm5772124pbb.83.2015.05.01.15.41.34 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 01 May 2015 15:41:34 -0700 (PDT) From: John Stultz To: linux-kernel@vger.kernel.org Cc: John Stultz , Nicolas Pitre , Thomas Gleixner , Josh Boyer , One Thousand Gnomes Subject: [PATCH] ktime: Fix ktime_divns to do signed division Date: Fri, 1 May 2015 15:41:25 -0700 Message-Id: <1430520085-24535-1-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.stultz@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.174 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , It was noted that the 32bit implementation of ktime_divns was doing unsgined division adn didn't properly handle negative values. This patch fixes the problem by checking and preserving the sign bit, and then reapplying it if appropriate after the division. Unfortunately there is some duplication since we have the optimized version for constant 32bit divider. I was considering reworkign the __ktime_divns helper to simplify the sign-handling logic, but then it would likely just be a s64/s64 divide, and probably should be more generic. Thoughts? Nicolas also notes that the ktime_divns() function breaks if someone passes in a negative divisor as well. This patch doesn't yet address that issue. Cc: Nicolas Pitre Cc: Thomas Gleixner Cc: Josh Boyer Cc: One Thousand Gnomes Reported-by: Trevor Cordes Signed-off-by: John Stultz --- include/linux/ktime.h | 12 ++++++++++-- kernel/time/hrtimer.c | 11 +++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/linux/ktime.h b/include/linux/ktime.h index 5fc3d10..d947263 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -166,12 +166,20 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) } #if BITS_PER_LONG < 64 -extern u64 __ktime_divns(const ktime_t kt, s64 div); +extern s64 __ktime_divns(const ktime_t kt, s64 div); static inline u64 ktime_divns(const ktime_t kt, s64 div) { if (__builtin_constant_p(div) && !(div >> 32)) { - u64 ns = kt.tv64; + s64 ns = kt.tv64; + int neg = 0; + + if (ns < 0) { + neg = 1; + ns = -ns; + } do_div(ns, div); + if (neg) + ns = -ns; return ns; } else { return __ktime_divns(kt, div); diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 76d4bd9..4c1b294 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -266,12 +266,17 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags) /* * Divide a ktime value by a nanosecond value */ -u64 __ktime_divns(const ktime_t kt, s64 div) +s64 __ktime_divns(const ktime_t kt, s64 div) { - u64 dclc; + s64 dclc; int sft = 0; + int neg = 0; dclc = ktime_to_ns(kt); + if (dclc < 0) { + neg = 1; + dclc = -dclc; + } /* Make sure the divisor is less than 2^32: */ while (div >> 32) { sft++; @@ -279,6 +284,8 @@ u64 __ktime_divns(const ktime_t kt, s64 div) } dclc >>= sft; do_div(dclc, (unsigned long) div); + if (neg) + dclc = -dclc; return dclc; }