mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Javen <javen_xu@realsil.com.cn>
To: "netdev-bot+sashiko@kernel.org" <netdev-bot+sashiko@kernel.org>
Cc: "hkallweit1@gmail.com" <hkallweit1@gmail.com>,
	"nic_swsd@realtek.com" <nic_swsd@realtek.com>,
	"andrew+netdev@lunn.ch" <andrew+netdev@lunn.ch>,
	"davem@davemloft.net" <davem@davemloft.net>,
	"edumazet@google.com" <edumazet@google.com>,
	"kuba@kernel.org" <kuba@kernel.org>,
	"pabeni@redhat.com" <pabeni@redhat.com>,
	"horms@kernel.org" <horms@kernel.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [net-next,v12,2/7] r8169: refactor RX path to prepare for multi-queue
Date: Fri, 4 Sep 2026 03:06:47 +0000	[thread overview]
Message-ID: <429c7a6c99df47d7b4e2638ee9df5101@realsil.com.cn> (raw)
In-Reply-To: <178846812274.3394541.14036248825057917928@kernel.org>

>Critical: 0 · High: 0 · Medium: 3 · Low: 0
>
>- [Medium] Undisclosed functional change folded into a patch whose
>  changelog promises a pure refactor: `R8169_RX_RING_BYTES` is changed…
>- [Medium] State introduced by this patch that is never consumed, and a
>  netdev queue count advertised to the core that never matches reality.
>- [Medium] IRQF_NO_THREAD is silently dropped for MSI/MSI-X vectors.
>
>--
>
>r8169: refactor RX path to prepare for multi-queue
>
>This patch introduces struct rtl8169_rx_ring and moves the RX ring state out of
>rtl8169_private into a per-queue array, and switches the netdev allocation to
>devm_alloc_etherdev_mqs() with up to 8 RX queues while num_rx_rings stays
>at 1.
>
>> diff --git a/drivers/net/ethernet/realtek/r8169_main.c
>> b/drivers/net/ethernet/realtek/r8169_main.c
>> index 87eb10616a0c..9311a0cab4eb 100644
>> --- a/drivers/net/ethernet/realtek/r8169_main.c
>> +++ b/drivers/net/ethernet/realtek/r8169_main.c
>> @@ -74,9 +74,19 @@
>>  #define NUM_TX_DESC  256     /* Number of Tx descriptor registers */
>>  #define NUM_RX_DESC  256     /* Number of Rx descriptor registers */
>>  #define R8169_TX_RING_BYTES  (NUM_TX_DESC * sizeof(struct TxDesc))
>> -#define R8169_RX_RING_BYTES  (NUM_RX_DESC * sizeof(struct RxDesc))
>> +
>> +/*
>> + * Workaround for the hardware DMA prefetcher. The H/W might
>> +aggressively
>> + * fetch one more descriptor even after hitting the RingEnd mark. We
>> + * allocate this extra dummy space as padding to prevent
>> +out-of-bounds
>> + * access and potential IOMMU faults.
>> + */
>> +#define R8169_RX_RING_BYTES  ((NUM_RX_DESC + 1) * sizeof(struct
>> +RxDesc))
>
>[Severity: Medium]
>The changelog describes this patch as "a preparatory refactoring of the RX
>path", but this macro changes behaviour for every supported chip.  Two
>questions about it.
>
>First, if the hardware really does "fetch one more descriptor even after hitting
>the RingEnd mark", then the driver before this patch lets the device DMA past
>the end of the ring on all chip generations.  Would that make this an
>independent fix that wants its own patch with a Fixes: tag, so that stable trees
>pick it up?  As submitted the change is invisible to backporters.
>
>Second, sizeof(struct RxDesc) is 16 and NUM_RX_DESC is 256, so the old
>request was exactly 4096 bytes and the new one is 4112 bytes:
>
>        rtl8169_alloc_rx_desc()
>          dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, ...)
>
>Since dma_alloc_coherent() rounds up to a power-of-two page order, does this
>turn the per-ring coherent allocation from one page into two, doubling the
>coherent DMA footprint per RX ring (and eight times that once the rest of the
>series enables multiple rings)?  Would allocating one page and reserving the
>last descriptor as the pad, or documenting the extra page, be preferable?
>
>>  #define R8169_TX_STOP_THRS   (MAX_SKB_FRAGS + 1)
>>  #define R8169_TX_START_THRS  (2 * R8169_TX_STOP_THRS)
>> +#define R8169_MAX_RX_QUEUES  8
>> +#define R8169_DEFAULT_RX_QUEUES      1
>> +#define R8169_MAX_TX_QUEUES  1
>>
>>  #define OCP_STD_PHY_BASE     0xa400
>>
>
>[ ... ]
>
>> @@ -728,6 +739,15 @@ enum rtl_dash_type {
>>       RTL_DASH_25_BP,
>>  };
>>
>> +struct rtl8169_rx_ring {
>> +     u32 cur_rx;
>> +     u32 dirty_rx;
>
>[Severity: Medium]
>Is dirty_rx used anywhere?  Grepping the tree at the end of this series returns
>only this declaration and the single store in
>rtl8169_init_ring_indexes() below - there is no comparison against cur_rx and
>no refill or doorbell logic reading it.  Should the field be dropped until the
>patch that actually needs it?
>
>> +     struct RxDesc *rx_desc_array;
>> +     dma_addr_t rx_desc_phy_addr[NUM_RX_DESC];
>> +     dma_addr_t rx_phy_addr;
>> +     struct page *rx_databuff[NUM_RX_DESC]; };
>> +
>
>[ ... ]
>
>> @@ -2620,9 +2638,26 @@ static void rtl_init_rxcfg(struct rtl8169_private
>*tp)
>>       }
>>  }
>>
>> +static void rtl8169_rx_desc_init(struct rtl8169_private *tp) {
>> +     for (int i = 0; i < tp->num_rx_rings; i++) {
>> +             struct rtl8169_rx_ring *ring = &tp->rx_ring[i];
>> +
>> +             memset(ring->rx_desc_array, 0x0, R8169_RX_RING_BYTES);
>> +     }
>> +}
>> +
>>  static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)  {
>> -     tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;
>> +     tp->dirty_tx = 0;
>> +     tp->cur_tx = 0;
>> +
>> +     for (int i = 0; i < tp->num_rx_rings; i++) {
>> +             struct rtl8169_rx_ring *ring = &tp->rx_ring[i];
>> +
>> +             ring->dirty_rx = 0;
>> +             ring->cur_rx = 0;
>> +     }
>>  }
>>
>
>[ ... ]
>
>> @@ -4184,55 +4240,107 @@ static void rtl8169_rx_clear(struct
>> rtl8169_private *tp)
>
>[ ... ]
>
>> +static int rtl8169_alloc_rx_desc(struct rtl8169_private *tp) {
>> +     struct pci_dev *pdev = tp->pci_dev;
>> +     struct rtl8169_rx_ring *ring;
>> +
>> +     for (int i = 0; i < tp->num_rx_rings; i++) {
>> +             ring = &tp->rx_ring[i];
>> +             ring->rx_desc_array = dma_alloc_coherent(&pdev->dev,
>> +                                                      R8169_RX_RING_BYTES,
>> +                                                      &ring->rx_phy_addr,
>> +                                                      GFP_KERNEL);
>> +             if (!ring->rx_desc_array)
>> +                     return -ENOMEM;
>> +     }
>> +     return 0;
>> +}
>> +
>
>[ ... ]
>
>> @@ -5688,7 +5812,10 @@ static int rtl_init_one(struct pci_dev *pdev, const
>struct pci_device_id *ent)
>>       u32 txconfig;
>>       u32 xid;
>>
>> -     dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
>> +     dev = devm_alloc_etherdev_mqs(&pdev->dev, sizeof(*tp),
>> +                                   R8169_MAX_TX_QUEUES,
>> +                                   R8169_MAX_RX_QUEUES);
>> +
>
>[Severity: Medium]
>This asks the core for 8 RX queues on every chip, and alloc_netdev_mqs() sets
>dev->real_num_rx_queues = rxqs:
>
>net/core/dev.c:alloc_netdev_mqs() {
>        ...
>        dev->real_num_rx_queues = rxqs;
>        ...
>}
>
>rtl_setup_rx_params() keeps tp->num_rx_rings at 1, and there is no
>netif_set_real_num_rx_queues() call in the driver, either here or at the end of
>the series.  Does that leave every r8169 device advertising 8 RX queues to
>userspace - /sys/class/net/<dev>/queues/rx-0 through rx-7 with their RPS/RFS
>knobs, plus the netdev-genl queue enumeration - while only ring 0 ever
>receives packets?
>
>Should rtl_init_one() call netif_set_real_num_rx_queues(dev,
>tp->num_rx_rings) once the ring count is known?

