Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4689580imu; Sat, 19 Jan 2019 16:04:34 -0800 (PST) X-Google-Smtp-Source: ALg8bN73d0+wqlpreui7CXNUbkCic5amKHqStd7seOvwga7RoI1TLw/X55S3HcMqtXdy0nedDJ/k X-Received: by 2002:a63:4d0e:: with SMTP id a14mr23220588pgb.408.1547942674534; Sat, 19 Jan 2019 16:04:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547942674; cv=none; d=google.com; s=arc-20160816; b=dxFs9w6rWYvwOszTabEqWUsN+9pfcozgUNsPqb4crcvQllmfDn8C/6RNZoIMwW8p5k mOzcv0M0Vr3sQGCziVn911no7Ohe3EWyJkIbU0C/+7KafVzLtjgjuUwENU/adAhRoSiE eVb6f2dVdWL+GPFNzc3ixGMKSl6J7BLSJQvn6/2bVzcWKv5KYA/F0N/A5V0BPnk3tYqa avpHXRN0uRnno2Pc5kewvCKaP1wEFKUycqi4sUxYJCCTNgRuBPa1kvFdbbhMlM03y6hp IHj3zDpTw3LNS2Y9wZeS/uyT+lTYGe0V0GS1Rjg35YuokyZeSxDQjhvLRIxI4nYTHTfo Atnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=XmptBrJjo7Ktl3DY1stW0Co+sSuKn8sgmBTlsAATWwA=; b=rqrMkThiSqAgs2adCzCt0bQ2aL0m814CZqkvKxfTGs0Yf7zi3oLExiYi86nkXZkRO1 A0Q/hfKKSM6EEPnf+fA3eSJb9xIgc87Gb/CnLi6DSGW7W+v/B2GvBhCtZlp2WJ1iaLcb j0cIsaLMcokoQv0/3mGhTyPWtVMO33hdNWypvV+OA4gIh7GSxSJ91Lj4tikVRpxfuk10 jtYy+DfMTIOd+HRKpgEpHFqLEvbwPZpNzoOnoIOktr2zRdWIq9bv0L2qiiGSmhupwM/s imbIxNLbf0uhy4Qq3Sum1mubcRBcXR402xNQW0H0nafOf48oYfmFUtujsHNevYgqPcBb oRLQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i1si8492541pfj.276.2019.01.19.16.04.18; Sat, 19 Jan 2019 16:04:34 -0800 (PST) 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; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729978AbfATABq (ORCPT + 99 others); Sat, 19 Jan 2019 19:01:46 -0500 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:46944 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729803AbfATABq (ORCPT ); Sat, 19 Jan 2019 19:01:46 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0327CA78; Sat, 19 Jan 2019 16:01:46 -0800 (PST) Received: from brain-police (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0A9743F6A8; Sat, 19 Jan 2019 16:01:43 -0800 (PST) Date: Sun, 20 Jan 2019 00:01:40 +0000 From: Will Deacon To: Florian La Roche Cc: linux-kernel@vger.kernel.org, Crt Mori , Joe Perches , Davidlohr Bueso , Peter Zijlstra , Linus Torvalds Subject: Re: fix int_sqrt() for very large numbers Message-ID: <20190120000138.GI26876@brain-police> References: <20190119151450.26879-1-Florian.LaRoche@googlemail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190119151450.26879-1-Florian.LaRoche@googlemail.com> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Jan 19, 2019 at 04:14:50PM +0100, Florian La Roche wrote: > If an input number x for int_sqrt() has the highest bit set, then > __ffs(x) is 64. (1UL << 64) is an overflow and breaks the algorithm. This is confusing, because the patch doesn't go near an __ffs(). > Just subtracting 1 is an even better guess for the initial > value of m and that's what also used to be done in earlier > versions of this code. > > best regards, > > Florian La Roche > > Signed-off-by: Florian La Roche > --- > lib/int_sqrt.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c > index 14436f4ca6bd..ea00e84dc272 100644 > --- a/lib/int_sqrt.c > +++ b/lib/int_sqrt.c > @@ -23,7 +23,7 @@ unsigned long int_sqrt(unsigned long x) > if (x <= 1) > return x; > > - m = 1UL << (__fls(x) & ~1UL); > + m = 1UL << ((__fls(x) - 1) & ~1UL); I think this one is fine, because __fls() gives you back 0-63 (or undefined, but the previous <= 1 check handles that case). > while (m != 0) { > b = y + m; > y >>= 1; > @@ -52,7 +52,7 @@ u32 int_sqrt64(u64 x) > if (x <= ULONG_MAX) > return int_sqrt((unsigned long) x); > > - m = 1ULL << (fls64(x) & ~1ULL); > + m = 1ULL << ((fls64(x) - 1) & ~1ULL); This just looks like a copy-paste error because there isn't an __fls64(). But I think your suggestion here is ok, given the previous check against ULONG_MAX. Will