Message ID | 20221227100450.2257-3-i.bornyakov@metrotek.ru |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp1319464wrt; Tue, 27 Dec 2022 02:16:50 -0800 (PST) X-Google-Smtp-Source: AMrXdXvgINHSRIGmS/r06K0WxlSYOKH8fj3JlW08ZAV4bqnqj7bvvKpDzA8PCDKrS+0WbaeBPvv5 X-Received: by 2002:a17:907:d48a:b0:7c1:766e:e09 with SMTP id vj10-20020a170907d48a00b007c1766e0e09mr17862662ejc.29.1672136210062; Tue, 27 Dec 2022 02:16:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672136210; cv=none; d=google.com; s=arc-20160816; b=NFkGG+pQiZkPmA6ruaZjdiwL9W53k0UL91M34fQWJFgtskGEKdR1OVZsK11NiKrxJA 88JYHiFucu0Cpqlsd277hZrR+q89++zeVGmEDVNWiXvy/PWM6l7pTvFDxrnMejgeRkcY ClivXX4ZqxVSebQio0oOFSaEybDkYZmF9iI60a8tR59V9tVsoheAr1tdRg39vHM77Q1r M6k/i28ykAdePOGxJ0sWI21N+LqCRCjOJzFDwc9y4pIrKrRlNcZLZbgNLFGsSK2V9BN8 xK+IM5w4nM91aTSHgV7K4Jp7jlIfjxht7THSSFi9WL/jvy/7s+3+HZ1tjJmrlDDefILd zkuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=716xkZbp3iNOvCg2puSvnz/yGSgh4p9sWyA0DAmTnAI=; b=HF0wALBmuW/gDeX31y0cAu2+k2j0hjIPtdlbR4cjgZ1TapaN1PD+xLWwjwmdDnBbIT AtaZyztogHnoYQVz9xdtNqGGEAZZpUA6RiOs4Q3kpYswi56NqE8xhvnM1Dhe3ByMdXCm w8WGe2Okjvf6z1BW/Pk1L6DXzJy0sXtiLMUbsb7nTAp3Ve4IdAXZYw8lDVWoBbBOUh+n sGlecJ0PP/nVO5h1nhQ09v+9TJNba7/y8GLBU6SwJg4wBF4q0FbWEk/28VPfx72tmfrA WUlI+jksSs8y7uW8QCNTs0ypispDx+PzN70fMDLAzGUfiC1oB95VYpanJ9IhxnePZMUN ngGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@metrotek.ru header.s=mail header.b=SLvWAWwm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o13-20020a17090611cd00b007c16b3feca1si9594382eja.903.2022.12.27.02.16.26; Tue, 27 Dec 2022 02:16:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=fail header.i=@metrotek.ru header.s=mail header.b=SLvWAWwm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231317AbiL0KHf (ORCPT <rfc822;eddaouddi.ayoub@gmail.com> + 99 others); Tue, 27 Dec 2022 05:07:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229445AbiL0KHa (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 27 Dec 2022 05:07:30 -0500 Received: from mail.pr-group.ru (mail.pr-group.ru [178.18.215.3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 159062FF; Tue, 27 Dec 2022 02:07:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=metrotek.ru; s=mail; h=from:subject:date:message-id:to:cc:mime-version:content-transfer-encoding: in-reply-to:references; bh=7Fvs78gYqrEVBbbQ/K9bc20z+/joLO6qDiw854CBaFQ=; b=SLvWAWwm+e3kVkiocTYSH6yr8Rs4Gu5Kc7UcGaV7cR8Y2jyWu/puOUzaEXH20HRVtNx9mlnWJzec4 zdOKRm6SM1RgM450cjqAla6xG9c0haKUEfj+zz3xCcarc1GcXMjEctepRhxzJ5kvfBUfewGJQqGeUt A1gEE7ClAEUMMcpJmE24UriX0i3Nr+sDyJKYGOFP4FIKCA3PJWUl2mbOAdPRDBnx9O5CbS5PPt3B+y 3zkd5uhPxNRLBm7H5x5D1MNeQIIGR/vXoAx7okkvsGyQgyvHMRLoSKwh2j5+GKvL7dPY+29ZJXvJSu JdFwuUq63RVjs8cplssk17HQsG8u/RQ== X-Kerio-Anti-Spam: Build: [Engines: 2.16.5.1460, Stamp: 3], Multi: [Enabled, t: (0.000010,0.012862)], BW: [Enabled, t: (0.000031,0.000002)], RTDA: [Enabled, t: (0.094436), Hit: No, Details: v2.42.0; Id: 15.52ka2l.1gl9gppe8.3nj; mclb], total: 0(700) X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Level: X-Footer: bWV0cm90ZWsucnU= Received: from localhost.localdomain ([78.37.162.181]) (authenticated user i.bornyakov@metrotek.ru) by mail.pr-group.ru with ESMTPSA (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)); Tue, 27 Dec 2022 13:07:10 +0300 From: Ivan Bornyakov <i.bornyakov@metrotek.ru> To: Conor Dooley <conor.dooley@microchip.com>, Moritz Fischer <mdf@kernel.org>, Wu Hao <hao.wu@intel.com>, Xu Yilun <yilun.xu@intel.com>, Tom Rix <trix@redhat.com>, =?utf-8?q?Ilpo_J?= =?utf-8?q?=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com> Cc: Ivan Bornyakov <i.bornyakov@metrotek.ru>, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org, system@metrotek.ru Subject: [PATCH v3 2/3] fpga: microchip-spi: rewrite status polling in a time measurable way Date: Tue, 27 Dec 2022 13:04:49 +0300 Message-Id: <20221227100450.2257-3-i.bornyakov@metrotek.ru> X-Mailer: git-send-email 2.38.2 In-Reply-To: <20221227100450.2257-1-i.bornyakov@metrotek.ru> References: <20221227100450.2257-1-i.bornyakov@metrotek.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1753361898917044359?= X-GMAIL-MSGID: =?utf-8?q?1753361898917044359?= |
Series |
Reliability improvements for Microchip MPF FPGA manager
|
|
Commit Message
Ivan Bornyakov
Dec. 27, 2022, 10:04 a.m. UTC
Original busy loop with retries count in mpf_poll_status() is not too
reliable, as it takes different times on different systems. Replace it
with read_poll_timeout() macro.
While at it, fix polling stop condition to met function's original
intention declared in the comment. The issue with original polling stop
condition is that it stops if any of mask bits is set, while intention
was to stop if all mask bits is set. This was not noticible because only
MPF_STATUS_READY is passed as mask argument and it is BIT(1).
Fixes: 5f8d4a900830 ("fpga: microchip-spi: add Microchip MPF FPGA manager")
Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru>
---
drivers/fpga/microchip-spi.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
Comments
On Tue, 27 Dec 2022, Ivan Bornyakov wrote: > Original busy loop with retries count in mpf_poll_status() is not too > reliable, as it takes different times on different systems. Replace it > with read_poll_timeout() macro. > > While at it, fix polling stop condition to met function's original > intention declared in the comment. The issue with original polling stop > condition is that it stops if any of mask bits is set, while intention > was to stop if all mask bits is set. This was not noticible because only > MPF_STATUS_READY is passed as mask argument and it is BIT(1). > > Fixes: 5f8d4a900830 ("fpga: microchip-spi: add Microchip MPF FPGA manager") > Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru> > --- > drivers/fpga/microchip-spi.c | 24 ++++++++++-------------- > 1 file changed, 10 insertions(+), 14 deletions(-) > > diff --git a/drivers/fpga/microchip-spi.c b/drivers/fpga/microchip-spi.c > index e72fedd93a27..8d1d9476d0cc 100644 > --- a/drivers/fpga/microchip-spi.c > +++ b/drivers/fpga/microchip-spi.c > @@ -6,6 +6,7 @@ > #include <asm/unaligned.h> > #include <linux/delay.h> > #include <linux/fpga/fpga-mgr.h> > +#include <linux/iopoll.h> > #include <linux/module.h> > #include <linux/of_device.h> > #include <linux/spi/spi.h> > @@ -33,7 +34,7 @@ > > #define MPF_BITS_PER_COMPONENT_SIZE 22 > > -#define MPF_STATUS_POLL_RETRIES 10000 > +#define MPF_STATUS_POLL_TIMEOUT (2 * USEC_PER_SEC) > #define MPF_STATUS_BUSY BIT(0) > #define MPF_STATUS_READY BIT(1) > #define MPF_STATUS_SPI_VIOLATION BIT(2) > @@ -197,21 +198,16 @@ static int mpf_ops_parse_header(struct fpga_manager *mgr, > /* Poll HW status until busy bit is cleared and mask bits are set. */ > static int mpf_poll_status(struct mpf_priv *priv, u8 mask) > { > - int status, retries = MPF_STATUS_POLL_RETRIES; > + int ret, status; > > - while (retries--) { > - status = mpf_read_status(priv); > - if (status < 0) > - return status; > - > - if (status & MPF_STATUS_BUSY) > - continue; > - > - if (!mask || (status & mask)) > - return status; > - } > + ret = read_poll_timeout(mpf_read_status, status, > + (status < 0) || > + ((status & (MPF_STATUS_BUSY | mask)) == mask), > + 0, MPF_STATUS_POLL_TIMEOUT, false, priv); > + if (ret < 0) > + return ret; > > - return -EBUSY; > + return status; > } > > static int mpf_spi_write(struct mpf_priv *priv, const void *buf, size_t buf_size) Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
On Tue, Dec 27, 2022 at 01:04:49PM +0300, Ivan Bornyakov wrote: > Original busy loop with retries count in mpf_poll_status() is not too > reliable, as it takes different times on different systems. Replace it > with read_poll_timeout() macro. > > While at it, fix polling stop condition to met function's original > intention declared in the comment. The issue with original polling stop > condition is that it stops if any of mask bits is set, while intention > was to stop if all mask bits is set. This was not noticible because only > MPF_STATUS_READY is passed as mask argument and it is BIT(1). > > Fixes: 5f8d4a900830 ("fpga: microchip-spi: add Microchip MPF FPGA manager") > Signed-off-by: Ivan Bornyakov <i.bornyakov@metrotek.ru> > --- > drivers/fpga/microchip-spi.c | 24 ++++++++++-------------- > 1 file changed, 10 insertions(+), 14 deletions(-) > > diff --git a/drivers/fpga/microchip-spi.c b/drivers/fpga/microchip-spi.c > index e72fedd93a27..8d1d9476d0cc 100644 > --- a/drivers/fpga/microchip-spi.c > +++ b/drivers/fpga/microchip-spi.c > @@ -6,6 +6,7 @@ > #include <asm/unaligned.h> > #include <linux/delay.h> > #include <linux/fpga/fpga-mgr.h> > +#include <linux/iopoll.h> > #include <linux/module.h> > #include <linux/of_device.h> > #include <linux/spi/spi.h> > @@ -33,7 +34,7 @@ > > #define MPF_BITS_PER_COMPONENT_SIZE 22 > > -#define MPF_STATUS_POLL_RETRIES 10000 > +#define MPF_STATUS_POLL_TIMEOUT (2 * USEC_PER_SEC) > #define MPF_STATUS_BUSY BIT(0) > #define MPF_STATUS_READY BIT(1) > #define MPF_STATUS_SPI_VIOLATION BIT(2) > @@ -197,21 +198,16 @@ static int mpf_ops_parse_header(struct fpga_manager *mgr, > /* Poll HW status until busy bit is cleared and mask bits are set. */ > static int mpf_poll_status(struct mpf_priv *priv, u8 mask) > { > - int status, retries = MPF_STATUS_POLL_RETRIES; > + int ret, status; > > - while (retries--) { > - status = mpf_read_status(priv); > - if (status < 0) > - return status; > - > - if (status & MPF_STATUS_BUSY) > - continue; > - > - if (!mask || (status & mask)) > - return status; > - } Would you mind moving the small comment before the function down to here and mentioning handling the failure case? The current implementation is a bit easier to understand than the new version that's wrapped in read_poll_timeout(). Otherwise, change seems like a good idea. Acked-by: Conor Dooley <conor.dooley@microchip.com> > + ret = read_poll_timeout(mpf_read_status, status, > + (status < 0) || > + ((status & (MPF_STATUS_BUSY | mask)) == mask), > + if (ret < 0) > + return ret; > > - return -EBUSY; > + return status; > } > > static int mpf_spi_write(struct mpf_priv *priv, const void *buf, size_t buf_size) > -- > 2.38.2 > >
diff --git a/drivers/fpga/microchip-spi.c b/drivers/fpga/microchip-spi.c index e72fedd93a27..8d1d9476d0cc 100644 --- a/drivers/fpga/microchip-spi.c +++ b/drivers/fpga/microchip-spi.c @@ -6,6 +6,7 @@ #include <asm/unaligned.h> #include <linux/delay.h> #include <linux/fpga/fpga-mgr.h> +#include <linux/iopoll.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/spi/spi.h> @@ -33,7 +34,7 @@ #define MPF_BITS_PER_COMPONENT_SIZE 22 -#define MPF_STATUS_POLL_RETRIES 10000 +#define MPF_STATUS_POLL_TIMEOUT (2 * USEC_PER_SEC) #define MPF_STATUS_BUSY BIT(0) #define MPF_STATUS_READY BIT(1) #define MPF_STATUS_SPI_VIOLATION BIT(2) @@ -197,21 +198,16 @@ static int mpf_ops_parse_header(struct fpga_manager *mgr, /* Poll HW status until busy bit is cleared and mask bits are set. */ static int mpf_poll_status(struct mpf_priv *priv, u8 mask) { - int status, retries = MPF_STATUS_POLL_RETRIES; + int ret, status; - while (retries--) { - status = mpf_read_status(priv); - if (status < 0) - return status; - - if (status & MPF_STATUS_BUSY) - continue; - - if (!mask || (status & mask)) - return status; - } + ret = read_poll_timeout(mpf_read_status, status, + (status < 0) || + ((status & (MPF_STATUS_BUSY | mask)) == mask), + 0, MPF_STATUS_POLL_TIMEOUT, false, priv); + if (ret < 0) + return ret; - return -EBUSY; + return status; } static int mpf_spi_write(struct mpf_priv *priv, const void *buf, size_t buf_size)