This is incorrect. The driver actually DOES call netif_set_real_num_queues()

  reply	other threads:[~2026-09-04  3:07 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31  5:39 [PATCH net-next v12 0/7] r8169: add RSS support for RTL8127 javen
2026-08-31  5:39 ` [PATCH net-next v12 1/7] r8169: add support for multi irqs javen
2026-09-03 20:42   ` [net-next,v12,1/7] " netdev-bot+sashiko
2026-09-04  2:46     ` Javen
2026-08-31  5:39 ` [PATCH net-next v12 2/7] r8169: refactor RX path to prepare for multi-queue javen
2026-09-03 20:42   ` [net-next,v12,2/7] " netdev-bot+sashiko
2026-09-04  3:06     ` Javen [this message]
2026-08-31  5:39 ` [PATCH net-next v12 3/7] r8169: add support for new interrupt mapping javen
2026-09-03 20:42   ` [net-next,v12,3/7] " netdev-bot+sashiko
2026-08-31  5:39 ` [PATCH net-next v12 4/7] r8169: enable " javen
2026-09-03 20:42   ` [net-next,v12,4/7] " netdev-bot+sashiko
2026-08-31  5:39 ` [PATCH net-next v12 5/7] r8169: add support and enable rss javen
2026-09-03 20:42   ` [net-next,v12,5/7] " netdev-bot+sashiko
2026-08-31  5:39 ` [PATCH net-next v12 6/7] r8169: move struct ethtool_ops javen
2026-08-31  5:39 ` [PATCH net-next v12 7/7] r8169: add get_channel support for ethtool javen
2026-09-03 20:42   ` [net-next,v12,7/7] " netdev-bot+sashiko

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=429c7a6c99df47d7b4e2638ee9df5101@realsil.com.cn \
    --to=javen_xu@realsil.com.cn \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hkallweit1@gmail.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nic_swsd@realtek.com \
    --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

all inboxes | Powered by JetHome®