From patchwork Tue Dec 5 13:02:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 174043 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp3410748vqy; Tue, 5 Dec 2023 05:02:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IEh3MWKAs84GNS8vDo4QcKP9k+O3Ncu9d896ZSlNoRMLcapTmCGv+iIsNo2rxY4q0kC29Ds X-Received: by 2002:a05:6a21:6d96:b0:18f:b899:21d4 with SMTP id wl22-20020a056a216d9600b0018fb89921d4mr35352pzb.92.1701781345581; Tue, 05 Dec 2023 05:02:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701781345; cv=none; d=google.com; s=arc-20160816; b=qw5kP7npLLvpaOm6pyDG5y5HgHsd6q65T6OeYKLriWgLj+FaluCIwkwnJtaaryFn1L YaSz3kPGgXu5hYpWiS4zxSVaUbY1o/gz6E39TnjWbktVp7n8B4f6PnO4Zmd841I3xRkw xbgTrxgygG583rhmIQvgHpnC9wfCCtZj/4rUv+/gE42LYJx+DN0e2tP8QtQKwxagAW2j aTs8ylnNyvUWZ+YouBK8iLpU/nGz7XIHO8lma9eYYdhz7CfffUAu0t4WsGxsSQuIKqM+ 4pXvIQjYLciXg83wj9Xhw9mNkUULVbj03yu6LqToAW8ElRuBxdeMgz4u9X6988wtWe36 xpYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-disposition:mime-version:message-id :subject:cc:to:from:date:dkim-signature; bh=wVkkONZNfkX/iqB+XjK9GHA8D0k5JMrE6DojR60eqaY=; fh=iW45axIta/n/LGZl/hNRckTnBEjPax1LyHxTDDNOCRU=; b=ChoMZHOH0sw6aj1qK+A1e4M7Re0HIlg4MtiYVB9/3U1ibPhv8CwegkO+xNAVRa8X2m 1ZUtaerEfJ2PwImHLvxht7Ch3QPY6kM3vAXl/qDjZCFc+phkF3xFlvgRJAIrEa0SSZxw Fh2YE3YFH8z/DOcV9nxr+k9xDO5L222kwgUcrZvgJqsyg/TX7/hOQI/PMz/kMvT7R4Uc dpSditegAgex7e/hyLduNk3bz4vZdIev7M5NxmOHgSAjMS7MYZMnWFOUXkvTHzM0SImQ ro+MvX8VzkC8FvIvwZPjHM/ZeIehowMHBaUHz5hjcOLqNaTSBHkHDlVz9P9rKsQaOJhy +jHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=D6MUHoGg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id w13-20020a65534d000000b005aa7d3730dfsi9144776pgr.114.2023.12.05.05.02.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 05:02:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=D6MUHoGg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 5D0388022EBC; Tue, 5 Dec 2023 05:02:18 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235161AbjLENCJ (ORCPT + 99 others); Tue, 5 Dec 2023 08:02:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235124AbjLENCI (ORCPT ); Tue, 5 Dec 2023 08:02:08 -0500 Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EF90D7; Tue, 5 Dec 2023 05:02:14 -0800 (PST) Received: by mail-lj1-x230.google.com with SMTP id 38308e7fff4ca-2c9f62447c2so28574411fa.0; Tue, 05 Dec 2023 05:02:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701781333; x=1702386133; darn=vger.kernel.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=wVkkONZNfkX/iqB+XjK9GHA8D0k5JMrE6DojR60eqaY=; b=D6MUHoGgJ/6SI9+AoORI8jqnKO0a7qeRmgw6djvw03qTewZZ4n6syf6F6yZc2Kkf0K AU9DiEhaz2/ZCzwpr3QPwiXL7+Jyv/mS393B4nwmrdliTUGODNq2RraufOTe7mVun/9H 172nG+607I1bXUvPskn027N/IeEeTNBaptb0XR7migdOajUe0A4oh2QNcXmDcz75P29w dNGNF3PQPP4lp3RMwOdE25XqK4fC7k6WLOAHs8tl12t8pBV3psbLLNbYYRCVPz74LqtV 1RS7BI4EY73IkhIuHdgoRedoMoR5bzLw7VCLkd750qZIAwXMdi/YoIcF90oeC8eZfQ20 5Vxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701781333; x=1702386133; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wVkkONZNfkX/iqB+XjK9GHA8D0k5JMrE6DojR60eqaY=; b=HVzO6HbICG81Cux2KVAf3XYLHSzkJ/fGJqoqG6QSYvllr4BKCL7/CJ3SacdQz/m+p+ AhDwDPxB0/uKlIJF5AwR0pfuXCcnLKnM8244T0fPZcsG9la/X7GmdpmmkWPD+KTYtIxQ IcTbdWiRUMpjptIcDMrW9bAHCb89sws3z9F8BcYhK6Cqr7PqMKRVU1GALg89GbV+nFkq zQ3yuzV9cBpibkPtAmkQ+zijtADHM+aUnmJgT7QZwalu1gQc9+GikFp0WmR0BziyYhyg Nggjyml9dF535wrmlRjxjRezhXh0oXpAmKlaLisMblrtoSzYFQamzYreK0Wz/hqErwF0 MZnA== X-Gm-Message-State: AOJu0Ywr/IaGbVdPE0nZsyVFn3bHuxvIC+7ESWwlKH9f+rt9i+nEb00j IKvLNfm9LwZN+ETF0GU2wao= X-Received: by 2002:a2e:6a12:0:b0:2c9:e3ad:1f32 with SMTP id f18-20020a2e6a12000000b002c9e3ad1f32mr870027ljc.6.1701781332351; Tue, 05 Dec 2023 05:02:12 -0800 (PST) Received: from dc78bmyyyyyyyyyyyyyby-3.rev.dnainternet.fi (dc78bmyyyyyyyyyyyyyby-3.rev.dnainternet.fi. [2001:14ba:16f8:1500::2]) by smtp.gmail.com with ESMTPSA id u18-20020a2eb812000000b002ca0090a933sm801384ljo.10.2023.12.05.05.02.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 05:02:11 -0800 (PST) Date: Tue, 5 Dec 2023 15:02:02 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Matti Vaittinen , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, Subhajit Ghosh Subject: [PATCH v2] iio: gts-helpers: Round gains and scales Message-ID: <37d3aa193e69577353d314e94463a08d488ddd8d.1701780964.git.mazziesaccount@gmail.com> MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Tue, 05 Dec 2023 05:02:18 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781264259920289057 X-GMAIL-MSGID: 1784447076348899542 The GTS helpers do flooring of scale when calculating available scales. This results available-scales to be reported smaller than they should when the division in scale computation resulted remainder greater than half of the divider. (decimal part of result > 0.5) Furthermore, when gains are computed based on scale, the gain resulting from the scale computation is also floored. As a consequence the floored scales reported by available scales may not match the gains that can be set. Finally, the loop-based implementation of the 64-bit division which is used by GTS-helpers may be running for a _very long_ time. This patch does also replace this implementation by a well-known variant of a 64-bit division div64_u64(). The related discussion can be found from: https://lore.kernel.org/all/84d7c283-e8e5-4c98-835c-fe3f6ff94f4b@gmail.com/ Do rounding when computing scales and gains. Fixes: 38416c28e168 ("iio: light: Add gain-time-scale helpers") Signed-off-by: Matti Vaittinen --- Revision history: v1 => v2: - fix rounding in iio_gts_get_gain() The iio_gts_get_gain() is accidentally doing >> 2 when it attempts to divide by 2. Fix this. - use proper 64bit division div64_u64() instead of a loop and extra 32bit function - Fix iio_gts_total_gain_to_scale() documentation as it's not computing gain. - Add a comment on rounding logic in iio_gts_total_gain_to_scale(). It's fair to point out Jonathan questioned the rounding logic and suggested using the more of a "de-facto" method of adding divider / 2 to value being divided, and checking for overflow. The proper handling of the overflow however resulted even more confusing code (in my subjective opinion) than the (more) straightforward approach of checking the size of the reminder and adding +1 to result when needed. Subjahit, is there any chance you test this patch with your driver? Can you drop the: if (val2 % 10) val2 += 1; from scale setting and do you see written and read scales matching? I did run a few Kunit tests on this change - but I'm still a bit jumpy on it... Reviewing/testing is highly appreciated! --- drivers/iio/industrialio-gts-helper.c | 31 +++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index 7653261d2dc2..19091193e430 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -28,28 +29,32 @@ * scale is 64 100 000 000. * @scale: Linearized scale to compute the gain for. * - * Return: (floored) gain corresponding to the scale. -EINVAL if scale + * Return: (rounded) gain corresponding to the scale. -EINVAL if scale * is invalid. */ static int iio_gts_get_gain(const u64 max, const u64 scale) { - u64 full = max; - int tmp = 1; + u64 full = max, half_div; + int tmp = 0; if (scale > full || !scale) return -EINVAL; - if (U64_MAX - full < scale) { - /* Risk of overflow */ - if (full - scale < scale) + half_div = scale >> 1; + + if (U64_MAX - full < half_div) { + /* + * Would overflow when adding half_div to full. Hence we need + * to subtract scale from full if full is big enough. + */ + if (full - scale <= half_div) return 1; full -= scale; tmp++; } - while (full > scale * (u64)tmp) - tmp++; + tmp += div64_u64(full + half_div, scale); return tmp; } @@ -140,10 +145,18 @@ int iio_gts_total_gain_to_scale(struct iio_gts *gts, int total_gain, int *scale_int, int *scale_nano) { u64 tmp; + int rem; tmp = gts->max_scale; - do_div(tmp, total_gain); + rem = do_div(tmp, total_gain); + + /* + * Round up if remainder is equal to or greater than the half of + * the divider. + */ + if (total_gain > 1 && rem >= total_gain / 2) + tmp += 1ULL; return iio_gts_delinearize(tmp, NANO, scale_int, scale_nano); }