Message ID | 20221116205308.2996556-5-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 q4csp56807wrr; Wed, 16 Nov 2022 12:55:06 -0800 (PST) X-Google-Smtp-Source: AA0mqf5hxnTfcLFNkNm+ut/HZ3N+zhwKREM2lxprk3JsFb7VVLAQmlrTkmrhyXBbdCzEJ46ScRHC X-Received: by 2002:a05:6402:2c8:b0:461:1f4c:36d0 with SMTP id b8-20020a05640202c800b004611f4c36d0mr19986613edx.310.1668632106057; Wed, 16 Nov 2022 12:55:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668632106; cv=none; d=google.com; s=arc-20160816; b=k4sJWtwgJjjH/N5r0a2vKQlp2pLUNcpsQtwrchHE/8vU1eImTzxflhSdQc6wO26WOb C2bSSRNAcRBOQRFTfsiB9rVLjm26xmBRecCzMTt33IzxJV9eKeW5SCrM7fgW12Kpq2vL DAnHoCOUnZnZC2I4WrhvEus6MHsIRvHorf4M91oL4G9KT53nbHvaBGYUWzkmE/RkAlbz sUPLGAwYM4eIrPf1NibqqFeUI7ijKZby33YQKx9BckpEXwrXk64Zu36rBusyUJbaJejx tstFPprgD7dR7ZThFKt9v8E+YFh3nIrCKkEWi7R06cvv9ki8PoCXubqOQOKZ1EKnwCF4 J1yg== 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=WAaUVMJZwNldvM6e6aFGn3ObvVWSf2L0v/SEyFHK/I4=; b=knnzT7YCcWgXGxoByOu6bnAnlHJ0gKW7m80V8ytSRkQXmjKU9uI1cT2LcsTmgjwzxr UpAq/kBoeMCYr/c0F721DejmWKcp+/az0WH7kfzQuXs2gFAyISsg2vXVTtpgYn/V0Zcm yG7F4/Hw1pzrj2sJ4DEkyn8t0YENsx/txY7g9JBL5rhDefR1d25J2p1Z/jTSxWETNj9r OQiL4B5BT5GHMl6t1R5IY80DMNcULxjSXeO86akO2gu/RGOC60DbYas8BunQ1xaJl0mP ZOHIRULoWQ+092xw+eICo2hR9hZuD7ERmbalseMcgyuudWLUbHmAakPw23RCBn2lOGm3 gGfQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=ltqQnT0E; 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 i14-20020a50870e000000b0045fc914660csi13336321edb.200.2022.11.16.12.54.43; Wed, 16 Nov 2022 12:55:06 -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=ltqQnT0E; 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 S234009AbiKPUyQ (ORCPT <rfc822;just.gull.subs@gmail.com> + 99 others); Wed, 16 Nov 2022 15:54:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234379AbiKPUxr (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 16 Nov 2022 15:53:47 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13B2DF25 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:53:28 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id t25so47115074ejb.8 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:53:28 -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=WAaUVMJZwNldvM6e6aFGn3ObvVWSf2L0v/SEyFHK/I4=; b=ltqQnT0EMFXwbpNbg9tdXI3avhCvHSr0oRUgU1tqw7+Unw0j+hl2GIavNu3ounoJDP nvNUC7Rd2dmnkcoByRgHQMhN2Jt4l1/KXgNv0sSJb+TiuAeuqfAnAJz5atJAXnGg99H8 UpdwG2F5AtucQXp6D8/Scz6aeCIdU8MXHn8EVGBz5ESYLLQRzTAbbP/gp6ksMxMJbCts Gs6tbhKZub13E96iZdU3qWuiP2WpqlcvYHSxlnDAJkidA4ULgmmj2hDHWbdq79H5FxsM g7iR8wYul79Lf08h1AekXk82Zcmmsk6LgHF6aSPOCqsOPbaSii3ag97VLOF4Qql2/YYp uN1A== 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=WAaUVMJZwNldvM6e6aFGn3ObvVWSf2L0v/SEyFHK/I4=; b=4Hj8FQgeoP6aly7cUz2CQd8ahT7sl6aqUbXIXmrHMp5JXllP6lGvqLLB1csBJ2ju91 0p9r3YaMSmJsks7KnlGz9ADiTr210vj+6TGIorj/IfC0+LdPFL1qQUuQ32hcXPFBE7Vu 7qq7CsSnlj9B96Dg3Z1XqjOdch9W9NC1UcZaz4DD4tSZdItZ6pVF11LROuPtfPPX3e2q J2rqRwCZjl9ZYUn2HNeVpw2iZRNUGiWmz8hZWwxx3DwcEnfTxqw9bogpldxiGCSV1JYR u2tUBUzinqFwsxF4EfNNf6uEcQiMI2MSpEK2r/vQxOeL3T0JuuTTNKnpjS7tfjo3VPPM 5udA== X-Gm-Message-State: ANoB5pmU/pLG/1lSqd5HQMJ/VQfjnGoJ5RI/tMxyXEuk2ViyXYep6sz/ kjwYvB/34Rn+6y7XeSVCLTBFQA== X-Received: by 2002:a17:906:33da:b0:78d:b046:aaae with SMTP id w26-20020a17090633da00b0078db046aaaemr18417533eja.218.1668632007251; Wed, 16 Nov 2022 12:53:27 -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.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Nov 2022 12:53:26 -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 04/15] can: m_can: Use transmit event FIFO watermark level interrupt Date: Wed, 16 Nov 2022 21:52:57 +0100 Message-Id: <20221116205308.2996556-5-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=ham 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?1749687579619873903?= X-GMAIL-MSGID: =?utf-8?q?1749687579619873903?= |
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 only mode of operation is an interrupt for every transmit
event. This is inefficient for peripheral chips. Use the transmit FIFO
event watermark interrupt instead if the FIFO size is more than 2. Use
FIFOsize - 1 for the watermark so the interrupt is triggered early
enough to not stop transmitting.
Note that if the number of transmits is less than the watermark level,
the transmit events will not be processed until there is any other
interrupt. This will only affect statistic counters. Also there is an
interrupt every time the timestamp wraps around.
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
drivers/net/can/m_can/m_can.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
Comments
On 16.11.2022 21:52:57, Markus Schneider-Pargmann wrote: > Currently the only mode of operation is an interrupt for every transmit > event. This is inefficient for peripheral chips. Use the transmit FIFO > event watermark interrupt instead if the FIFO size is more than 2. Use > FIFOsize - 1 for the watermark so the interrupt is triggered early > enough to not stop transmitting. > > Note that if the number of transmits is less than the watermark level, > the transmit events will not be processed until there is any other > interrupt. This will only affect statistic counters. Also there is an > interrupt every time the timestamp wraps around. > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> Please make this configurable with the ethtool TX IRQ coalescing parameter. Please setup an hwtimer to enable the regular interrupt after some configurable time to avoid starving of the TX complete events. I've implemented this for the mcp251xfd driver, see: 656fc12ddaf8 ("can: mcp251xfd: add TX IRQ coalescing ethtool support") 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") 846990e0ed82 ("can: mcp251xfd: add RX IRQ coalescing ethtool support") 60a848c50d2d ("can: mcp251xfd: add RX IRQ coalescing support") 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") Marc
Hi Marc, Thanks for reviewing. On Wed, Nov 30, 2022 at 06:17:15PM +0100, Marc Kleine-Budde wrote: > On 16.11.2022 21:52:57, Markus Schneider-Pargmann wrote: > > Currently the only mode of operation is an interrupt for every transmit > > event. This is inefficient for peripheral chips. Use the transmit FIFO > > event watermark interrupt instead if the FIFO size is more than 2. Use > > FIFOsize - 1 for the watermark so the interrupt is triggered early > > enough to not stop transmitting. > > > > Note that if the number of transmits is less than the watermark level, > > the transmit events will not be processed until there is any other > > interrupt. This will only affect statistic counters. Also there is an > > interrupt every time the timestamp wraps around. > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > Please make this configurable with the ethtool TX IRQ coalescing > parameter. Please setup an hwtimer to enable the regular interrupt after > some configurable time to avoid starving of the TX complete events. I guess hwtimer==hrtimer? I thought about setting up a timer but decided against it as the TX completion events are only used to update statistics of the interface, as far as I can tell. I can implement a timer as well. For the upcoming receive side patch I already added a hrtimer. I may try to use the same timer for both directions as it is going to do the exact same thing in both cases (call the interrupt routine). Of course that depends on the details of the coalescing support. Any objections on that? > I've implemented this for the mcp251xfd driver, see: > > 656fc12ddaf8 ("can: mcp251xfd: add TX IRQ coalescing ethtool support") > 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") > 846990e0ed82 ("can: mcp251xfd: add RX IRQ coalescing ethtool support") > 60a848c50d2d ("can: mcp251xfd: add RX IRQ coalescing support") > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") Thanks for the pointers. I will have a look and try to implement it similarly. Best, Markus
On 01.12.2022 09:25:21, Markus Schneider-Pargmann wrote: > Hi Marc, > > Thanks for reviewing. > > On Wed, Nov 30, 2022 at 06:17:15PM +0100, Marc Kleine-Budde wrote: > > On 16.11.2022 21:52:57, Markus Schneider-Pargmann wrote: > > > Currently the only mode of operation is an interrupt for every transmit > > > event. This is inefficient for peripheral chips. Use the transmit FIFO > > > event watermark interrupt instead if the FIFO size is more than 2. Use > > > FIFOsize - 1 for the watermark so the interrupt is triggered early > > > enough to not stop transmitting. > > > > > > Note that if the number of transmits is less than the watermark level, > > > the transmit events will not be processed until there is any other > > > interrupt. This will only affect statistic counters. Also there is an > > > interrupt every time the timestamp wraps around. > > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > > > Please make this configurable with the ethtool TX IRQ coalescing > > parameter. Please setup an hwtimer to enable the regular interrupt after > > some configurable time to avoid starving of the TX complete events. > > I guess hwtimer==hrtimer? Sorry, yes! > I thought about setting up a timer but decided against it as the TX > completion events are only used to update statistics of the interface, > as far as I can tell. I can implement a timer as well. It's not only statistics, the sending socket can opt in to receive the sent CAN frame on successful transmission. Other sockets will (by default) receive successful sent CAN frames. The idea is that the other sockets see the same CAN bus, doesn't matter if they are on a different system receiving the CAN frame via the bus or on the same system receiving the CAN frame as soon it has been sent to the bus. > For the upcoming receive side patch I already added a hrtimer. I may try > to use the same timer for both directions as it is going to do the exact > same thing in both cases (call the interrupt routine). Of course that > depends on the details of the coalescing support. Any objections on > that? For the mcp251xfd I implemented the RX and TX coalescing independent of each other and made it configurable via ethtool's IRQ coalescing options. The hardware doesn't support any timeouts and only FIFO not empty, FIFO half full and FIFO full IRQs and the on chip RAM for mailboxes is rather limited. I think the mcan core has the same limitations. The configuration for the mcp251xfd looks like this: - First decide for classical CAN or CAN-FD mode - configure RX and TX ring size 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") For TX only a single FIFO is used. For RX up to 3 FIFOs (up to a depth of 32 each). FIFO depth is limited to power of 2. On the mcan cores this is currently done with a DT property. Runtime configurable ring size is optional but gives more flexibility for our use-cases due to limited RAM size. - configure RX and TX coalescing via ethtools Set a timeout and the max CAN frames to coalesce. The max frames are limited to half or full FIFO. How does coalescing work? If coalescing is activated during reading of the RX'ed frames the FIFO not empty IRQ is disabled (the half or full IRQ stays enabled). After handling the RX'ed frames a hrtimer is started. In the hrtimer's functions the FIFO not empty IRQ is enabled again. I decided not to call the IRQ handler from the hrtimer to avoid concurrency, but enable the FIFO not empty IRQ. > > I've implemented this for the mcp251xfd driver, see: > > > > 656fc12ddaf8 ("can: mcp251xfd: add TX IRQ coalescing ethtool support") > > 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") > > 846990e0ed82 ("can: mcp251xfd: add RX IRQ coalescing ethtool support") > > 60a848c50d2d ("can: mcp251xfd: add RX IRQ coalescing support") > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > Thanks for the pointers. I will have a look and try to implement it > similarly. If you want to implement runtime configurable ring size, I created a function to help in the calculation of the ring sizes: a1439a5add62 ("can: mcp251xfd: ram: add helper function for runtime ring size calculation") The code is part of the mcp251xfd driver, but is prepared to become a generic helper function. The HW parameters are described with struct can_ram_config and use you can_ram_get_layout() to get a valid RAM layout based on CAN/CAN-FD ring size and coalescing parameters. regards, Marc
HI Marc, On Thu, Dec 01, 2022 at 10:05:08AM +0100, Marc Kleine-Budde wrote: > On 01.12.2022 09:25:21, Markus Schneider-Pargmann wrote: > > Hi Marc, > > > > Thanks for reviewing. > > > > On Wed, Nov 30, 2022 at 06:17:15PM +0100, Marc Kleine-Budde wrote: > > > On 16.11.2022 21:52:57, Markus Schneider-Pargmann wrote: > > > > Currently the only mode of operation is an interrupt for every transmit > > > > event. This is inefficient for peripheral chips. Use the transmit FIFO > > > > event watermark interrupt instead if the FIFO size is more than 2. Use > > > > FIFOsize - 1 for the watermark so the interrupt is triggered early > > > > enough to not stop transmitting. > > > > > > > > Note that if the number of transmits is less than the watermark level, > > > > the transmit events will not be processed until there is any other > > > > interrupt. This will only affect statistic counters. Also there is an > > > > interrupt every time the timestamp wraps around. > > > > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > > > > > Please make this configurable with the ethtool TX IRQ coalescing > > > parameter. Please setup an hwtimer to enable the regular interrupt after > > > some configurable time to avoid starving of the TX complete events. > > > > I guess hwtimer==hrtimer? > > Sorry, yes! > > > I thought about setting up a timer but decided against it as the TX > > completion events are only used to update statistics of the interface, > > as far as I can tell. I can implement a timer as well. > > It's not only statistics, the sending socket can opt in to receive the > sent CAN frame on successful transmission. Other sockets will (by > default) receive successful sent CAN frames. The idea is that the other > sockets see the same CAN bus, doesn't matter if they are on a different > system receiving the CAN frame via the bus or on the same system > receiving the CAN frame as soon it has been sent to the bus. Thanks for explaining. I wasn't aware of that. I agree on the timer then. > > > For the upcoming receive side patch I already added a hrtimer. I may try > > to use the same timer for both directions as it is going to do the exact > > same thing in both cases (call the interrupt routine). Of course that > > depends on the details of the coalescing support. Any objections on > > that? > > For the mcp251xfd I implemented the RX and TX coalescing independent of > each other and made it configurable via ethtool's IRQ coalescing > options. > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > limited. I think the mcan core has the same limitations. Yes and no, the mcan core provides watermark levels so it has more options, but there is no hardware timer as well (at least I didn't see anything usable). > > The configuration for the mcp251xfd looks like this: > > - First decide for classical CAN or CAN-FD mode > - configure RX and TX ring size > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > For TX only a single FIFO is used. > For RX up to 3 FIFOs (up to a depth of 32 each). > FIFO depth is limited to power of 2. > On the mcan cores this is currently done with a DT property. > Runtime configurable ring size is optional but gives more flexibility > for our use-cases due to limited RAM size. > - configure RX and TX coalescing via ethtools > Set a timeout and the max CAN frames to coalesce. > The max frames are limited to half or full FIFO. mcan can offer more options for the max frames limit fortunately. > > How does coalescing work? > > If coalescing is activated during reading of the RX'ed frames the FIFO > not empty IRQ is disabled (the half or full IRQ stays enabled). After > handling the RX'ed frames a hrtimer is started. In the hrtimer's > functions the FIFO not empty IRQ is enabled again. My rx path patches are working similarly though not 100% the same. I will adopt everything and add it to the next version of this series. > > I decided not to call the IRQ handler from the hrtimer to avoid > concurrency, but enable the FIFO not empty IRQ. mcan uses a threaded irq and I found this nice helper function I am currently using for the receive path. irq_wake_thread() It is not widely used so I hope this is fine. But this hopefully avoids the concurrency issue. Also I don't need to artificially create an IRQ as you do. > > > > I've implemented this for the mcp251xfd driver, see: > > > > > > 656fc12ddaf8 ("can: mcp251xfd: add TX IRQ coalescing ethtool support") > > > 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") > > > 846990e0ed82 ("can: mcp251xfd: add RX IRQ coalescing ethtool support") > > > 60a848c50d2d ("can: mcp251xfd: add RX IRQ coalescing support") > > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > > > Thanks for the pointers. I will have a look and try to implement it > > similarly. > > If you want to implement runtime configurable ring size, I created a > function to help in the calculation of the ring sizes: > > a1439a5add62 ("can: mcp251xfd: ram: add helper function for runtime ring size calculation") > > The code is part of the mcp251xfd driver, but is prepared to become a > generic helper function. The HW parameters are described with struct > can_ram_config and use you can_ram_get_layout() to get a valid RAM > layout based on CAN/CAN-FD ring size and coalescing parameters. Thank you. I think configurable ring sizes are currently out of scope for me as I only have limited time for this. Thank you Marc! Best, Markus
On 01.12.2022 11:12:20, Markus Schneider-Pargmann wrote: > > > For the upcoming receive side patch I already added a hrtimer. I may try > > > to use the same timer for both directions as it is going to do the exact > > > same thing in both cases (call the interrupt routine). Of course that > > > depends on the details of the coalescing support. Any objections on > > > that? > > > > For the mcp251xfd I implemented the RX and TX coalescing independent of > > each other and made it configurable via ethtool's IRQ coalescing > > options. > > > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > > limited. I think the mcan core has the same limitations. > > Yes and no, the mcan core provides watermark levels so it has more > options, but there is no hardware timer as well (at least I didn't see > anything usable). Are there any limitations to the water mark level? > > The configuration for the mcp251xfd looks like this: > > > > - First decide for classical CAN or CAN-FD mode > > - configure RX and TX ring size > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > For TX only a single FIFO is used. > > For RX up to 3 FIFOs (up to a depth of 32 each). > > FIFO depth is limited to power of 2. > > On the mcan cores this is currently done with a DT property. > > Runtime configurable ring size is optional but gives more flexibility > > for our use-cases due to limited RAM size. > > - configure RX and TX coalescing via ethtools > > Set a timeout and the max CAN frames to coalesce. > > The max frames are limited to half or full FIFO. > > mcan can offer more options for the max frames limit fortunately. > > > > > How does coalescing work? > > > > If coalescing is activated during reading of the RX'ed frames the FIFO > > not empty IRQ is disabled (the half or full IRQ stays enabled). After > > handling the RX'ed frames a hrtimer is started. In the hrtimer's > > functions the FIFO not empty IRQ is enabled again. > > My rx path patches are working similarly though not 100% the same. I > will adopt everything and add it to the next version of this series. > > > > > I decided not to call the IRQ handler from the hrtimer to avoid > > concurrency, but enable the FIFO not empty IRQ. > > mcan uses a threaded irq and I found this nice helper function I am > currently using for the receive path. > irq_wake_thread() > > It is not widely used so I hope this is fine. But this hopefully avoids > the concurrency issue. Also I don't need to artificially create an IRQ > as you do. I think it's Ok to use the function. Which IRQs are enabled after you leave the RX handler? The mcp251xfd driver enables only a high watermark IRQ and sets up the hrtimer. Then we have 3 scenarios: - high watermark IRQ triggers -> IRQ is handled, - FIFO level between 0 and high water mark -> no IRQ triggered, but hrtimer will run, irq_wake_thread() is called, IRQ is handled - FIFO level 0 -> no IRQ triggered, hrtimer will run. What do you do in the IRQ handler? Check if FIFO is empty and enable the FIFO not empty IRQ? The mcp251xfd unconditionally enables the FIFO not empty IRQ in the hrtimer. This avoids reading of the FIFO fill level. [...] > > If you want to implement runtime configurable ring size, I created a > > function to help in the calculation of the ring sizes: > > > > a1439a5add62 ("can: mcp251xfd: ram: add helper function for runtime ring size calculation") > > > > The code is part of the mcp251xfd driver, but is prepared to become a > > generic helper function. The HW parameters are described with struct > > can_ram_config and use you can_ram_get_layout() to get a valid RAM > > layout based on CAN/CAN-FD ring size and coalescing parameters. > > Thank you. I think configurable ring sizes are currently out of scope > for me as I only have limited time for this. Ok. regards, Marc
On Thu, Dec 01, 2022 at 12:00:33PM +0100, Marc Kleine-Budde wrote: > On 01.12.2022 11:12:20, Markus Schneider-Pargmann wrote: > > > > For the upcoming receive side patch I already added a hrtimer. I may try > > > > to use the same timer for both directions as it is going to do the exact > > > > same thing in both cases (call the interrupt routine). Of course that > > > > depends on the details of the coalescing support. Any objections on > > > > that? > > > > > > For the mcp251xfd I implemented the RX and TX coalescing independent of > > > each other and made it configurable via ethtool's IRQ coalescing > > > options. > > > > > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > > > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > > > limited. I think the mcan core has the same limitations. > > > > Yes and no, the mcan core provides watermark levels so it has more > > options, but there is no hardware timer as well (at least I didn't see > > anything usable). > > Are there any limitations to the water mark level? Anything specific? I can't really see any limitation. You can set the watermark between 1 and 32. I guess we could also always use it instead of the new-element interrupt, but I haven't tried that yet. That may simplify the code. > > > > The configuration for the mcp251xfd looks like this: > > > > > > - First decide for classical CAN or CAN-FD mode > > > - configure RX and TX ring size > > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > > For TX only a single FIFO is used. > > > For RX up to 3 FIFOs (up to a depth of 32 each). > > > FIFO depth is limited to power of 2. > > > On the mcan cores this is currently done with a DT property. > > > Runtime configurable ring size is optional but gives more flexibility > > > for our use-cases due to limited RAM size. > > > - configure RX and TX coalescing via ethtools > > > Set a timeout and the max CAN frames to coalesce. > > > The max frames are limited to half or full FIFO. > > > > mcan can offer more options for the max frames limit fortunately. > > > > > > > > How does coalescing work? > > > > > > If coalescing is activated during reading of the RX'ed frames the FIFO > > > not empty IRQ is disabled (the half or full IRQ stays enabled). After > > > handling the RX'ed frames a hrtimer is started. In the hrtimer's > > > functions the FIFO not empty IRQ is enabled again. > > > > My rx path patches are working similarly though not 100% the same. I > > will adopt everything and add it to the next version of this series. > > > > > > > > I decided not to call the IRQ handler from the hrtimer to avoid > > > concurrency, but enable the FIFO not empty IRQ. > > > > mcan uses a threaded irq and I found this nice helper function I am > > currently using for the receive path. > > irq_wake_thread() > > > > It is not widely used so I hope this is fine. But this hopefully avoids > > the concurrency issue. Also I don't need to artificially create an IRQ > > as you do. > > I think it's Ok to use the function. Which IRQs are enabled after you > leave the RX handler? The mcp251xfd driver enables only a high watermark > IRQ and sets up the hrtimer. Then we have 3 scenarios: > - high watermark IRQ triggers -> IRQ is handled, > - FIFO level between 0 and high water mark -> no IRQ triggered, but > hrtimer will run, irq_wake_thread() is called, IRQ is handled > - FIFO level 0 -> no IRQ triggered, hrtimer will run. What do you do in > the IRQ handler? Check if FIFO is empty and enable the FIFO not empty > IRQ? I am currently doing the normal IRQ handler run. It checks the "Interrupt Register" at the beginning. This register does not show the interrupts that fired, it shows the status. So even though the watermark interrupt didn't trigger when called by a timer, RF0N 'new message' status bit is still set if there is something new in the FIFO. Of course it is the same for the transmit status bits. So there is no need to read the FIFO fill levels directly, just the general status register. Best, Markus
On 01.12.2022 17:59:51, Markus Schneider-Pargmann wrote: > On Thu, Dec 01, 2022 at 12:00:33PM +0100, Marc Kleine-Budde wrote: > > On 01.12.2022 11:12:20, Markus Schneider-Pargmann wrote: > > > > > For the upcoming receive side patch I already added a hrtimer. I may try > > > > > to use the same timer for both directions as it is going to do the exact > > > > > same thing in both cases (call the interrupt routine). Of course that > > > > > depends on the details of the coalescing support. Any objections on > > > > > that? > > > > > > > > For the mcp251xfd I implemented the RX and TX coalescing independent of > > > > each other and made it configurable via ethtool's IRQ coalescing > > > > options. > > > > > > > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > > > > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > > > > limited. I think the mcan core has the same limitations. > > > > > > Yes and no, the mcan core provides watermark levels so it has more > > > options, but there is no hardware timer as well (at least I didn't see > > > anything usable). > > > > Are there any limitations to the water mark level? > > Anything specific? I can't really see any limitation. You can set the > watermark between 1 and 32. I guess we could also always use it instead > of the new-element interrupt, but I haven't tried that yet. That may > simplify the code. Makes sense. > > > > The configuration for the mcp251xfd looks like this: > > > > > > > > - First decide for classical CAN or CAN-FD mode > > > > - configure RX and TX ring size > > > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > > > For TX only a single FIFO is used. > > > > For RX up to 3 FIFOs (up to a depth of 32 each). > > > > FIFO depth is limited to power of 2. > > > > On the mcan cores this is currently done with a DT property. > > > > Runtime configurable ring size is optional but gives more flexibility > > > > for our use-cases due to limited RAM size. > > > > - configure RX and TX coalescing via ethtools > > > > Set a timeout and the max CAN frames to coalesce. > > > > The max frames are limited to half or full FIFO. > > > > > > mcan can offer more options for the max frames limit fortunately. > > > > > > > > > > > How does coalescing work? > > > > > > > > If coalescing is activated during reading of the RX'ed frames the FIFO > > > > not empty IRQ is disabled (the half or full IRQ stays enabled). After > > > > handling the RX'ed frames a hrtimer is started. In the hrtimer's > > > > functions the FIFO not empty IRQ is enabled again. > > > > > > My rx path patches are working similarly though not 100% the same. I > > > will adopt everything and add it to the next version of this series. > > > > > > > > > > > I decided not to call the IRQ handler from the hrtimer to avoid > > > > concurrency, but enable the FIFO not empty IRQ. > > > > > > mcan uses a threaded irq and I found this nice helper function I am > > > currently using for the receive path. > > > irq_wake_thread() > > > > > > It is not widely used so I hope this is fine. But this hopefully avoids > > > the concurrency issue. Also I don't need to artificially create an IRQ > > > as you do. > > > > I think it's Ok to use the function. Which IRQs are enabled after you > > leave the RX handler? The mcp251xfd driver enables only a high watermark > > IRQ and sets up the hrtimer. Then we have 3 scenarios: > > - high watermark IRQ triggers -> IRQ is handled, > > - FIFO level between 0 and high water mark -> no IRQ triggered, but > > hrtimer will run, irq_wake_thread() is called, IRQ is handled > > - FIFO level 0 -> no IRQ triggered, hrtimer will run. What do you do in > > the IRQ handler? Check if FIFO is empty and enable the FIFO not empty > > IRQ? > > I am currently doing the normal IRQ handler run. It checks the > "Interrupt Register" at the beginning. This register does not show the > interrupts that fired, it shows the status. So even though the watermark > interrupt didn't trigger when called by a timer, RF0N 'new message' > status bit is still set if there is something new in the FIFO. That covers scenario 2 from above. > Of course it is the same for the transmit status bits. ACK - The TX complete event handling is a 95% copy/paste of the RX handling. > So there is no need to read the FIFO fill levels directly, just the > general status register. What do you do if the hrtimer fires and there's no CAN frame waiting in the FIFO? Marc
On Fri, Dec 02, 2022 at 10:23:06AM +0100, Marc Kleine-Budde wrote: ... > > > > > The configuration for the mcp251xfd looks like this: > > > > > > > > > > - First decide for classical CAN or CAN-FD mode > > > > > - configure RX and TX ring size > > > > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > > > > For TX only a single FIFO is used. > > > > > For RX up to 3 FIFOs (up to a depth of 32 each). > > > > > FIFO depth is limited to power of 2. > > > > > On the mcan cores this is currently done with a DT property. > > > > > Runtime configurable ring size is optional but gives more flexibility > > > > > for our use-cases due to limited RAM size. > > > > > - configure RX and TX coalescing via ethtools > > > > > Set a timeout and the max CAN frames to coalesce. > > > > > The max frames are limited to half or full FIFO. > > > > > > > > mcan can offer more options for the max frames limit fortunately. > > > > > > > > > > > > > > How does coalescing work? > > > > > > > > > > If coalescing is activated during reading of the RX'ed frames the FIFO > > > > > not empty IRQ is disabled (the half or full IRQ stays enabled). After > > > > > handling the RX'ed frames a hrtimer is started. In the hrtimer's > > > > > functions the FIFO not empty IRQ is enabled again. > > > > > > > > My rx path patches are working similarly though not 100% the same. I > > > > will adopt everything and add it to the next version of this series. > > > > > > > > > > > > > > I decided not to call the IRQ handler from the hrtimer to avoid > > > > > concurrency, but enable the FIFO not empty IRQ. > > > > > > > > mcan uses a threaded irq and I found this nice helper function I am > > > > currently using for the receive path. > > > > irq_wake_thread() > > > > > > > > It is not widely used so I hope this is fine. But this hopefully avoids > > > > the concurrency issue. Also I don't need to artificially create an IRQ > > > > as you do. > > > > > > I think it's Ok to use the function. Which IRQs are enabled after you > > > leave the RX handler? The mcp251xfd driver enables only a high watermark > > > IRQ and sets up the hrtimer. Then we have 3 scenarios: > > > - high watermark IRQ triggers -> IRQ is handled, > > > - FIFO level between 0 and high water mark -> no IRQ triggered, but > > > hrtimer will run, irq_wake_thread() is called, IRQ is handled > > > - FIFO level 0 -> no IRQ triggered, hrtimer will run. What do you do in > > > the IRQ handler? Check if FIFO is empty and enable the FIFO not empty > > > IRQ? > > > > I am currently doing the normal IRQ handler run. It checks the > > "Interrupt Register" at the beginning. This register does not show the > > interrupts that fired, it shows the status. So even though the watermark > > interrupt didn't trigger when called by a timer, RF0N 'new message' > > status bit is still set if there is something new in the FIFO. > > That covers scenario 2 from above. > > > Of course it is the same for the transmit status bits. > > ACK - The TX complete event handling is a 95% copy/paste of the RX > handling. > > > So there is no need to read the FIFO fill levels directly, just the > > general status register. > > What do you do if the hrtimer fires and there's no CAN frame waiting in > the FIFO? Just enabling the 'new item' interrupt again and keep the hrtimer disabled. Best, Markus
On 02.12.2022 10:43:46, Markus Schneider-Pargmann wrote: > On Fri, Dec 02, 2022 at 10:23:06AM +0100, Marc Kleine-Budde wrote: > ... > > > > > > The configuration for the mcp251xfd looks like this: > > > > > > > > > > > > - First decide for classical CAN or CAN-FD mode > > > > > > - configure RX and TX ring size > > > > > > 9263c2e92be9 ("can: mcp251xfd: ring: add support for runtime configurable RX/TX ring parameters") > > > > > > For TX only a single FIFO is used. > > > > > > For RX up to 3 FIFOs (up to a depth of 32 each). > > > > > > FIFO depth is limited to power of 2. > > > > > > On the mcan cores this is currently done with a DT property. > > > > > > Runtime configurable ring size is optional but gives more flexibility > > > > > > for our use-cases due to limited RAM size. > > > > > > - configure RX and TX coalescing via ethtools > > > > > > Set a timeout and the max CAN frames to coalesce. > > > > > > The max frames are limited to half or full FIFO. > > > > > > > > > > mcan can offer more options for the max frames limit fortunately. > > > > > > > > > > > > > > > > > How does coalescing work? > > > > > > > > > > > > If coalescing is activated during reading of the RX'ed frames the FIFO > > > > > > not empty IRQ is disabled (the half or full IRQ stays enabled). After > > > > > > handling the RX'ed frames a hrtimer is started. In the hrtimer's > > > > > > functions the FIFO not empty IRQ is enabled again. > > > > > > > > > > My rx path patches are working similarly though not 100% the same. I > > > > > will adopt everything and add it to the next version of this series. > > > > > > > > > > > > > > > > > I decided not to call the IRQ handler from the hrtimer to avoid > > > > > > concurrency, but enable the FIFO not empty IRQ. > > > > > > > > > > mcan uses a threaded irq and I found this nice helper function I am > > > > > currently using for the receive path. > > > > > irq_wake_thread() > > > > > > > > > > It is not widely used so I hope this is fine. But this hopefully avoids > > > > > the concurrency issue. Also I don't need to artificially create an IRQ > > > > > as you do. > > > > > > > > I think it's Ok to use the function. Which IRQs are enabled after you > > > > leave the RX handler? The mcp251xfd driver enables only a high watermark > > > > IRQ and sets up the hrtimer. Then we have 3 scenarios: > > > > - high watermark IRQ triggers -> IRQ is handled, > > > > - FIFO level between 0 and high water mark -> no IRQ triggered, but > > > > hrtimer will run, irq_wake_thread() is called, IRQ is handled > > > > - FIFO level 0 -> no IRQ triggered, hrtimer will run. What do you do in > > > > the IRQ handler? Check if FIFO is empty and enable the FIFO not empty > > > > IRQ? > > > > > > I am currently doing the normal IRQ handler run. It checks the > > > "Interrupt Register" at the beginning. This register does not show the > > > interrupts that fired, it shows the status. So even though the watermark > > > interrupt didn't trigger when called by a timer, RF0N 'new message' > > > status bit is still set if there is something new in the FIFO. > > > > That covers scenario 2 from above. > > > > > Of course it is the same for the transmit status bits. > > > > ACK - The TX complete event handling is a 95% copy/paste of the RX > > handling. > > > > > So there is no need to read the FIFO fill levels directly, just the > > > general status register. > > > > What do you do if the hrtimer fires and there's no CAN frame waiting in > > the FIFO? > > Just enabling the 'new item' interrupt again and keep the hrtimer > disabled. Sounds good! regards, Marc
Hi Marc, On Thu, Dec 01, 2022 at 05:59:53PM +0100, Markus Schneider-Pargmann wrote: > On Thu, Dec 01, 2022 at 12:00:33PM +0100, Marc Kleine-Budde wrote: > > On 01.12.2022 11:12:20, Markus Schneider-Pargmann wrote: > > > > > For the upcoming receive side patch I already added a hrtimer. I may try > > > > > to use the same timer for both directions as it is going to do the exact > > > > > same thing in both cases (call the interrupt routine). Of course that > > > > > depends on the details of the coalescing support. Any objections on > > > > > that? > > > > > > > > For the mcp251xfd I implemented the RX and TX coalescing independent of > > > > each other and made it configurable via ethtool's IRQ coalescing > > > > options. > > > > > > > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > > > > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > > > > limited. I think the mcan core has the same limitations. > > > > > > Yes and no, the mcan core provides watermark levels so it has more > > > options, but there is no hardware timer as well (at least I didn't see > > > anything usable). > > > > Are there any limitations to the water mark level? > > Anything specific? I can't really see any limitation. You can set the > watermark between 1 and 32. I guess we could also always use it instead > of the new-element interrupt, but I haven't tried that yet. That may > simplify the code. Just a quick comment here after trying this, I decided against it. - I can't modify the watermark levels once the chip is active. - Using interrupt (un)masking I can change the behavior for tx and rx with a single register write instead of two to the two fifo configuration registers. You will see this in the second part of the series then. Best, Markus
On 13.12.2022 18:19:46, Markus Schneider-Pargmann wrote: > Hi Marc, > > On Thu, Dec 01, 2022 at 05:59:53PM +0100, Markus Schneider-Pargmann wrote: > > On Thu, Dec 01, 2022 at 12:00:33PM +0100, Marc Kleine-Budde wrote: > > > On 01.12.2022 11:12:20, Markus Schneider-Pargmann wrote: > > > > > > For the upcoming receive side patch I already added a hrtimer. I may try > > > > > > to use the same timer for both directions as it is going to do the exact > > > > > > same thing in both cases (call the interrupt routine). Of course that > > > > > > depends on the details of the coalescing support. Any objections on > > > > > > that? > > > > > > > > > > For the mcp251xfd I implemented the RX and TX coalescing independent of > > > > > each other and made it configurable via ethtool's IRQ coalescing > > > > > options. > > > > > > > > > > The hardware doesn't support any timeouts and only FIFO not empty, FIFO > > > > > half full and FIFO full IRQs and the on chip RAM for mailboxes is rather > > > > > limited. I think the mcan core has the same limitations. > > > > > > > > Yes and no, the mcan core provides watermark levels so it has more > > > > options, but there is no hardware timer as well (at least I didn't see > > > > anything usable). > > > > > > Are there any limitations to the water mark level? > > > > Anything specific? I can't really see any limitation. You can set the > > watermark between 1 and 32. I guess we could also always use it instead > > of the new-element interrupt, but I haven't tried that yet. That may > > simplify the code. > > Just a quick comment here after trying this, I decided against it. > - I can't modify the watermark levels once the chip is active. > - Using interrupt (un)masking I can change the behavior for tx and rx > with a single register write instead of two to the two fifo > configuration registers. Makes sense. > You will see this in the second part of the series then. Marc
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index f5bba848bd56..4a6972c8bacd 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -254,6 +254,7 @@ enum m_can_reg { #define TXESC_TBDS_64B 0x7 /* Tx Event FIFO Configuration (TXEFC) */ +#define TXEFC_EFWM_MASK GENMASK(29, 24) #define TXEFC_EFS_MASK GENMASK(21, 16) /* Tx Event FIFO Status (TXEFS) */ @@ -1094,8 +1095,8 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) netif_wake_queue(dev); } } else { - if (ir & IR_TEFN) { - /* New TX FIFO Element arrived */ + if (ir & (IR_TEFN | IR_TEFW)) { + /* New TX FIFO Element arrived or watermark reached */ if (m_can_echo_tx_event(dev) != 0) goto out_fail; if (!cdev->tx_skb && netif_queue_stopped(dev)) @@ -1242,6 +1243,7 @@ static void m_can_chip_config(struct net_device *dev) { struct m_can_classdev *cdev = netdev_priv(dev); u32 cccr, test; + u32 interrupts = IR_ALL_INT; m_can_config_endisable(cdev, true); @@ -1276,11 +1278,20 @@ static void m_can_chip_config(struct net_device *dev) FIELD_PREP(TXEFC_EFS_MASK, 1) | cdev->mcfg[MRAM_TXE].off); } else { + u32 txe_watermark; + + txe_watermark = cdev->mcfg[MRAM_TXE].num - 1; /* Full TX Event FIFO is used */ m_can_write(cdev, M_CAN_TXEFC, + FIELD_PREP(TXEFC_EFWM_MASK, + txe_watermark) | FIELD_PREP(TXEFC_EFS_MASK, cdev->mcfg[MRAM_TXE].num) | cdev->mcfg[MRAM_TXE].off); + + /* Watermark interrupt mode */ + if (txe_watermark) + interrupts &= ~IR_TEFN; } /* rx fifo configuration, blocking mode, fifo size 1 */ @@ -1338,15 +1349,13 @@ static void m_can_chip_config(struct net_device *dev) /* Enable interrupts */ m_can_write(cdev, M_CAN_IR, IR_ALL_INT); - if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { if (cdev->version == 30) - m_can_write(cdev, M_CAN_IE, IR_ALL_INT & - ~(IR_ERR_LEC_30X)); + interrupts &= ~(IR_ERR_LEC_30X); else - m_can_write(cdev, M_CAN_IE, IR_ALL_INT & - ~(IR_ERR_LEC_31X)); - else - m_can_write(cdev, M_CAN_IE, IR_ALL_INT); + interrupts &= ~(IR_ERR_LEC_31X); + } + m_can_write(cdev, M_CAN_IE, interrupts); /* route all interrupts to INT0 */ m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0);