Skip to content

Commit 2ed45a4

Browse files
author
CKI KWF Bot
committed
Merge: vmxnet3: backports for RHEL 10.1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1135 * 0458cbe vmxnet3: support higher link speeds from vmxnet3 v9 * 3f1baa9 vmxnet3: Fix tx queue race condition with XDP * 43f0999 vmxnet3: update MTU after device quiesce * 982d30c vmxnet3: correctly report gso type for UDP tunnels JIRA: https://issues.redhat.com/browse/RHEL-96969 Signed-off-by: Izabela Bakollari <ibakolla@redhat.com> Approved-by: Ivan Vecera <ivecera@redhat.com> Approved-by: Michal Schmidt <mschmidt@redhat.com> Approved-by: Kamal Heib <kheib@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 432e3b8 + 829448e commit 2ed45a4

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

drivers/net/vmxnet3/vmxnet3_drv.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
201201

202202
adapter->link_speed = ret >> 16;
203203
if (ret & 1) { /* Link is up. */
204+
/*
205+
* From vmxnet3 v9, the hypervisor reports the speed in Gbps.
206+
* Convert the speed to Mbps before rporting it to the kernel.
207+
* Max link speed supported is 10000G.
208+
*/
209+
if (VMXNET3_VERSION_GE_9(adapter) &&
210+
adapter->link_speed < 10000)
211+
adapter->link_speed = adapter->link_speed * 1000;
204212
netdev_info(adapter->netdev, "NIC Link is Up %d Mbps\n",
205213
adapter->link_speed);
206214
netif_carrier_on(adapter->netdev);
@@ -1560,6 +1568,30 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
15601568
return (hlen + (hdr.tcp->doff << 2));
15611569
}
15621570

1571+
static void
1572+
vmxnet3_lro_tunnel(struct sk_buff *skb, __be16 ip_proto)
1573+
{
1574+
struct udphdr *uh = NULL;
1575+
1576+
if (ip_proto == htons(ETH_P_IP)) {
1577+
struct iphdr *iph = (struct iphdr *)skb->data;
1578+
1579+
if (iph->protocol == IPPROTO_UDP)
1580+
uh = (struct udphdr *)(iph + 1);
1581+
} else {
1582+
struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
1583+
1584+
if (iph->nexthdr == IPPROTO_UDP)
1585+
uh = (struct udphdr *)(iph + 1);
1586+
}
1587+
if (uh) {
1588+
if (uh->check)
1589+
skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
1590+
else
1591+
skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
1592+
}
1593+
}
1594+
15631595
static int
15641596
vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
15651597
struct vmxnet3_adapter *adapter, int quota)
@@ -1873,6 +1905,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
18731905
if (segCnt != 0 && mss != 0) {
18741906
skb_shinfo(skb)->gso_type = rcd->v4 ?
18751907
SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
1908+
if (encap_lro)
1909+
vmxnet3_lro_tunnel(skb, skb->protocol);
18761910
skb_shinfo(skb)->gso_size = mss;
18771911
skb_shinfo(skb)->gso_segs = segCnt;
18781912
} else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
@@ -3599,8 +3633,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
35993633
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
36003634
int err = 0;
36013635

3602-
WRITE_ONCE(netdev->mtu, new_mtu);
3603-
36043636
/*
36053637
* Reset_work may be in the middle of resetting the device, wait for its
36063638
* completion.
@@ -3614,6 +3646,7 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
36143646

36153647
/* we need to re-create the rx queue based on the new mtu */
36163648
vmxnet3_rq_destroy_all(adapter);
3649+
WRITE_ONCE(netdev->mtu, new_mtu);
36173650
vmxnet3_adjust_rx_ring_size(adapter);
36183651
err = vmxnet3_rq_create_all(adapter);
36193652
if (err) {
@@ -3630,6 +3663,8 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
36303663
"Closing it\n", err);
36313664
goto out;
36323665
}
3666+
} else {
3667+
WRITE_ONCE(netdev->mtu, new_mtu);
36333668
}
36343669

36353670
out:

drivers/net/vmxnet3/vmxnet3_xdp.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ vmxnet3_xdp_get_tq(struct vmxnet3_adapter *adapter)
2828
if (likely(cpu < tq_number))
2929
tq = &adapter->tx_queue[cpu];
3030
else
31-
tq = &adapter->tx_queue[reciprocal_scale(cpu, tq_number)];
31+
tq = &adapter->tx_queue[cpu % tq_number];
3232

3333
return tq;
3434
}
@@ -124,6 +124,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
124124
u32 buf_size;
125125
u32 dw2;
126126

127+
spin_lock_irq(&tq->tx_lock);
127128
dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
128129
dw2 |= xdpf->len;
129130
ctx.sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill;
@@ -134,6 +135,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
134135

135136
if (vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) == 0) {
136137
tq->stats.tx_ring_full++;
138+
spin_unlock_irq(&tq->tx_lock);
137139
return -ENOSPC;
138140
}
139141

@@ -142,8 +144,10 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
142144
tbi->dma_addr = dma_map_single(&adapter->pdev->dev,
143145
xdpf->data, buf_size,
144146
DMA_TO_DEVICE);
145-
if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr))
147+
if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) {
148+
spin_unlock_irq(&tq->tx_lock);
146149
return -EFAULT;
150+
}
147151
tbi->map_type |= VMXNET3_MAP_SINGLE;
148152
} else { /* XDP buffer from page pool */
149153
page = virt_to_page(xdpf->data);
@@ -182,6 +186,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
182186
dma_wmb();
183187
gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^
184188
VMXNET3_TXD_GEN);
189+
spin_unlock_irq(&tq->tx_lock);
185190

186191
/* No need to handle the case when tx_num_deferred doesn't reach
187192
* threshold. Backend driver at hypervisor side will poll and reset
@@ -225,6 +230,7 @@ vmxnet3_xdp_xmit(struct net_device *dev,
225230
{
226231
struct vmxnet3_adapter *adapter = netdev_priv(dev);
227232
struct vmxnet3_tx_queue *tq;
233+
struct netdev_queue *nq;
228234
int i;
229235

230236
if (unlikely(test_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state)))
@@ -236,13 +242,17 @@ vmxnet3_xdp_xmit(struct net_device *dev,
236242
if (tq->stopped)
237243
return -ENETDOWN;
238244

245+
nq = netdev_get_tx_queue(adapter->netdev, tq->qid);
246+
247+
__netif_tx_lock(nq, smp_processor_id());
239248
for (i = 0; i < n; i++) {
240249
if (vmxnet3_xdp_xmit_frame(adapter, frames[i], tq, true)) {
241250
tq->stats.xdp_xmit_err++;
242251
break;
243252
}
244253
}
245254
tq->stats.xdp_xmit += i;
255+
__netif_tx_unlock(nq);
246256

247257
return i;
248258
}

0 commit comments

Comments
 (0)