History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma fixes from Jason Gunthorpe: "This is an unusually large bunch of bug fixes for the later rc cycle, rxe and mlx5 both dumped a lot of things at once. rxe continues to fix itself, and mlx5 is fixing a bunch of "queue counters" related bugs. There is one highly notable bug fix regarding the qkey. This small security check was missed in the original 2005 implementation and it allows some significant issues. Summary: - Two rtrs bug fixes for error unwind bugs - Several rxe bug fixes: * Incorrect Rx packet validation * Using memory without a refcount * Syzkaller found use before initialization * Regression fix for missing locking with the tasklet conversion from this merge window - Have bnxt report the correct link properties to userspace, this was a regression in v6.3 - Several mlx5 bug fixes: * Kernel crash triggerable by userspace for the RAW ethernet profile * Defend against steering refcounting issues created by userspace * Incorrect change of QP port affinity parameters in some LAG configurations - Fix mlx5 Q counters: * Do not over allocate Q counters to allow userspace to use the full port capacity * Kernel crash triggered by eswitch due to mis-use of Q counters * Incorrect mlx5_device for Q counters in some LAG configurations - Properly implement the IBA spec restricting privileged qkeys to root - Always an error when reading from a disassociated device's event queue - isert bug fixes: * Avoid a deadlock with the CM handler and CM ID destruction * Correct list corruption due to incorrect locking * Fix a use after free around connection tear down" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/rxe: Fix rxe_cq_post IB/isert: Fix incorrect release of isert connection IB/isert: Fix possible list corruption in CMA handler IB/isert: Fix dead lock in ib_isert RDMA/mlx5: Fix affinity assignment IB/uverbs: Fix to consider event queue closing also upon non-blocking mode RDMA/uverbs: Restrict usage of privileged QKEYs RDMA/cma: Always set static rate to 0 for RoCE RDMA/mlx5: Fix Q-counters query in LAG mode RDMA/mlx5: Remove vport Q-counters dependency on normal Q-counters RDMA/mlx5: Fix Q-counters per vport allocation RDMA/mlx5: Create an indirect flow table for steering anchor RDMA/mlx5: Initiate dropless RQ for RAW Ethernet functions RDMA/rxe: Fix the use-before-initialization error of resp_pkts RDMA/bnxt_re: Fix reporting active_{speed,width} attributes RDMA/rxe: Fix ref count error in check_rkey() RDMA/rxe: Fix packet length checks RDMA/rtrs: Fix rxe_dealloc_pd warning RDMA/rtrs: Fix the last iu->buf leak in err path

Linus Torvalds committed 3 years ago

Commit 93fd8eb2 parents b7feaa4 0c7e31422 files · +447 −130Browse files

Unified · Split

22 files
  1. drivers/infiniband/core/cma.c +2 −2
  2. drivers/infiniband/core/uverbs_cmd.c +6 −1
  3. drivers/infiniband/core/uverbs_main.c +5 −7
  4. drivers/infiniband/hw/bnxt_re/bnxt_re.h +0 −2
  5. drivers/infiniband/hw/bnxt_re/ib_verbs.c +4 −3
  6. drivers/infiniband/hw/bnxt_re/main.c +0 −2
  7. drivers/infiniband/hw/mlx5/counters.c +62 −27
  8. drivers/infiniband/hw/mlx5/fs.c +269 −7
  9. drivers/infiniband/hw/mlx5/fs.h +16 −0
  10. drivers/infiniband/hw/mlx5/main.c +3 −0
  11. drivers/infiniband/hw/mlx5/mlx5_ib.h +14 −0
  12. drivers/infiniband/hw/mlx5/qp.c +3 −0
  13. drivers/infiniband/sw/rxe/rxe_cq.c +2 −2
  14. drivers/infiniband/sw/rxe/rxe_net.c +6 −0
  15. drivers/infiniband/sw/rxe/rxe_qp.c +3 −4
  16. drivers/infiniband/sw/rxe/rxe_resp.c +2 −1
  17. drivers/infiniband/ulp/isert/ib_isert.c +12 −4
  18. drivers/infiniband/ulp/rtrs/rtrs-clt.c +23 −32
  19. drivers/infiniband/ulp/rtrs/rtrs.c +3 −1
  20. drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +0 −12
  21. include/linux/mlx5/driver.h +12 −0
  22. include/rdma/ib_addr.h +0 −23
