From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 1/3] net: docs: update the sample code in driver.rst
Date: Mon, 10 Apr 2023 18:33:21 -0700 [thread overview]
Message-ID: <20230411013323.513688-2-kuba@kernel.org> (raw)
In-Reply-To: <20230411013323.513688-1-kuba@kernel.org>
The sample code talks about single-queue devices and uses locks.
Update it to something resembling more modern code.
Make sure we mention use of READ_ONCE() / WRITE_ONCE().
Change the comment which talked about consumer on the xmit side.
AFAIU xmit is the producer and completions are a consumer.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
Documentation/networking/driver.rst | 61 +++++++++++++----------------
1 file changed, 27 insertions(+), 34 deletions(-)
diff --git a/Documentation/networking/driver.rst b/Documentation/networking/driver.rst
index 4071f2c00f8b..4f5dfa9c022e 100644
--- a/Documentation/networking/driver.rst
+++ b/Documentation/networking/driver.rst
@@ -47,30 +47,43 @@ Instead it must maintain the queue properly. For example,
.. code-block:: c
+ static u32 drv_tx_avail(struct drv_ring *dr)
+ {
+ u32 used = READ_ONCE(dr->prod) - READ_ONCE(dr->cons);
+
+ return dr->tx_ring_size - (used & bp->tx_ring_mask);
+ }
+
static netdev_tx_t drv_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct drv *dp = netdev_priv(dev);
+ struct netdev_queue *txq;
+ struct drv_ring *dr;
+ int idx;
+
+ idx = skb_get_queue_mapping(skb);
+ dr = dp->tx_rings[idx];
+ txq = netdev_get_tx_queue(dev, idx);
- lock_tx(dp);
//...
- /* This is a hard error log it. */
- if (TX_BUFFS_AVAIL(dp) <= (skb_shinfo(skb)->nr_frags + 1)) {
+ /* This should be a very rare race - log it. */
+ if (drv_tx_avail(dr) <= skb_shinfo(skb)->nr_frags + 1) {
netif_stop_queue(dev);
- unlock_tx(dp);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
- dev->name);
+ netdev_warn(dev, "Tx Ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
//... queue packet to card ...
- //... update tx consumer index ...
- if (TX_BUFFS_AVAIL(dp) <= (MAX_SKB_FRAGS + 1))
- netif_stop_queue(dev);
+ netdev_tx_sent_queue(txq, skb->len);
+
+ //... update tx producer index using WRITE_ONCE() ...
+
+ if (!netif_txq_maybe_stop(txq, drv_tx_avail(dr),
+ MAX_SKB_FRAGS + 1, 2 * MAX_SKB_FRAGS))
+ dr->stats.stopped++;
- //...
- unlock_tx(dp);
//...
return NETDEV_TX_OK;
}
@@ -79,30 +92,10 @@ Instead it must maintain the queue properly. For example,
.. code-block:: c
- if (netif_queue_stopped(dp->dev) &&
- TX_BUFFS_AVAIL(dp) > (MAX_SKB_FRAGS + 1))
- netif_wake_queue(dp->dev);
-
-For a non-scatter-gather supporting card, the three tests simply become:
-
-.. code-block:: c
-
- /* This is a hard error log it. */
- if (TX_BUFFS_AVAIL(dp) <= 0)
-
-and:
-
-.. code-block:: c
-
- if (TX_BUFFS_AVAIL(dp) == 0)
-
-and:
-
-.. code-block:: c
+ //... update tx consumer index using WRITE_ONCE() ...
- if (netif_queue_stopped(dp->dev) &&
- TX_BUFFS_AVAIL(dp) > 0)
- netif_wake_queue(dp->dev);
+ netif_txq_completed_wake(txq, cmpl_pkts, cmpl_bytes,
+ drv_tx_avail(dr), 2 * MAX_SKB_FRAGS);
Lockless queue stop / wake helper macros
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.39.2
next prev parent reply other threads:[~2023-04-11 1:33 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-11 1:33 [PATCH net-next 0/3] net: use READ_ONCE/WRITE_ONCE for ring index accesses Jakub Kicinski
2023-04-11 1:33 ` Jakub Kicinski [this message]
2023-04-11 15:52 ` [PATCH net-next 1/3] net: docs: update the sample code in driver.rst Jesse Brandeburg
2023-04-11 1:33 ` [PATCH net-next 2/3] bnxt: use READ_ONCE/WRITE_ONCE for ring indexes Jakub Kicinski
2023-04-11 15:52 ` Jesse Brandeburg
2023-04-11 23:09 ` Michael Chan
2023-04-11 1:33 ` [PATCH net-next 3/3] mlx4: " Jakub Kicinski
2023-04-11 15:52 ` Jesse Brandeburg
2023-04-11 15:55 ` [PATCH net-next 0/3] net: use READ_ONCE/WRITE_ONCE for ring index accesses Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230411013323.513688-2-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).