Skip to content

Commit 0dd38ec

Browse files
author
Herton R. Krzesinski
committed
Merge: MLX4 driver upgrade - kernel 6.0
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1778 Description: ============ Hi all, This MR upgrades mlx4 driver, it includes patches from kernel 5.19 - 6.0 Bugzilla: ========= Bugzilla: http://bugzilla.redhat.com/2112965 Upstream-status: ================ All patches are accepted upstream to Linus tree. Each patch commit message describes its origin. Testing: ======== This patch set passed incremental build testing to verify that it is bisectable. Sanity tests ran over mlx4 drivers on x86_64 systems (using ConnectX-3), including the following: Ethernet: -- IPv4 traffic (ICMP, TCP, UDP). -- IPv6 traffic (ICMP, TCP, UDP). VLAN: -- IPv4 traffic (ICMP, TCP, UDP). -- IPv6 traffic (ICMP, TCP, UDP). RoCE: -- RDMA (ibv_*_pingpong). -- RDMACM (examples that comes with librdmacm packages). Infiniband: -- RDMA (ibv_*_pingpong). -- RDMACM (examples that comes with librdmacm packages). IPoIB: -- IPv4 traffic (ICMP, TCP, UDP). -- IPv6 traffic (ICMP, TCP, UDP). PKey: -- IPv4 traffic (ICMP, TCP, UDP). -- IPv6 traffic (ICMP, TCP, UDP). NFSoRDMA: -- Discover, mount and write. iSER: -- Discover, login and mount. SRP: -- Verify srp_daemon service is up and system can discover SRP targets. Signed-off-by: Mohammad Kabat <mkabat@redhat.com> 2bd51c1 (Mohammad Kabat) net/mlx4_en: Fix wrong return value on ioctl EEPROM query failure 4d3f47c (Mohammad Kabat) RDMA/mlx4: Avoid flush_scheduled_work() usage 4946218 (Mohammad Kabat) mlx4: support BIG TCP packets 51c7ac8 (Mohammad Kabat) net: mellanox: fix open-coded for_each_set_bit() drivers/infiniband/hw/mlx4/cm.c | 29 +++++++++++---- drivers/infiniband/hw/mlx4/main.c | 10 +++++- drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 ++ drivers/net/ethernet/mellanox/mlx4/cmd.c | 23 ++++-------- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 ++ drivers/net/ethernet/mellanox/mlx4/en_tx.c | 47 ++++++++++++++++++++----- 7 files changed, 82 insertions(+), 35 deletions(-) Approved-by: Kamal Heib <kheib@redhat.com> Approved-by: Íñigo Huguet <ihuguet@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents 73bb7e1 + 2bd51c1 commit 0dd38ec

File tree

7 files changed

+82
-35
lines changed

7 files changed

+82
-35
lines changed

drivers/infiniband/hw/mlx4/cm.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct cm_req_msg {
8080
union ib_gid primary_path_sgid;
8181
};
8282

83+
static struct workqueue_struct *cm_wq;
8384