drivers/infiniband/core/cma.c+2−2
@@ -3295,7 +3295,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) · 3294 unmodified lines
32953295 route->path_rec->traffic_class = tos;
32963296 route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
32973297 route->path_rec->rate_selector = IB_SA_EQ;
3298− route->path_rec->rate = iboe_get_rate(ndev);
3298+ route->path_rec->rate = IB_RATE_PORT_CURRENT;
32993299 dev_put(ndev);
33003300 route->path_rec->packet_life_time_selector = IB_SA_EQ;
33013301 /* In case ACK timeout is set, use this value to calculate
@@ -4964,7 +4964,7 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv, · 1662 unmodified lines
49644964 if (!ndev)
49654965 return -ENODEV;
49664966
4967− ib.rec.rate = iboe_get_rate(ndev);
4967+ ib.rec.rate = IB_RATE_PORT_CURRENT;
49684968 ib.rec.hop_limit = 1;
49694969 ib.rec.mtu = iboe_get_mtu(ndev->mtu);
49704970
drivers/infiniband/core/uverbs_cmd.c+6−1
@@ -1850,8 +1850,13 @@ static int modify_qp(struct uverbs_attr_bundle *attrs, · 1849 unmodified lines
18501850 attr->path_mtu = cmd->base.path_mtu;
18511851 if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
18521852 attr->path_mig_state = cmd->base.path_mig_state;
1853− if (cmd->base.attr_mask & IB_QP_QKEY)
1853+ if (cmd->base.attr_mask & IB_QP_QKEY) {
1854+ if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
1855+ ret = -EPERM;
1856+ goto release_qp;
1857+ }
18541858 attr->qkey = cmd->base.qkey;
1859+ }
18551860 if (cmd->base.attr_mask & IB_QP_RQ_PSN)
18561861 attr->rq_psn = cmd->base.rq_psn;
18571862 if (cmd->base.attr_mask & IB_QP_SQ_PSN)
drivers/infiniband/core/uverbs_main.c+5−7
@@ -222,8 +222,12 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue, · 221 unmodified lines
222222 spin_lock_irq(&ev_queue->lock);
223223
224224 while (list_empty(&ev_queue->event_list)) {
225− spin_unlock_irq(&ev_queue->lock);
225+ if (ev_queue->is_closed) {
226+ spin_unlock_irq(&ev_queue->lock);
227+ return -EIO;
228+ }
226229
230+ spin_unlock_irq(&ev_queue->lock);
227231 if (filp->f_flags & O_NONBLOCK)
228232 return -EAGAIN;
229233
@@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue, · 3 unmodified lines
233237 return -ERESTARTSYS;
234238
235239 spin_lock_irq(&ev_queue->lock);
236−
237− /* If device was disassociated and no event exists set an error */
238− if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
239− spin_unlock_irq(&ev_queue->lock);
240− return -EIO;
241− }
242240 }
243241
244242 event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);
drivers/infiniband/hw/bnxt_re/bnxt_re.h+0−2
@@ -135,8 +135,6 @@ struct bnxt_re_dev { · 134 unmodified lines
135135
136136 struct delayed_work worker;
137137 u8 cur_prio_map;
138− u16 active_speed;
139− u8 active_width;
140138
141139 /* FP Notification Queue (CQ & SRQ) */
142140 struct tasklet_struct nq_task;
drivers/infiniband/hw/bnxt_re/ib_verbs.c+4−3
@@ -199,6 +199,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num, · 198 unmodified lines
199199 {
200200 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
201201 struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
202+ int rc;
202203
203204 memset(port_attr, 0, sizeof(*port_attr));
204205
@@ -228,10 +229,10 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num, · 23 unmodified lines
228229 port_attr->sm_sl = 0;
229230 port_attr->subnet_timeout = 0;
230231 port_attr->init_type_reply = 0;
231− port_attr->active_speed = rdev->active_speed;
232− port_attr->active_width = rdev->active_width;
232+ rc = ib_get_eth_speed(&rdev->ibdev, port_num, &port_attr->active_speed,
233+ &port_attr->active_width);
233234
234− return 0;
235+ return rc;
235236 }
236237
237238 int bnxt_re_get_port_immutable(struct ib_device *ibdev, u32 port_num,
drivers/infiniband/hw/bnxt_re/main.c+0−2
@@ -1077,8 +1077,6 @@ static int bnxt_re_ib_init(struct bnxt_re_dev *rdev) · 1076 unmodified lines
10771077 return rc;
10781078 }
10791079 dev_info(rdev_to_dev(rdev), "Device registered with IB successfully");
1080− ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
1081− &rdev->active_width);
10821080 set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
10831081
10841082 event = netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev) ?
drivers/infiniband/hw/mlx5/counters.c+62−27
@@ -209,7 +209,8 @@ static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev, · 208 unmodified lines
209209 !vport_qcounters_supported(dev)) || !port_num)
210210 return &dev->port[0].cnts;
211211
212− return &dev->port[port_num - 1].cnts;
212+ return is_mdev_switchdev_mode(dev->mdev) ?
213+ &dev->port[1].cnts : &dev->port[port_num - 1].cnts;
213214 }
214215
215216 /**
@@ -262,7 +263,7 @@ static struct rdma_hw_stats * · 46 unmodified lines
262263 mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)
263264 {
264265 struct mlx5_ib_dev *dev = to_mdev(ibdev);
265− const struct mlx5_ib_counters *cnts = &dev->port[port_num - 1].cnts;
266+ const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
266267
267268 return do_alloc_stats(cnts);
268269 }
@@ -329,6 +330,7 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev, · 60 unmodified lines
329330 {
330331 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
331332 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
333+ struct mlx5_core_dev *mdev;
332334 __be32 val;
333335 int ret, i;
334336
@@ -336,12 +338,16 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev, · 1 unmodified line
336338 dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)
337339 return 0;
338340
341+ mdev = mlx5_eswitch_get_core_dev(dev->port[port_num].rep->esw);
342+ if (!mdev)
343+ return -EOPNOTSUPP;
344+
339345 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
340346 MLX5_SET(query_q_counter_in, in, other_vport, 1);
341347 MLX5_SET(query_q_counter_in, in, vport_number,
342348 dev->port[port_num].rep->vport);
343349 MLX5_SET(query_q_counter_in, in, aggregate, 1);
344− ret = mlx5_cmd_exec_inout(dev->mdev, query_q_counter, in, out);
350+ ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);
345351 if (ret)
346352 return ret;
347353
@@ -575,43 +581,53 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev, · 227 unmodified lines
575581 bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
576582 port_num != MLX5_VPORT_PF;
577583 const struct mlx5_ib_counter *names;
578− int j = 0, i;
584+ int j = 0, i, size;
579585
580586 names = is_vport ? vport_basic_q_cnts : basic_q_cnts;
581− for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) {
587+ size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
588+ ARRAY_SIZE(basic_q_cnts);
589+ for (i = 0; i < size; i++, j++) {
582590 descs[j].name = names[i].name;
583− offsets[j] = basic_q_cnts[i].offset;
591+ offsets[j] = names[i].offset;
584592 }
585593
586594 names = is_vport ? vport_out_of_seq_q_cnts : out_of_seq_q_cnts;
595+ size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
596+ ARRAY_SIZE(out_of_seq_q_cnts);
587597 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {
588− for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) {
598+ for (i = 0; i < size; i++, j++) {
589599 descs[j].name = names[i].name;
590− offsets[j] = out_of_seq_q_cnts[i].offset;
600+ offsets[j] = names[i].offset;
591601 }
592602 }
593603
594604 names = is_vport ? vport_retrans_q_cnts : retrans_q_cnts;
605+ size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
606+ ARRAY_SIZE(retrans_q_cnts);
595607 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {
596− for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) {
608+ for (i = 0; i < size; i++, j++) {
597609 descs[j].name = names[i].name;
598− offsets[j] = retrans_q_cnts[i].offset;
610+ offsets[j] = names[i].offset;
599611 }
600612 }
601613
602614 names = is_vport ? vport_extended_err_cnts : extended_err_cnts;
615+ size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
616+ ARRAY_SIZE(extended_err_cnts);
603617 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
604− for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
618+ for (i = 0; i < size; i++, j++) {
605619 descs[j].name = names[i].name;
606− offsets[j] = extended_err_cnts[i].offset;
620+ offsets[j] = names[i].offset;
607621 }
608622 }
609623
610624 names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts;
625+ size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
626+ ARRAY_SIZE(roce_accl_cnts);
611627 if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
612− for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) {
628+ for (i = 0; i < size; i++, j++) {
613629 descs[j].name = names[i].name;
614− offsets[j] = roce_accl_cnts[i].offset;
630+ offsets[j] = names[i].offset;
615631 }
616632 }
617633
@@ -661,25 +677,37 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev, · 43 unmodified lines
661677 static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
662678 struct mlx5_ib_counters *cnts, u32 port_num)
663679 {
664− u32 num_counters, num_op_counters = 0;
680+ bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
681+ port_num != MLX5_VPORT_PF;
682+ u32 num_counters, num_op_counters = 0, size;
665683
666− num_counters = ARRAY_SIZE(basic_q_cnts);
684+ size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
685+ ARRAY_SIZE(basic_q_cnts);
686+ num_counters = size;
667687
688+ size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
689+ ARRAY_SIZE(out_of_seq_q_cnts);
668690 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))
669− num_counters += ARRAY_SIZE(out_of_seq_q_cnts);
691+ num_counters += size;
670692
693+ size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
694+ ARRAY_SIZE(retrans_q_cnts);
671695 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
672− num_counters += ARRAY_SIZE(retrans_q_cnts);
696+ num_counters += size;
673697
698+ size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
699+ ARRAY_SIZE(extended_err_cnts);
674700 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
675− num_counters += ARRAY_SIZE(extended_err_cnts);
701+ num_counters += size;
676702
703+ size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
704+ ARRAY_SIZE(roce_accl_cnts);
677705 if (MLX5_CAP_GEN(dev->mdev, roce_accl))
678− num_counters += ARRAY_SIZE(roce_accl_cnts);
706+ num_counters += size;
679707
680708 cnts->num_q_counters = num_counters;
681709
682− if (is_mdev_switchdev_mode(dev->mdev) && port_num != MLX5_VPORT_PF)
710+ if (is_vport)
683711 goto skip_non_qcounters;
684712
685713 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
@@ -725,11 +753,11 @@ err: · 39 unmodified lines
725753 static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
726754 {
727755 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
728− int num_cnt_ports;
756+ int num_cnt_ports = dev->num_ports;
729757 int i, j;
730758
731− num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
732− vport_qcounters_supported(dev)) ? dev->num_ports : 1;
759+ if (is_mdev_switchdev_mode(dev->mdev))
760+ num_cnt_ports = min(2, num_cnt_ports);
733761
734762 MLX5_SET(dealloc_q_counter_in, in, opcode,
735763 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
@@ -761,15 +789,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev) · 25 unmodified lines
761789 {
762790 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
763791 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
764− int num_cnt_ports;
792+ int num_cnt_ports = dev->num_ports;
765793 int err = 0;
766794 int i;
767795 bool is_shared;
768796
769797 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
770798 is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
771− num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
772− vport_qcounters_supported(dev)) ? dev->num_ports : 1;
799+
800+ /*
801+ * In switchdev we need to allocate two ports, one that is used for
802+ * the device Q_counters and it is essentially the real Q_counters of
803+ * this device, while the other is used as a helper for PF to be able to
804+ * query all other vports.
805+ */
806+ if (is_mdev_switchdev_mode(dev->mdev))
807+ num_cnt_ports = min(2, num_cnt_ports);
773808
774809 for (i = 0; i < num_cnt_ports; i++) {
775810 err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);
drivers/infiniband/hw/mlx5/fs.c+269−7
@@ -695,8 +695,6 @@ static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_ib_dev *dev, · 694 unmodified lines
695695 struct mlx5_flow_table_attr ft_attr = {};
696696 struct mlx5_flow_table *ft;
697697
698− if (mlx5_ib_shared_ft_allowed(&dev->ib_dev))
699− ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
700698 ft_attr.prio = priority;
701699 ft_attr.max_fte = num_entries;
702700 ft_attr.flags = flags;
@@ -2025,6 +2023,237 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject, · 1322 unmodified lines
20252023 return 0;
20262024 }
20272025
2026+static int steering_anchor_create_ft(struct mlx5_ib_dev *dev,
2027+ struct mlx5_ib_flow_prio *ft_prio,
2028+ enum mlx5_flow_namespace_type ns_type)
2029+{
2030+ struct mlx5_flow_table_attr ft_attr = {};
2031+ struct mlx5_flow_namespace *ns;
2032+ struct mlx5_flow_table *ft;
2033+
2034+ if (ft_prio->anchor.ft)
2035+ return 0;
2036+
2037+ ns = mlx5_get_flow_namespace(dev->mdev, ns_type);
2038+ if (!ns)
2039+ return -EOPNOTSUPP;
2040+
2041+ ft_attr.flags = MLX5_FLOW_TABLE_UNMANAGED;
2042+ ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
2043+ ft_attr.prio = 0;
2044+ ft_attr.max_fte = 2;
2045+ ft_attr.level = 1;
2046+
2047+ ft = mlx5_create_flow_table(ns, &ft_attr);
2048+ if (IS_ERR(ft))
2049+ return PTR_ERR(ft);
2050+
2051+ ft_prio->anchor.ft = ft;
2052+
2053+ return 0;
2054+}
2055+
2056+static void steering_anchor_destroy_ft(struct mlx5_ib_flow_prio *ft_prio)
2057+{
2058+ if (ft_prio->anchor.ft) {
2059+ mlx5_destroy_flow_table(ft_prio->anchor.ft);
2060+ ft_prio->anchor.ft = NULL;
2061+ }
2062+}
2063+
2064+static int
2065+steering_anchor_create_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
2066+{
2067+ int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
2068+ struct mlx5_flow_group *fg;
2069+ void *flow_group_in;
2070+ int err = 0;
2071+
2072+ if (ft_prio->anchor.fg_drop)
2073+ return 0;
2074+
2075+ flow_group_in = kvzalloc(inlen, GFP_KERNEL);
2076+ if (!flow_group_in)
2077+ return -ENOMEM;
2078+
2079+ MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1);
2080+ MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
2081+
2082+ fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
2083+ if (IS_ERR(fg)) {
2084+ err = PTR_ERR(fg);
2085+ goto out;
2086+ }
2087+
2088+ ft_prio->anchor.fg_drop = fg;
2089+
2090+out:
2091+ kvfree(flow_group_in);
2092+
2093+ return err;
2094+}
2095+
2096+static void
2097+steering_anchor_destroy_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
2098+{
2099+ if (ft_prio->anchor.fg_drop) {
2100+ mlx5_destroy_flow_group(ft_prio->anchor.fg_drop);
2101+ ft_prio->anchor.fg_drop = NULL;
2102+ }
2103+}
2104+
2105+static int
2106+steering_anchor_create_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
2107+{
2108+ int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
2109+ struct mlx5_flow_group *fg;
2110+ void *flow_group_in;
2111+ int err = 0;
2112+
2113+ if (ft_prio->anchor.fg_goto_table)
2114+ return 0;
2115+
2116+ flow_group_in = kvzalloc(inlen, GFP_KERNEL);
2117+ if (!flow_group_in)
2118+ return -ENOMEM;
2119+
2120+ fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
2121+ if (IS_ERR(fg)) {
2122+ err = PTR_ERR(fg);
2123+ goto out;
2124+ }
2125+ ft_prio->anchor.fg_goto_table = fg;
2126+
2127+out:
2128+ kvfree(flow_group_in);
2129+
2130+ return err;
2131+}
2132+
2133+static void
2134+steering_anchor_destroy_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
2135+{
2136+ if (ft_prio->anchor.fg_goto_table) {
2137+ mlx5_destroy_flow_group(ft_prio->anchor.fg_goto_table);
2138+ ft_prio->anchor.fg_goto_table = NULL;
2139+ }
2140+}
2141+
2142+static int
2143+steering_anchor_create_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
2144+{
2145+ struct mlx5_flow_act flow_act = {};
2146+ struct mlx5_flow_handle *handle;
2147+
2148+ if (ft_prio->anchor.rule_drop)
2149+ return 0;
2150+
2151+ flow_act.fg = ft_prio->anchor.fg_drop;
2152+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
2153+
2154+ handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
2155+ NULL, 0);
2156+ if (IS_ERR(handle))
2157+ return PTR_ERR(handle);
2158+
2159+ ft_prio->anchor.rule_drop = handle;
2160+
2161+ return 0;
2162+}
2163+
2164+static void steering_anchor_destroy_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
2165+{
2166+ if (ft_prio->anchor.rule_drop) {
2167+ mlx5_del_flow_rules(ft_prio->anchor.rule_drop);
2168+ ft_prio->anchor.rule_drop = NULL;
2169+ }
2170+}
2171+
2172+static int
2173+steering_anchor_create_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
2174+{
2175+ struct mlx5_flow_destination dest = {};
2176+ struct mlx5_flow_act flow_act = {};
2177+ struct mlx5_flow_handle *handle;
2178+
2179+ if (ft_prio->anchor.rule_goto_table)
2180+ return 0;
2181+
2182+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
2183+ flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
2184+ flow_act.fg = ft_prio->anchor.fg_goto_table;
2185+
2186+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
2187+ dest.ft = ft_prio->flow_table;
2188+
2189+ handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
2190+ &dest, 1);
2191+ if (IS_ERR(handle))
2192+ return PTR_ERR(handle);
2193+
2194+ ft_prio->anchor.rule_goto_table = handle;
2195+
2196+ return 0;
2197+}
2198+
2199+static void
2200+steering_anchor_destroy_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
2201+{
2202+ if (ft_prio->anchor.rule_goto_table) {
2203+ mlx5_del_flow_rules(ft_prio->anchor.rule_goto_table);
2204+ ft_prio->anchor.rule_goto_table = NULL;
2205+ }
2206+}
2207+
2208+static int steering_anchor_create_res(struct mlx5_ib_dev *dev,
2209+ struct mlx5_ib_flow_prio *ft_prio,
2210+ enum mlx5_flow_namespace_type ns_type)
2211+{
2212+ int err;
2213+
2214+ err = steering_anchor_create_ft(dev, ft_prio, ns_type);
2215+ if (err)
2216+ return err;
2217+
2218+ err = steering_anchor_create_fg_drop(ft_prio);
2219+ if (err)
2220+ goto destroy_ft;
2221+
2222+ err = steering_anchor_create_fg_goto_table(ft_prio);
2223+ if (err)
2224+ goto destroy_fg_drop;
2225+
2226+ err = steering_anchor_create_rule_drop(ft_prio);
2227+ if (err)
2228+ goto destroy_fg_goto_table;
2229+
2230+ err = steering_anchor_create_rule_goto_table(ft_prio);
2231+ if (err)
2232+ goto destroy_rule_drop;
2233+
2234+ return 0;
2235+
2236+destroy_rule_drop:
2237+ steering_anchor_destroy_rule_drop(ft_prio);
2238+destroy_fg_goto_table:
2239+ steering_anchor_destroy_fg_goto_table(ft_prio);
2240+destroy_fg_drop:
2241+ steering_anchor_destroy_fg_drop(ft_prio);
2242+destroy_ft:
2243+ steering_anchor_destroy_ft(ft_prio);
2244+
2245+ return err;
2246+}
2247+
2248+static void mlx5_steering_anchor_destroy_res(struct mlx5_ib_flow_prio *ft_prio)
2249+{
2250+ steering_anchor_destroy_rule_goto_table(ft_prio);
2251+ steering_anchor_destroy_rule_drop(ft_prio);
2252+ steering_anchor_destroy_fg_goto_table(ft_prio);
2253+ steering_anchor_destroy_fg_drop(ft_prio);
2254+ steering_anchor_destroy_ft(ft_prio);
2255+}
2256+
20282257 static int steering_anchor_cleanup(struct ib_uobject *uobject,
20292258 enum rdma_remove_reason why,
20302259 struct uverbs_attr_bundle *attrs)
@@ -2035,6 +2264,9 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject, · 4 unmodified lines
20352264 return -EBUSY;
20362265
20372266 mutex_lock(&obj->dev->flow_db->lock);
2267+ if (!--obj->ft_prio->anchor.rule_goto_table_ref)
2268+ steering_anchor_destroy_rule_goto_table(obj->ft_prio);
2269+
20382270 put_flow_table(obj->dev, obj->ft_prio, true);
20392271 mutex_unlock(&obj->dev->flow_db->lock);
20402272
@@ -2042,6 +2274,24 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject, · 1 unmodified line
20422274 return 0;
20432275 }
20442276
2277+static void fs_cleanup_anchor(struct mlx5_ib_flow_prio *prio,
2278+ int count)
2279+{
2280+ while (count--)
2281+ mlx5_steering_anchor_destroy_res(&prio[count]);
2282+}
2283+
2284+void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev)
2285+{
2286+ fs_cleanup_anchor(dev->flow_db->prios, MLX5_IB_NUM_FLOW_FT);
2287+ fs_cleanup_anchor(dev->flow_db->egress_prios, MLX5_IB_NUM_FLOW_FT);
2288+ fs_cleanup_anchor(dev->flow_db->sniffer, MLX5_IB_NUM_SNIFFER_FTS);
2289+ fs_cleanup_anchor(dev->flow_db->egress, MLX5_IB_NUM_EGRESS_FTS);
2290+ fs_cleanup_anchor(dev->flow_db->fdb, MLX5_IB_NUM_FDB_FTS);
2291+ fs_cleanup_anchor(dev->flow_db->rdma_rx, MLX5_IB_NUM_FLOW_FT);
2292+ fs_cleanup_anchor(dev->flow_db->rdma_tx, MLX5_IB_NUM_FLOW_FT);
2293+}
2294+
20452295 static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
20462296 struct mlx5_ib_flow_matcher *obj)
20472297 {
@@ -2182,21 +2432,31 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)( · 134 unmodified lines
21822432 return -ENOMEM;
21832433
21842434 mutex_lock(&dev->flow_db->lock);
2435+
21852436 ft_prio = _get_flow_table(dev, priority, ns_type, 0);
21862437 if (IS_ERR(ft_prio)) {
2187− mutex_unlock(&dev->flow_db->lock);
21882438 err = PTR_ERR(ft_prio);
21892439 goto free_obj;
21902440 }
21912441
21922442 ft_prio->refcount++;
2193− ft_id = mlx5_flow_table_id(ft_prio->flow_table);
2194− mutex_unlock(&dev->flow_db->lock);
2443+
2444+ if (!ft_prio->anchor.rule_goto_table_ref) {
2445+ err = steering_anchor_create_res(dev, ft_prio, ns_type);
2446+ if (err)
2447+ goto put_flow_table;
2448+ }
2449+
2450+ ft_prio->anchor.rule_goto_table_ref++;
2451+
2452+ ft_id = mlx5_flow_table_id(ft_prio->anchor.ft);
21952453
21962454 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,
21972455 &ft_id, sizeof(ft_id));
21982456 if (err)
2199− goto put_flow_table;
2457+ goto destroy_res;
2458+
2459+ mutex_unlock(&dev->flow_db->lock);
22002460
22012461 uobj->object = obj;
22022462 obj->dev = dev;
@@ -2205,8 +2465,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)( · 2 unmodified lines
22052465
22062466 return 0;
22072467
2468+destroy_res:
2469+ --ft_prio->anchor.rule_goto_table_ref;
2470+ mlx5_steering_anchor_destroy_res(ft_prio);
22082471 put_flow_table:
2209− mutex_lock(&dev->flow_db->lock);
22102472 put_flow_table(dev, ft_prio, true);
22112473 mutex_unlock(&dev->flow_db->lock);
22122474 free_obj:
drivers/infiniband/hw/mlx5/fs.h+16−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010
1111 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
1212 int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);
13+void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev);
1314 #else
1415 static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
1516 {
@@ -21,9 +22,24 @@ static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev) · 5 unmodified lines
2122 mutex_init(&dev->flow_db->lock);
2223 return 0;
2324 }
25+
26+inline void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev) {}
2427 #endif
28+
2529 static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)
2630 {
31+ /* When a steering anchor is created, a special flow table is also
32+ * created for the user to reference. Since the user can reference it,
33+ * the kernel cannot trust that when the user destroys the steering
34+ * anchor, they no longer reference the flow table.
35+ *
36+ * To address this issue, when a user destroys a steering anchor, only
37+ * the flow steering rule in the table is destroyed, but the table
38+ * itself is kept to deal with the above scenario. The remaining
39+ * resources are only removed when the RDMA device is destroyed, which
40+ * is a safe assumption that all references are gone.
41+ */
42+ mlx5_ib_fs_cleanup_anchor(dev);
2743 kfree(dev->flow_db);
2844 }
2945 #endif /* _MLX5_IB_FS_H */
drivers/infiniband/hw/mlx5/main.c+3−0
@@ -4275,6 +4275,9 @@ const struct mlx5_ib_profile raw_eth_profile = { · 4274 unmodified lines
42754275 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
42764276 mlx5_ib_stage_post_ib_reg_umr_init,
42774277 NULL),
4278+ STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
4279+ mlx5_ib_stage_delay_drop_init,
4280+ mlx5_ib_stage_delay_drop_cleanup),
42784281 STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
42794282 mlx5_ib_restrack_init,
42804283 NULL),
drivers/infiniband/hw/mlx5/mlx5_ib.h+14−0
@@ -237,8 +237,19 @@ enum { · 236 unmodified lines
237237 #define MLX5_IB_NUM_SNIFFER_FTS 2
238238 #define MLX5_IB_NUM_EGRESS_FTS 1
239239 #define MLX5_IB_NUM_FDB_FTS MLX5_BY_PASS_NUM_REGULAR_PRIOS
240+
241+struct mlx5_ib_anchor {
242+ struct mlx5_flow_table *ft;
243+ struct mlx5_flow_group *fg_goto_table;
244+ struct mlx5_flow_group *fg_drop;
245+ struct mlx5_flow_handle *rule_goto_table;
246+ struct mlx5_flow_handle *rule_drop;
247+ unsigned int rule_goto_table_ref;
248+};
249+
240250 struct mlx5_ib_flow_prio {
241251 struct mlx5_flow_table *flow_table;
252+ struct mlx5_ib_anchor anchor;
242253 unsigned int refcount;
243254 };
244255
@@ -1587,6 +1598,9 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev) · 1342 unmodified lines
15871598 MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))
15881599 return 0;
15891600
1601+ if (mlx5_lag_is_lacp_owner(dev->mdev) && !dev->lag_active)
1602+ return 0;
1603+
15901604 return dev->lag_active ||
15911605 (MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
15921606 MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));
drivers/infiniband/hw/mlx5/qp.c+3−0
@@ -1237,6 +1237,9 @@ static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev, · 1236 unmodified lines
12371237
12381238 MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);
12391239 MLX5_SET(tisc, tisc, transport_domain, tdn);
1240+ if (!mlx5_ib_lag_should_assign_affinity(dev) &&
1241+ mlx5_lag_is_lacp_owner(dev->mdev))
1242+ MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);
12401243 if (qp->flags & IB_QP_CREATE_SOURCE_QPN)
12411244 MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
12421245
drivers/infiniband/sw/rxe/rxe_cq.c+2−2
@@ -113,8 +113,6 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) · 112 unmodified lines
113113
114114 queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);
115115
116− spin_unlock_irqrestore(&cq->cq_lock, flags);
117−
118116 if ((cq->notify == IB_CQ_NEXT_COMP) ||
119117 (cq->notify == IB_CQ_SOLICITED && solicited)) {
120118 cq->notify = 0;
@@ -122,6 +120,8 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) · 1 unmodified line
122120 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
123121 }
124122
123+ spin_unlock_irqrestore(&cq->cq_lock, flags);
124+
125125 return 0;
126126 }
127127
drivers/infiniband/sw/rxe/rxe_net.c+6−0
@@ -159,6 +159,9 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 158 unmodified lines
159159 pkt->mask = RXE_GRH_MASK;
160160 pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);
161161
162+ /* remove udp header */
163+ skb_pull(skb, sizeof(struct udphdr));
164+
162165 rxe_rcv(skb);
163166
164167 return 0;
@@ -401,6 +404,9 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 236 unmodified lines
401404 return -EIO;
402405 }
403406
407+ /* remove udp header */
408+ skb_pull(skb, sizeof(struct udphdr));
409+
404410 rxe_rcv(skb);
405411
406412 return 0;
drivers/infiniband/sw/rxe/rxe_qp.c+3−4
@@ -176,6 +176,9 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp, · 175 unmodified lines
176176 spin_lock_init(&qp->rq.producer_lock);
177177 spin_lock_init(&qp->rq.consumer_lock);
178178
179+ skb_queue_head_init(&qp->req_pkts);
180+ skb_queue_head_init(&qp->resp_pkts);
181+
179182 atomic_set(&qp->ssn, 0);
180183 atomic_set(&qp->skb_out, 0);
181184 }
@@ -234,8 +237,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, · 52 unmodified lines
234237 qp->req.opcode = -1;
235238 qp->comp.opcode = -1;
236239
237− skb_queue_head_init(&qp->req_pkts);
238−
239240 rxe_init_task(&qp->req.task, qp, rxe_requester);
240241 rxe_init_task(&qp->comp.task, qp, rxe_completer);
241242
@@ -279,8 +280,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, · 37 unmodified lines
279280 }
280281 }
281282
282− skb_queue_head_init(&qp->resp_pkts);
283−
284283 rxe_init_task(&qp->resp.task, qp, rxe_responder);
285284
286285 qp->resp.opcode = OPCODE_NONE;
drivers/infiniband/sw/rxe/rxe_resp.c+2−1
@@ -489,8 +489,9 @@ static enum resp_states check_rkey(struct rxe_qp *qp, · 488 unmodified lines
489489 if (mw->access & IB_ZERO_BASED)
490490 qp->resp.offset = mw->addr;
491491
492− rxe_put(mw);
493492 rxe_get(mr);
493+ rxe_put(mw);
494+ mw = NULL;
494495 } else {
495496 mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
496497 if (!mr) {
drivers/infiniband/ulp/isert/ib_isert.c+12−4
@@ -657,9 +657,13 @@ static int · 656 unmodified lines
657657 isert_connect_error(struct rdma_cm_id *cma_id)
658658 {
659659 struct isert_conn *isert_conn = cma_id->qp->qp_context;
660+ struct isert_np *isert_np = cma_id->context;
660661
661662 ib_drain_qp(isert_conn->qp);
663+
664+ mutex_lock(&isert_np->mutex);
662665 list_del_init(&isert_conn->node);
666+ mutex_unlock(&isert_np->mutex);
663667 isert_conn->cm_id = NULL;
664668 isert_put_conn(isert_conn);
665669
@@ -2431,6 +2435,7 @@ isert_free_np(struct iscsi_np *np) · 1765 unmodified lines
24312435 {
24322436 struct isert_np *isert_np = np->np_context;
24332437 struct isert_conn *isert_conn, *n;
2438+ LIST_HEAD(drop_conn_list);
24342439
24352440 if (isert_np->cm_id)
24362441 rdma_destroy_id(isert_np->cm_id);
@@ -2450,7 +2455,7 @@ isert_free_np(struct iscsi_np *np) · 13 unmodified lines
24502455 node) {
24512456 isert_info("cleaning isert_conn %p state (%d)\n",
24522457 isert_conn, isert_conn->state);
2453− isert_connect_release(isert_conn);
2458+ list_move_tail(&isert_conn->node, &drop_conn_list);
24542459 }
24552460 }
24562461
@@ -2461,11 +2466,16 @@ isert_free_np(struct iscsi_np *np) · 4 unmodified lines
24612466 node) {
24622467 isert_info("cleaning isert_conn %p state (%d)\n",
24632468 isert_conn, isert_conn->state);
2464− isert_connect_release(isert_conn);
2469+ list_move_tail(&isert_conn->node, &drop_conn_list);
24652470 }
24662471 }
24672472 mutex_unlock(&isert_np->mutex);
24682473
2474+ list_for_each_entry_safe(isert_conn, n, &drop_conn_list, node) {
2475+ list_del_init(&isert_conn->node);
2476+ isert_connect_release(isert_conn);
2477+ }
2478+
24692479 np->np_context = NULL;
24702480 kfree(isert_np);
24712481 }
@@ -2560,8 +2570,6 @@ static void isert_wait_conn(struct iscsit_conn *conn) · 88 unmodified lines
25602570 isert_put_unsol_pending_cmds(conn);
25612571 isert_wait4cmds(conn);
25622572 isert_wait4logout(isert_conn);
2563−
2564− queue_work(isert_release_wq, &isert_conn->release_work);
25652573 }
25662574
25672575 static void isert_free_conn(struct iscsit_conn *conn)
drivers/infiniband/ulp/rtrs/rtrs-clt.c+23−32
@@ -2040,6 +2040,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id, · 2039 unmodified lines
20402040 return 0;
20412041 }
20422042
2043+/* The caller should do the cleanup in case of error */
20432044 static int create_cm(struct rtrs_clt_con *con)
20442045 {
20452046 struct rtrs_path *s = con->c.path;
@@ -2062,14 +2063,14 @@ static int create_cm(struct rtrs_clt_con *con) · 16 unmodified lines
20622063 err = rdma_set_reuseaddr(cm_id, 1);
20632064 if (err != 0) {
20642065 rtrs_err(s, "Set address reuse failed, err: %d\n", err);
2065− goto destroy_cm;
2066+ return err;
20662067 }
20672068 err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,
20682069 (struct sockaddr *)&clt_path->s.dst_addr,
20692070 RTRS_CONNECT_TIMEOUT_MS);
20702071 if (err) {
20712072 rtrs_err(s, "Failed to resolve address, err: %d\n", err);
2072− goto destroy_cm;
2073+ return err;
20732074 }
20742075 /*
20752076 * Combine connection status and session events. This is needed
@@ -2084,29 +2085,15 @@ static int create_cm(struct rtrs_clt_con *con) · 8 unmodified lines
20842085 if (err == 0)
20852086 err = -ETIMEDOUT;
20862087 /* Timedout or interrupted */
2087− goto errr;
2088− }
2089− if (con->cm_err < 0) {
2090− err = con->cm_err;
2091− goto errr;
2088+ return err;
20922089 }
2093− if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING) {
2090+ if (con->cm_err < 0)
2091+ return con->cm_err;
2092+ if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING)
20942093 /* Device removal */
2095− err = -ECONNABORTED;
2096− goto errr;
2097− }
2094+ return -ECONNABORTED;
20982095
20992096 return 0;
2100−
2101−errr:
2102− stop_cm(con);
2103− mutex_lock(&con->con_mutex);
2104− destroy_con_cq_qp(con);
2105− mutex_unlock(&con->con_mutex);
2106−destroy_cm:
2107− destroy_cm(con);
2108−
2109− return err;
21102097 }
21112098
21122099 static void rtrs_clt_path_up(struct rtrs_clt_path *clt_path)
@@ -2334,7 +2321,7 @@ static void rtrs_clt_close_work(struct work_struct *work) · 221 unmodified lines
23342321 static int init_conns(struct rtrs_clt_path *clt_path)
23352322 {
23362323 unsigned int cid;
2337− int err;
2324+ int err, i;
23382325
23392326 /*
23402327 * On every new session connections increase reconnect counter
@@ -2350,10 +2337,8 @@ static int init_conns(struct rtrs_clt_path *clt_path) · 9 unmodified lines
23502337 goto destroy;
23512338
23522339 err = create_cm(to_clt_con(clt_path->s.con[cid]));
2353− if (err) {
2354− destroy_con(to_clt_con(clt_path->s.con[cid]));
2340+ if (err)
23552341 goto destroy;
2356− }
23572342 }
23582343 err = alloc_path_reqs(clt_path);
23592344 if (err)
@@ -2364,15 +2349,21 @@ static int init_conns(struct rtrs_clt_path *clt_path) · 4 unmodified lines
23642349 return 0;
23652350
23662351 destroy:
2367− while (cid--) {
2368− struct rtrs_clt_con *con = to_clt_con(clt_path->s.con[cid]);
2352+ /* Make sure we do the cleanup in the order they are created */
2353+ for (i = 0; i <= cid; i++) {
2354+ struct rtrs_clt_con *con;
23692355
2370− stop_cm(con);
2356+ if (!clt_path->s.con[i])
2357+ break;
23712358
2372− mutex_lock(&con->con_mutex);
2373− destroy_con_cq_qp(con);
2374− mutex_unlock(&con->con_mutex);
2375− destroy_cm(con);
2359+ con = to_clt_con(clt_path->s.con[i]);
2360+ if (con->c.cm_id) {
2361+ stop_cm(con);
2362+ mutex_lock(&con->con_mutex);
2363+ destroy_con_cq_qp(con);
2364+ mutex_unlock(&con->con_mutex);
2365+ destroy_cm(con);
2366+ }
23762367 destroy_con(con);
23772368 }
23782369 /*
drivers/infiniband/ulp/rtrs/rtrs.c+3−1
@@ -37,8 +37,10 @@ struct rtrs_iu *rtrs_iu_alloc(u32 iu_num, size_t size, gfp_t gfp_mask, · 36 unmodified lines
3737 goto err;
3838
3939 iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);
40− if (ib_dma_mapping_error(dma_dev, iu->dma_addr))
40+ if (ib_dma_mapping_error(dma_dev, iu->dma_addr)) {
41+ kfree(iu->buf);
4142 goto err;
43+ }
4244
4345 iu->cqe.done = done;
4446 iu->size = size;
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h+0−12
@@ -276,18 +276,6 @@ static inline bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev) · 275 unmodified lines
276276 return pci_num_vf(dev->pdev) ? true : false;
277277 }
278278
279−static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
280−{
281− /* LACP owner conditions:
282− * 1) Function is physical.
283− * 2) LAG is supported by FW.
284− * 3) LAG is managed by driver (currently the only option).
285− */
286− return MLX5_CAP_GEN(dev, vport_group_manager) &&
287− (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
288− MLX5_CAP_GEN(dev, lag_master);
289−}
290−
291279 int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);
292280 static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
293281 {
include/linux/mlx5/driver.h+12−0
@@ -1238,6 +1238,18 @@ static inline u16 mlx5_core_max_vfs(const struct mlx5_core_dev *dev) · 1237 unmodified lines
12381238 return dev->priv.sriov.max_vfs;
12391239 }
12401240
1241+static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
1242+{
1243+ /* LACP owner conditions:
1244+ * 1) Function is physical.
1245+ * 2) LAG is supported by FW.
1246+ * 3) LAG is managed by driver (currently the only option).
1247+ */
1248+ return MLX5_CAP_GEN(dev, vport_group_manager) &&
1249+ (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
1250+ MLX5_CAP_GEN(dev, lag_master);
1251+}
1252+
12411253 static inline int mlx5_get_gid_table_len(u16 param)
12421254 {
12431255 if (param > 4) {
include/rdma/ib_addr.h+0−23
@@ -194,29 +194,6 @@ static inline enum ib_mtu iboe_get_mtu(int mtu) · 193 unmodified lines
194194 return 0;
195195 }
196196
197−static inline int iboe_get_rate(struct net_device *dev)
198−{
199− struct ethtool_link_ksettings cmd;
200− int err;
201−
202− rtnl_lock();
203− err = __ethtool_get_link_ksettings(dev, &cmd);
204− rtnl_unlock();
205− if (err)
206− return IB_RATE_PORT_CURRENT;
207−
208− if (cmd.base.speed >= 40000)
209− return IB_RATE_40_GBPS;
210− else if (cmd.base.speed >= 30000)
211− return IB_RATE_30_GBPS;
212− else if (cmd.base.speed >= 20000)
213− return IB_RATE_20_GBPS;
214− else if (cmd.base.speed >= 10000)
215− return IB_RATE_10_GBPS;
216− else
217− return IB_RATE_PORT_CURRENT;
218−}
219−
220197 static inline int rdma_link_local_addr(struct in6_addr *addr)
221198 {
222199 if (addr->s6_addr32[0] == htonl(0xfe800000) &&