Message ID | 20221116205308.2996556-3-msp@baylibre.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp56862wrr; Wed, 16 Nov 2022 12:55:16 -0800 (PST) X-Google-Smtp-Source: AA0mqf5rOC9QgI6QmRGZ4Xpxq9fvAZ4oyRxhQJuh0fe4ibbg2JOBkxdjir5n4dYEnLIGhHeoK5jJ X-Received: by 2002:a17:906:2354:b0:7ad:c8d6:bc7f with SMTP id m20-20020a170906235400b007adc8d6bc7fmr18806808eja.118.1668632116083; Wed, 16 Nov 2022 12:55:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668632116; cv=none; d=google.com; s=arc-20160816; b=nqjL4kEhWKU4G3KaF99WM/aybcPAfX3G7qnGiND2d/E+yV/621kma6UmXPlBU2AoQM aY4yfZlUS9LxYosMVTGj7bwGAUdpv8iaDPIpCAKJI1d2u7PU92sGsjA3HETYZIgo2oKg bDqAh5PCR8zyptUr6Qms3tXrPSow5QgcNeNQoCJ7uMpv30vl9bveS2jWni/m/Qic4jdG qp4aBPtsok3vjD2b8lJt2xk2s1PXx3rfjGMUVIDjcCkBzLbe3wpfcHW819xWw7qUeL9z Rk0mdRTDmMBWKCtmCLuKdcZjT7cGRivB5LhkbbH4N/BMmNhe2hOHvzkNyIGxQijyUmYJ bTEg== 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=ajsZbX3+twaGsWlZnthQH+DJqMTcB864bD+ktj1XJi8=; b=ExUmeBvNWXR+viXEgmakMc4H8ZUJGdos/N6GuyCxfff9h/SPZ9kus0Z39yxHElHLzF YS+p65G61zqV7glMw9hiVldPWXezr1kf/sOSld2mpKc9pX8wR/nQ/IoqKQf+E5kdPyP9 7vPhD+HtMj3Tx3ORZqZ1Dd/Z4UgQUdLVftix2p7/t84Y3NXZJPkvE7/rtf5yTxLJWrje WGp43LvlpvBJfBrCSY7G9OO2Y/mzXgeVD7NC9pd+VJxHjSJ5Zof8gXg8OZH67jwwYv2T O7YhBbDQ2W/cAKBP0n4B0wdJzsD/GY9ieVgTYpBL+jjBW9YwhGibkmAyeVvBLp9U4mXU rKMA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=cGyV6iSy; 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 k16-20020a17090666d000b00787abcb1ce0si13792674ejp.679.2022.11.16.12.54.52; Wed, 16 Nov 2022 12:55:16 -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=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=cGyV6iSy; 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 S237236AbiKPUyV (ORCPT <rfc822;just.gull.subs@gmail.com> + 99 others); Wed, 16 Nov 2022 15:54:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234040AbiKPUxq (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 16 Nov 2022 15:53:46 -0500 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B5752E27 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:53:27 -0800 (PST) Received: by mail-ed1-x52f.google.com with SMTP id z18so28438557edb.9 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:53:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ajsZbX3+twaGsWlZnthQH+DJqMTcB864bD+ktj1XJi8=; b=cGyV6iSyzBue0i5l97tQs1F/+bVMjgHav1MAY5Sp3ebIBKAF7rtEZUC/JmhiwCz45R rRQmwP4+vYFx1HAHkCDFG483CrsfEqHCo+WCCTFlJMKBWpByz9CHRlXEaEQXB15nQPg4 dVsPlUsn/h1qq8jjY1MBSrqbPNamW8aseozcmaPGAq5PLnSUxm1OYs1RIplM/W+npToS w+3jyD1we20/rAh/289ilWSbioDeGmbslRMCVMzHBoPyp6ZqDInmObMZhFFeJfhVg5b/ iuEhPle4TOpHkI0KN4kdg09gqWy6Y6GZf3f7H+fUL6eCG+EP6tv6oKJnBQ1vawL2Zg8+ FgpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ajsZbX3+twaGsWlZnthQH+DJqMTcB864bD+ktj1XJi8=; b=Iugrfh0fgXKug1UE6XoItx5uTaWQxWS8k+OXT+OjeOfbLTojaUwKLqBIXzFbEf8fk9 CjFLZuJnQ5wEtPqt55x9W2dCh3XFz6uBcoIKazI3VrdTT7uBOj3i57xmLG3/wJdimRuu KtJ/cMosNnT1kE5amh0lUxLFY4+z8tTt4vSZGj0bOB2LekioOI2ojG4lece9ArZENngF zwRHzkWWakr5JSariphkRQZ0D1Jfekl2i5/DyJNwoZUoFEB+ObjiCkXxZh5GR1vkQ0Ci l6eUPKJjCKVy1fMaOxIMXmcSZtITtDw5Y0/8lqjebNQe1jwabpFEUnGQiGe/2DFqSsA+ /oIg== X-Gm-Message-State: ANoB5pnEOtnatlGQWDmg1FL1pUl8DZIGT/DjXUQaXd5gEDF6dHWmAarL AKhUZHb+gQhEWhlBFobZmg1h9Q== X-Received: by 2002:aa7:d6cb:0:b0:467:e2dd:b593 with SMTP id x11-20020aa7d6cb000000b00467e2ddb593mr12985138edr.378.1668632005445; Wed, 16 Nov 2022 12:53:25 -0800 (PST) Received: from blmsp.fritz.box ([2001:4090:a244:804b:353b:565:addf:3aa7]) by smtp.gmail.com with ESMTPSA id kv17-20020a17090778d100b007aece68483csm6782828ejc.193.2022.11.16.12.53.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Nov 2022 12:53:24 -0800 (PST) From: Markus Schneider-Pargmann <msp@baylibre.com> To: Chandrasekar Ramakrishnan <rcsekar@samsung.com>, Marc Kleine-Budde <mkl@pengutronix.de>, Wolfgang Grandegger <wg@grandegger.com> Cc: linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Markus Schneider-Pargmann <msp@baylibre.com> Subject: [PATCH 02/15] can: m_can: Wakeup net queue once tx was issued Date: Wed, 16 Nov 2022 21:52:55 +0100 Message-Id: <20221116205308.2996556-3-msp@baylibre.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221116205308.2996556-1-msp@baylibre.com> References: <20221116205308.2996556-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 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?1749687589428357681?= X-GMAIL-MSGID: =?utf-8?q?1749687589428357681?= |
Series |
can: m_can: Optimizations for tcan and peripheral chips
|
|
Commit Message
Markus Schneider-Pargmann
Nov. 16, 2022, 8:52 p.m. UTC
Currently the driver waits to wakeup the queue until the interrupt for
the transmit event is received and acknowledged. If we want to use the
hardware FIFO, this is too late.
Instead release the queue as soon as the transmit was transferred into
the hardware FIFO. We are then ready for the next transmit to be
transferred.
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
drivers/net/can/m_can/m_can.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
Comments
On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > Currently the driver waits to wakeup the queue until the interrupt for > the transmit event is received and acknowledged. If we want to use the > hardware FIFO, this is too late. > > Instead release the queue as soon as the transmit was transferred into > the hardware FIFO. We are then ready for the next transmit to be > transferred. If you want to really speed up the TX path, remove the worker and use the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). Extra bonus if you implement xmit_more() and transfer more than 1 skb per SPI transfer. Marc
Hi Marc, On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > Currently the driver waits to wakeup the queue until the interrupt for > > the transmit event is received and acknowledged. If we want to use the > > hardware FIFO, this is too late. > > > > Instead release the queue as soon as the transmit was transferred into > > the hardware FIFO. We are then ready for the next transmit to be > > transferred. > > If you want to really speed up the TX path, remove the worker and use > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). Good idea. I will check how regmap's async_write works and if it is suitable to do the job. I don't want to drop the regmap usage for this right now. > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > per SPI transfer. That's on my todo list, but I am not sure I will get to it soonish. Thank you Marc!. Best, Markus
On 01.12.2022 09:43:02, Markus Schneider-Pargmann wrote: > Hi Marc, > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > Currently the driver waits to wakeup the queue until the interrupt for > > > the transmit event is received and acknowledged. If we want to use the > > > hardware FIFO, this is too late. > > > > > > Instead release the queue as soon as the transmit was transferred into > > > the hardware FIFO. We are then ready for the next transmit to be > > > transferred. > > > > If you want to really speed up the TX path, remove the worker and use > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > Good idea. I will check how regmap's async_write works and if it is > suitable to do the job. I don't want to drop the regmap usage for this > right now. IIRC regmap async write still uses mutexes, but sleeping is not allowed in the xmit handler. The mcp251xfd driver does the endianness conversion (and the optional CRC) manually for the TX path. Sending directly from the xmit handler basically eliminates the queuing between the network stack and the worker. Getting rid of the worker makes life easier and it's faster anyways. > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > per SPI transfer. > > That's on my todo list, but I am not sure I will get to it soonish. I haven't implemented this for the mcp251xfd, yet, but I have some proof-of-concept code somewhere. However, the mcp251xfd driver already implemented byte queue limits: 0084e298acfe ("can: mcp251xfd: add BQL support"). regards, Marc
Hi Marc, On Thu, Dec 01, 2022 at 10:16:05AM +0100, Marc Kleine-Budde wrote: > On 01.12.2022 09:43:02, Markus Schneider-Pargmann wrote: > > Hi Marc, > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > the transmit event is received and acknowledged. If we want to use the > > > > hardware FIFO, this is too late. > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > transferred. > > > > > > If you want to really speed up the TX path, remove the worker and use > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > Good idea. I will check how regmap's async_write works and if it is > > suitable to do the job. I don't want to drop the regmap usage for this > > right now. > > IIRC regmap async write still uses mutexes, but sleeping is not allowed > in the xmit handler. The mcp251xfd driver does the endianness conversion > (and the optional CRC) manually for the TX path. I just saw, you can force regmap to use spinlocks as well. But it uses the same operation for sync operations as well. > > Sending directly from the xmit handler basically eliminates the queuing > between the network stack and the worker. Getting rid of the worker > makes life easier and it's faster anyways. The current implementation of the driver doesn't really queue anything between the network stack and the worker. It is a queue of size 1 ;). To be honest I would rather focus on the other things than on getting rid of the worker completely as this can be done in a separate patch later as well. Yes I agree it would be nice to get rid of the worker but it is also probably not a major bottleneck for the performance and in its current state it works. If I have time left at the end I will be more than happy to do that. But for the moment I would just keep the worker as it is. Is that OK for you? Thanks, Markus > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > per SPI transfer. > > > > That's on my todo list, but I am not sure I will get to it soonish. > > I haven't implemented this for the mcp251xfd, yet, but I have some > proof-of-concept code somewhere. However, the mcp251xfd driver already > implemented byte queue limits: 0084e298acfe ("can: mcp251xfd: add BQL > support"). > > regards, > Marc > > -- > Pengutronix e.K. | Marc Kleine-Budde | > Embedded Linux | https://www.pengutronix.de | > Vertretung West/Dortmund | Phone: +49-231-2826-924 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On 01.12.2022 17:49:02, Markus Schneider-Pargmann wrote: > Hi Marc, > > On Thu, Dec 01, 2022 at 10:16:05AM +0100, Marc Kleine-Budde wrote: > > On 01.12.2022 09:43:02, Markus Schneider-Pargmann wrote: > > > Hi Marc, > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > hardware FIFO, this is too late. > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > transferred. > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > Good idea. I will check how regmap's async_write works and if it is > > > suitable to do the job. I don't want to drop the regmap usage for this > > > right now. > > > > IIRC regmap async write still uses mutexes, but sleeping is not allowed > > in the xmit handler. The mcp251xfd driver does the endianness conversion > > (and the optional CRC) manually for the TX path. > > I just saw, you can force regmap to use spinlocks as well. But it uses > the same operation for sync operations as well. But you cannot use sync SPI api under a spinlock. > > Sending directly from the xmit handler basically eliminates the queuing > > between the network stack and the worker. Getting rid of the worker > > makes life easier and it's faster anyways. > > The current implementation of the driver doesn't really queue anything > between the network stack and the worker. It is a queue of size 1 ;). Ok > To be honest I would rather focus on the other things than on getting > rid of the worker completely as this can be done in a separate patch > later as well. Yes I agree it would be nice to get rid of the worker but > it is also probably not a major bottleneck for the performance and in > its current state it works. If I have time left at the end I will be > more than happy to do that. But for the moment I would just keep the > worker as it is. Is that OK for you? Sure. Marc
On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > Currently the driver waits to wakeup the queue until the interrupt for > the transmit event is received and acknowledged. If we want to use the > hardware FIFO, this is too late. > > Instead release the queue as soon as the transmit was transferred into > the hardware FIFO. We are then ready for the next transmit to be > transferred. > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > --- > drivers/net/can/m_can/m_can.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > index 2c01e3f7b23f..4adf03111782 100644 > --- a/drivers/net/can/m_can/m_can.c > +++ b/drivers/net/can/m_can/m_can.c > @@ -1097,10 +1097,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) > /* New TX FIFO Element arrived */ > if (m_can_echo_tx_event(dev) != 0) > goto out_fail; > - > - if (netif_queue_stopped(dev) && > - !m_can_tx_fifo_full(cdev)) > + if (!cdev->tx_skb && netif_queue_stopped(dev)) > netif_wake_queue(dev); Please don't start the queue if the FIFO is still full. Is this a gamble, that it will take long enough until the work queue runs that the FIFO is not full anymore? > + Nitpick: Please don't introduce an extra newline here. > } > } > > @@ -1705,6 +1704,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > if (m_can_tx_fifo_full(cdev) || > m_can_next_echo_skb_occupied(dev, putidx)) > netif_stop_queue(dev); > + else if (cdev->is_peripheral && !cdev->tx_skb && netif_queue_stopped(dev)) > + netif_wake_queue(dev); Same question as above, what happens if the FIFO is full? e.g. in case of a slow bus or the first CAN frame in the FIFO has a low prio... > } > > return NETDEV_TX_OK; > -- > 2.38.1 > > Marc
Hi Marc, On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > Currently the driver waits to wakeup the queue until the interrupt for > > the transmit event is received and acknowledged. If we want to use the > > hardware FIFO, this is too late. > > > > Instead release the queue as soon as the transmit was transferred into > > the hardware FIFO. We are then ready for the next transmit to be > > transferred. > > If you want to really speed up the TX path, remove the worker and use > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > per SPI transfer. Just a quick question here, I mplemented a xmit_more() call and I am testing it right now, but it always returns false even under high pressure. The device has a txqueuelen set to 1000. Do I need to turn some other knob for this to work? Thanks, Markus
On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > Hi Marc, > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > Currently the driver waits to wakeup the queue until the interrupt for > > > the transmit event is received and acknowledged. If we want to use the > > > hardware FIFO, this is too late. > > > > > > Instead release the queue as soon as the transmit was transferred into > > > the hardware FIFO. We are then ready for the next transmit to be > > > transferred. > > > > If you want to really speed up the TX path, remove the worker and use > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > per SPI transfer. > > Just a quick question here, I mplemented a xmit_more() call and I am > testing it right now, but it always returns false even under high > pressure. The device has a txqueuelen set to 1000. Do I need to turn > some other knob for this to work? AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). The etas_es58x driver implements xmit_more(), I added the Author Vincent on Cc. Marc
On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > Hi Marc, > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > the transmit event is received and acknowledged. If we want to use the > > > > hardware FIFO, this is too late. > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > transferred. > > > > > > If you want to really speed up the TX path, remove the worker and use > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > per SPI transfer. > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > testing it right now, but it always returns false even under high > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > some other knob for this to work? > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > on Cc. Have a look at netdev_queue_set_dql_min_limit() in the etas driver. Marc
On Wed. 14 Dec. 2022 at 18:28, Marc Kleine-Budde <mkl@pengutronix.de> wrote: > On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > > Hi Marc, > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > hardware FIFO, this is too late. > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > transferred. > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > > per SPI transfer. > > > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > > testing it right now, but it always returns false even under high > > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > > some other knob for this to work? I was the first to use BQL in a CAN driver. It also took me time to first figure out the existence of xmit_more() and even more to understand how to make it so that it would return true. > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > > on Cc. > > Have a look at netdev_queue_set_dql_min_limit() in the etas driver. The functions you need are the netdev_send_queue() and the netdev_complete_queue(): https://elixir.bootlin.com/linux/latest/source/include/linux/netdevice.h#L3424 For CAN, you probably want to have a look to can_skb_get_frame_len(). https://elixir.bootlin.com/linux/latest/source/include/linux/can/length.h#L166 The netdev_queue_set_dql_min_limit() gives hints by setting a minimum value for BQL. It is optional (and as of today I am the only user of it). Yours sincerely, Vincent Mailhol
On Wed, Dec 14, 2022 at 10:22:01AM +0100, Marc Kleine-Budde wrote: > On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > > Hi Marc, > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > hardware FIFO, this is too late. > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > transferred. > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > > per SPI transfer. > > > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > > testing it right now, but it always returns false even under high > > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > > some other knob for this to work? > > > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > > on Cc. > > Have a look at netdev_queue_set_dql_min_limit() in the etas driver. Thank you, I need to implement BQL, I wasn't aware of that. I may need to delay this a bit just to get some feedback on the current state of my patches, so I know what I need to work on first. But it seems to be just accounting... Anyways, thank you :) Best, Markus
Hi Vincent, On Wed, Dec 14, 2022 at 07:15:25PM +0900, Vincent MAILHOL wrote: > On Wed. 14 Dec. 2022 at 18:28, Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > > > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > > > Hi Marc, > > > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > > hardware FIFO, this is too late. > > > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > > transferred. > > > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > > > per SPI transfer. > > > > > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > > > testing it right now, but it always returns false even under high > > > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > > > some other knob for this to work? > > I was the first to use BQL in a CAN driver. It also took me time to > first figure out the existence of xmit_more() and even more to > understand how to make it so that it would return true. > > > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > > > > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > > > on Cc. > > > > Have a look at netdev_queue_set_dql_min_limit() in the etas driver. > > The functions you need are the netdev_send_queue() and the > netdev_complete_queue(): > > https://elixir.bootlin.com/linux/latest/source/include/linux/netdevice.h#L3424 > > For CAN, you probably want to have a look to can_skb_get_frame_len(). > > https://elixir.bootlin.com/linux/latest/source/include/linux/can/length.h#L166 > > The netdev_queue_set_dql_min_limit() gives hints by setting a minimum > value for BQL. It is optional (and as of today I am the only user of > it). Thank you for this summary, great that you already invested the time to make it work with a CAN driver. I will give it a try in the m_can driver. Best, Markus
Hi, On Wed, Dec 14, 2022 at 11:35:43AM +0100, Markus Schneider-Pargmann wrote: > Hi Vincent, > > On Wed, Dec 14, 2022 at 07:15:25PM +0900, Vincent MAILHOL wrote: > > On Wed. 14 Dec. 2022 at 18:28, Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > > > > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > > > > Hi Marc, > > > > > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > > > hardware FIFO, this is too late. > > > > > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > > > transferred. > > > > > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > > > > per SPI transfer. > > > > > > > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > > > > testing it right now, but it always returns false even under high > > > > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > > > > some other knob for this to work? > > > > I was the first to use BQL in a CAN driver. It also took me time to > > first figure out the existence of xmit_more() and even more to > > understand how to make it so that it would return true. > > > > > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > > > > > > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > > > > on Cc. > > > > > > Have a look at netdev_queue_set_dql_min_limit() in the etas driver. > > > > The functions you need are the netdev_send_queue() and the > > netdev_complete_queue(): > > > > https://elixir.bootlin.com/linux/latest/source/include/linux/netdevice.h#L3424 > > > > For CAN, you probably want to have a look to can_skb_get_frame_len(). > > > > https://elixir.bootlin.com/linux/latest/source/include/linux/can/length.h#L166 > > > > The netdev_queue_set_dql_min_limit() gives hints by setting a minimum > > value for BQL. It is optional (and as of today I am the only user of > > it). > > Thank you for this summary, great that you already invested the time to > make it work with a CAN driver. I will give it a try in the m_can > driver. Thanks again, it looks like it is working after adding netdev_sent_queue and netdev_complete_queue. Best, Markus
On Thu. 15 Dec. 2022 at 18:44, Markus Schneider-Pargmann <msp@baylibre.com> wrote: > Hi, > > On Wed, Dec 14, 2022 at 11:35:43AM +0100, Markus Schneider-Pargmann wrote: > > Hi Vincent, > > > > On Wed, Dec 14, 2022 at 07:15:25PM +0900, Vincent MAILHOL wrote: > > > On Wed. 14 Dec. 2022 at 18:28, Marc Kleine-Budde <mkl@pengutronix.de> wrote: > > > > On 14.12.2022 10:18:20, Marc Kleine-Budde wrote: > > > > > On 14.12.2022 10:14:06, Markus Schneider-Pargmann wrote: > > > > > > Hi Marc, > > > > > > > > > > > > On Wed, Nov 30, 2022 at 06:21:00PM +0100, Marc Kleine-Budde wrote: > > > > > > > On 16.11.2022 21:52:55, Markus Schneider-Pargmann wrote: > > > > > > > > Currently the driver waits to wakeup the queue until the interrupt for > > > > > > > > the transmit event is received and acknowledged. If we want to use the > > > > > > > > hardware FIFO, this is too late. > > > > > > > > > > > > > > > > Instead release the queue as soon as the transmit was transferred into > > > > > > > > the hardware FIFO. We are then ready for the next transmit to be > > > > > > > > transferred. > > > > > > > > > > > > > > If you want to really speed up the TX path, remove the worker and use > > > > > > > the spi_async() API from the xmit callback, see mcp251xfd_start_xmit(). > > > > > > > > > > > > > > Extra bonus if you implement xmit_more() and transfer more than 1 skb > > > > > > > per SPI transfer. > > > > > > > > > > > > Just a quick question here, I mplemented a xmit_more() call and I am > > > > > > testing it right now, but it always returns false even under high > > > > > > pressure. The device has a txqueuelen set to 1000. Do I need to turn > > > > > > some other knob for this to work? > > > > > > I was the first to use BQL in a CAN driver. It also took me time to > > > first figure out the existence of xmit_more() and even more to > > > understand how to make it so that it would return true. > > > > > > > > AFAIK you need BQL support: see 0084e298acfe ("can: mcp251xfd: add BQL support"). > > > > > > > > > > The etas_es58x driver implements xmit_more(), I added the Author Vincent > > > > > on Cc. > > > > > > > > Have a look at netdev_queue_set_dql_min_limit() in the etas driver. > > > > > > The functions you need are the netdev_send_queue() and the > > > netdev_complete_queue(): > > > > > > https://elixir.bootlin.com/linux/latest/source/include/linux/netdevice.h#L3424 > > > > > > For CAN, you probably want to have a look to can_skb_get_frame_len(). > > > > > > https://elixir.bootlin.com/linux/latest/source/include/linux/can/length.h#L166 > > > > > > The netdev_queue_set_dql_min_limit() gives hints by setting a minimum > > > value for BQL. It is optional (and as of today I am the only user of > > > it). > > > > Thank you for this summary, great that you already invested the time to > > make it work with a CAN driver. I will give it a try in the m_can > > driver. > > Thanks again, it looks like it is working after adding netdev_sent_queue > and netdev_complete_queue. Happy to hear that :) A quick advice just in case: make sure to test the different error branches (failed TX, can_restart() after bus off…). Yours sincerely, Vincent Mailhol
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 2c01e3f7b23f..4adf03111782 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1097,10 +1097,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) /* New TX FIFO Element arrived */ if (m_can_echo_tx_event(dev) != 0) goto out_fail; - - if (netif_queue_stopped(dev) && - !m_can_tx_fifo_full(cdev)) + if (!cdev->tx_skb && netif_queue_stopped(dev)) netif_wake_queue(dev); + } } @@ -1705,6 +1704,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) if (m_can_tx_fifo_full(cdev) || m_can_next_echo_skb_occupied(dev, putidx)) netif_stop_queue(dev); + else if (cdev->is_peripheral && !cdev->tx_skb && netif_queue_stopped(dev)) + netif_wake_queue(dev); } return NETDEV_TX_OK;