8485
static void set_local_comm_id(struct ib_mad *mad, u32 cm_id)
8586
{
@@ -288,10 +289,10 @@ static void schedule_delayed(struct ib_device *ibdev, struct id_map_entry *id)
288289
/*make sure that there is no schedule inside the scheduled work.*/
289290
if (!sriov->is_going_down && !id->scheduled_delete) {
290291
id->scheduled_delete = 1;
291-
schedule_delayed_work(&id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
292+
queue_delayed_work(cm_wq, &id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
292293
} else if (id->scheduled_delete) {
293294
/* Adjust timeout if already scheduled */
294-
mod_delayed_work(system_wq, &id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
295+
mod_delayed_work(cm_wq, &id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
295296
}
296297
spin_unlock_irqrestore(&sriov->going_down_lock, flags);
297298
spin_unlock(&sriov->id_map_lock);
@@ -370,7 +371,7 @@ static int alloc_rej_tmout(struct mlx4_ib_sriov *sriov, u32 rem_pv_cm_id, int sl
370371
ret = xa_err(item);
371372
else
372373
/* If a retry, adjust delayed work */
373-
mod_delayed_work(system_wq, &item->timeout, CM_CLEANUP_CACHE_TIMEOUT);
374+
mod_delayed_work(cm_wq, &item->timeout, CM_CLEANUP_CACHE_TIMEOUT);
374375
goto err_or_exists;
375376
}
376377
xa_unlock(&sriov->xa_rej_tmout);
@@ -393,7 +394,7 @@ static int alloc_rej_tmout(struct mlx4_ib_sriov *sriov, u32 rem_pv_cm_id, int sl
393394
return xa_err(old);
394395
}
395396

396-
schedule_delayed_work(&item->timeout, CM_CLEANUP_CACHE_TIMEOUT);
397+
queue_delayed_work(cm_wq, &item->timeout, CM_CLEANUP_CACHE_TIMEOUT);
397398

398399
return 0;
399400

@@ -500,15 +501,15 @@ static void rej_tmout_xa_cleanup(struct mlx4_ib_sriov *sriov, int slave)
500501
xa_lock(&sriov->xa_rej_tmout);
501502
xa_for_each(&sriov->xa_rej_tmout, id, item) {
502503
if (slave < 0 || slave == item->slave) {
503-
mod_delayed_work(system_wq, &item->timeout, 0);
504+
mod_delayed_work(cm_wq, &item->timeout, 0);
504505
flush_needed = true;
505506
++cnt;
506507
}
507508
}
508509
xa_unlock(&sriov->xa_rej_tmout);
509510

510511
if (flush_needed) {
511-
flush_scheduled_work();
512+
flush_workqueue(cm_wq);
512513
pr_debug("Deleted %d entries in xarray for slave %d during cleanup\n",
513514
cnt, slave);
514515
}
@@ -540,7 +541,7 @@ void mlx4_ib_cm_paravirt_clean(struct mlx4_ib_dev *dev, int slave)
540541
spin_unlock(&sriov->id_map_lock);
541542

542543
if (need_flush)
543-
flush_scheduled_work(); /* make sure all timers were flushed */
544+
flush_workqueue(cm_wq); /* make sure all timers were flushed */
544545

545546
/* now, remove all leftover entries from databases*/
546547
spin_lock(&sriov->id_map_lock);
@@ -587,3 +588,17 @@ void mlx4_ib_cm_paravirt_clean(struct mlx4_ib_dev *dev, int slave)
587588

588589
rej_tmout_xa_cleanup(sriov, slave);
589590
}
591+
592+
int mlx4_ib_cm_init(void)
593+
{
594+
cm_wq = alloc_workqueue("mlx4_ib_cm", 0, 0);
595+
if (!cm_wq)
596+
return -ENOMEM;
597+
598+
return 0;
599+
}
600+
601+
void mlx4_ib_cm_destroy(void)
602+
{
603+
destroy_workqueue(cm_wq);
604+
}

drivers/infiniband/hw/mlx4/main.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3307,10 +3307,14 @@ static int __init mlx4_ib_init(void)
33073307
if (!wq)
33083308
return -ENOMEM;
33093309

3310-
err = mlx4_ib_mcg_init();
3310+
err = mlx4_ib_cm_init();
33113311
if (err)
33123312
goto clean_wq;
33133313

3314+
err = mlx4_ib_mcg_init();
3315+
if (err)
3316+
goto clean_cm;
3317+
33143318
err = mlx4_register_interface(&mlx4_ib_interface);
33153319
if (err)
33163320
goto clean_mcg;
@@ -3320,6 +3324,9 @@ static int __init mlx4_ib_init(void)
33203324
clean_mcg:
33213325
mlx4_ib_mcg_destroy();
33223326

3327+
clean_cm:
3328+
mlx4_ib_cm_destroy();
3329+
33233330
clean_wq:
33243331
destroy_workqueue(wq);
33253332
return err;
@@ -3329,6 +3336,7 @@ static void __exit mlx4_ib_cleanup(void)
33293336
{
33303337
mlx4_unregister_interface(&mlx4_ib_interface);
33313338
mlx4_ib_mcg_destroy();
3339+
mlx4_ib_cm_destroy();
33323340
destroy_workqueue(wq);
33333341
}
33343342

drivers/infiniband/hw/mlx4/mlx4_ib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,4 +937,7 @@ mlx4_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table)
937937
int mlx4_ib_umem_calc_optimal_mtt_size(struct ib_umem *umem, u64 start_va,
938938
int *num_of_mtts);
939939

940+
int mlx4_ib_cm_init(void);
941+
void mlx4_ib_cm_destroy(void);
942+
940943
#endif /* MLX4_IB_H */

drivers/net/ethernet/mellanox/mlx4/cmd.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,21 +1994,16 @@ static void mlx4_allocate_port_vpps(struct mlx4_dev *dev, int port)
19941994

19951995
static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
19961996
{
1997-
int port, err;
1997+
int p, port, err;
19981998
struct mlx4_vport_state *vp_admin;
19991999
struct mlx4_vport_oper_state *vp_oper;
20002000
struct mlx4_slave_state *slave_state =
20012001
&priv->mfunc.master.slave_state[slave];
20022002
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(
20032003
&priv->dev, slave);
2004-
int min_port = find_first_bit(actv_ports.ports,
2005-
priv->dev.caps.num_ports) + 1;
2006-
int max_port = min_port - 1 +
2007-
bitmap_weight(actv_ports.ports, priv->dev.caps.num_ports);
20082004

2009-
for (port = min_port; port <= max_port; port++) {
2010-
if (!test_bit(port - 1, actv_ports.ports))
2011-
continue;
2005+
for_each_set_bit(p, actv_ports.ports, priv->dev.caps.num_ports) {
2006+
port = p + 1;
20122007
priv->mfunc.master.vf_oper[slave].smi_enabled[port] =
20132008
priv->mfunc.master.vf_admin[slave].enable_smi[port];
20142009
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
@@ -2063,19 +2058,13 @@ static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
20632058

20642059
static void mlx4_master_deactivate_admin_state(struct mlx4_priv *priv, int slave)
20652060
{
2066-
int port;
2061+
int p, port;
20672062
struct mlx4_vport_oper_state *vp_oper;
20682063
struct mlx4_active_ports actv_ports = mlx4_get_active_ports(
20692064
&priv->dev, slave);
2070-
int min_port = find_first_bit(actv_ports.ports,
2071-
priv->dev.caps.num_ports) + 1;
2072-
int max_port = min_port - 1 +
2073-
bitmap_weight(actv_ports.ports, priv->dev.caps.num_ports);
20742065

2075-
2076-
for (port = min_port; port <= max_port; port++) {
2077-
if (!test_bit(port - 1, actv_ports.ports))
2078-
continue;
2066+
for_each_set_bit(p, actv_ports.ports, priv->dev.caps.num_ports) {
2067+
port = p + 1;
20792068
priv->mfunc.master.vf_oper[slave].smi_enabled[port] =
20802069
MLX4_VF_SMI_DISABLED;
20812070
vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];

drivers/net/ethernet/mellanox/mlx4/en_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2110,7 +2110,7 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
21102110
en_err(priv,
21112111
"mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n",
21122112
i, offset, ee->len - i, ret);
2113-
return 0;
2113+
return ret;
21142114
}
21152115

21162116
i += ret;

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,6 +3417,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
34173417
dev->min_mtu = ETH_MIN_MTU;
34183418
dev->max_mtu = priv->max_mtu;
34193419

3420+
/* supports LSOv2 packets. */
3421+
netif_set_tso_max_size(dev, GSO_MAX_SIZE);
3422+
34203423
mdev->pndev[port] = dev;
34213424
mdev->upper[port] = NULL;
34223425

drivers/net/ethernet/mellanox/mlx4/en_tx.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <linux/ip.h>
4444
#include <linux/ipv6.h>
4545
#include <linux/indirect_call_wrapper.h>
46+
#include <net/ipv6.h>
4647

4748
#include "mlx4_en.h"
4849

@@ -634,19 +635,28 @@ static int get_real_size(const struct sk_buff *skb,
634635
struct net_device *dev,
635636
int *lso_header_size,
636637
bool *inline_ok,
637-
void **pfrag)
638+
void **pfrag,
639+
int *hopbyhop)
638640
{
639641
struct mlx4_en_priv *priv = netdev_priv(dev);
640642
int real_size;
641643

642644
if (shinfo->gso_size) {
643645
*inline_ok = false;
644-
if (skb->encapsulation)
646+
*hopbyhop = 0;
647+
if (skb->encapsulation) {
645648
*lso_header_size = skb_inner_tcp_all_headers(skb);
646-
else
649+
} else {
650+
/* Detects large IPV6 TCP packets and prepares for removal of
651+
* HBH header that has been pushed by ip6_xmit(),
652+
* mainly so that tcpdump can dissect them.
653+
*/
654+
if (ipv6_has_hopopt_jumbo(skb))
655+
*hopbyhop = sizeof(struct hop_jumbo_hdr);
647656
*lso_header_size = skb_tcp_all_headers(skb);
657+
}
648658
real_size = CTRL_SIZE + shinfo->nr_frags * DS_SIZE +
649-
ALIGN(*lso_header_size + 4, DS_SIZE);
659+
ALIGN(*lso_header_size - *hopbyhop + 4, DS_SIZE);
650660
if (unlikely(*lso_header_size != skb_headlen(skb))) {
651661
/* We add a segment for the skb linear buffer only if
652662
* it contains data */
@@ -873,6 +883,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
873883
int desc_size;
874884
int real_size;
875885
u32 index, bf_index;
886+
struct ipv6hdr *h6;
876887
__be32 op_own;
877888
int lso_header_size;
878889
void *fragptr = NULL;
@@ -881,6 +892,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
881892
bool stop_queue;
882893
bool inline_ok;
883894
u8 data_offset;
895+
int hopbyhop;
884896
bool bf_ok;
885897

886898
tx_ind = skb_get_queue_mapping(skb);
@@ -890,7 +902,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
890902
goto tx_drop;
891903

892904
real_size = get_real_size(skb, shinfo, dev, &lso_header_size,
893-
&inline_ok, &fragptr);
905+
&inline_ok, &fragptr, &hopbyhop);
894906
if (unlikely(!real_size))
895907
goto tx_drop_count;
896908

@@ -943,7 +955,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
943955
data = &tx_desc->data;
944956
data_offset = offsetof(struct mlx4_en_tx_desc, data);
945957
} else {
946-
int lso_align = ALIGN(lso_header_size + 4, DS_SIZE);
958+
int lso_align = ALIGN(lso_header_size - hopbyhop + 4, DS_SIZE);
947959

948960
data = (void *)&tx_desc->lso + lso_align;
949961
data_offset = offsetof(struct mlx4_en_tx_desc, lso) + lso_align;
@@ -1008,14 +1020,31 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
10081020
((ring->prod & ring->size) ?
10091021
cpu_to_be32(MLX4_EN_BIT_DESC_OWN) : 0);
10101022

1023+
lso_header_size -= hopbyhop;
10111024
/* Fill in the LSO prefix */
10121025
tx_desc->lso.mss_hdr_size = cpu_to_be32(
10131026
shinfo->gso_size << 16 | lso_header_size);
10141027

1015-
/* Copy headers;
1016-
* note that we already verified that it is linear */
1017-
memcpy(tx_desc->lso.header, skb->data, lso_header_size);
10181028

1029+
if (unlikely(hopbyhop)) {
1030+
/* remove the HBH header.
1031+
* Layout: [Ethernet header][IPv6 header][HBH][TCP header]
1032+
*/
1033+
memcpy(tx_desc->lso.header, skb->data, ETH_HLEN + sizeof(*h6));
1034+
h6 = (struct ipv6hdr *)((char *)tx_desc->lso.header + ETH_HLEN);
1035+
h6->nexthdr = IPPROTO_TCP;
1036+
/* Copy the TCP header after the IPv6 one */
1037+
memcpy(h6 + 1,
1038+
skb->data + ETH_HLEN + sizeof(*h6) +
1039+
sizeof(struct hop_jumbo_hdr),
1040+
tcp_hdrlen(skb));
1041+
/* Leave ipv6 payload_len set to 0, as LSO v2 specs request. */
1042+
} else {
1043+
/* Copy headers;
1044+
* note that we already verified that it is linear
1045+
*/
1046+
memcpy(tx_desc->lso.header, skb->data, lso_header_size);
1047+
}
10191048
ring->tso_packets++;
10201049

10211050
i = shinfo->gso_segs;

0 commit comments

Comments
 (0)