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
3295 route->path_rec->traffic_class = tos;3295 route->path_rec->traffic_class = tos;
3296 route->path_rec->mtu = iboe_get_mtu(ndev->mtu);3296 route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
3297 route->path_rec->rate_selector = IB_SA_EQ;3297 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;
3299 dev_put(ndev);3299 dev_put(ndev);
3300 route->path_rec->packet_life_time_selector = IB_SA_EQ;3300 route->path_rec->packet_life_time_selector = IB_SA_EQ;
3301 /* In case ACK timeout is set, use this value to calculate3301 /* 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
4964 if (!ndev)4964 if (!ndev)
4965 return -ENODEV;4965 return -ENODEV;
4966 4966
4967 ib.rec.rate = iboe_get_rate(ndev);4967 ib.rec.rate = IB_RATE_PORT_CURRENT;
4968 ib.rec.hop_limit = 1;4968 ib.rec.hop_limit = 1;
4969 ib.rec.mtu = iboe_get_mtu(ndev->mtu);4969 ib.rec.mtu = iboe_get_mtu(ndev->mtu);
4970 4970
drivers/infiniband/core/uverbs_cmd.c+6−1
@@ -1850,8 +1850,13 @@ static int modify_qp(struct uverbs_attr_bundle *attrs, · 1849 unmodified lines
1850 attr->path_mtu = cmd->base.path_mtu;1850 attr->path_mtu = cmd->base.path_mtu;
1851 if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)1851 if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
1852 attr->path_mig_state = cmd->base.path_mig_state;1852 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 }
1854 attr->qkey = cmd->base.qkey;1858 attr->qkey = cmd->base.qkey;
1859 }
1855 if (cmd->base.attr_mask & IB_QP_RQ_PSN)1860 if (cmd->base.attr_mask & IB_QP_RQ_PSN)
1856 attr->rq_psn = cmd->base.rq_psn;1861 attr->rq_psn = cmd->base.rq_psn;
1857 if (cmd->base.attr_mask & IB_QP_SQ_PSN)1862 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
222 spin_lock_irq(&ev_queue->lock);222 spin_lock_irq(&ev_queue->lock);
223 223
224 while (list_empty(&ev_queue->event_list)) {224 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 }
226 229
230 spin_unlock_irq(&ev_queue->lock);
227 if (filp->f_flags & O_NONBLOCK)231 if (filp->f_flags & O_NONBLOCK)
228 return -EAGAIN;232 return -EAGAIN;
229 233
@@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue, · 3 unmodified lines
233 return -ERESTARTSYS;237 return -ERESTARTSYS;
234 238
235 spin_lock_irq(&ev_queue->lock);239 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 }
242 }240 }
243 241
244 event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);242 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
135 135
136 struct delayed_work worker;136 struct delayed_work worker;
137 u8 cur_prio_map;137 u8 cur_prio_map;
138 u16 active_speed;
139 u8 active_width;
140 138
141 /* FP Notification Queue (CQ & SRQ) */139 /* FP Notification Queue (CQ & SRQ) */
142 struct tasklet_struct nq_task;140 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
199{199{
200 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);200 struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
201 struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;201 struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
202 int rc;
202 203
203 memset(port_attr, 0, sizeof(*port_attr));204 memset(port_attr, 0, sizeof(*port_attr));
204 205
@@ -228,10 +229,10 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num, · 23 unmodified lines
228 port_attr->sm_sl = 0;229 port_attr->sm_sl = 0;
229 port_attr->subnet_timeout = 0;230 port_attr->subnet_timeout = 0;
230 port_attr->init_type_reply = 0;231 port_attr->init_type_reply = 0;
231 port_attr->active_speed = rdev->active_speed;232 rc = ib_get_eth_speed(&rdev->ibdev, port_num, &port_attr->active_speed,
232 port_attr->active_width = rdev->active_width;233 &port_attr->active_width);
233 234
234 return 0;235 return rc;
235}236}
236 237
237int bnxt_re_get_port_immutable(struct ib_device *ibdev, u32 port_num,238int 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
1077 return rc;1077 return rc;
1078 }1078 }
1079 dev_info(rdev_to_dev(rdev), "Device registered with IB successfully");1079 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);
1082 set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);1080 set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
1083 1081
1084 event = netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev) ?1082 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
209 !vport_qcounters_supported(dev)) || !port_num)209 !vport_qcounters_supported(dev)) || !port_num)
210 return &dev->port[0].cnts;210 return &dev->port[0].cnts;
211 211
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;
213}214}
214 215
215/**216/**
@@ -262,7 +263,7 @@ static struct rdma_hw_stats * · 46 unmodified lines
262mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)263mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)
263{264{
264 struct mlx5_ib_dev *dev = to_mdev(ibdev);265 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);
266 267
267 return do_alloc_stats(cnts);268 return do_alloc_stats(cnts);
268}269}
@@ -329,6 +330,7 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev, · 60 unmodified lines
329{330{
330 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};331 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
331 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};332 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
333 struct mlx5_core_dev *mdev;
332 __be32 val;334 __be32 val;
333 int ret, i;335 int ret, i;
334 336
@@ -336,12 +338,16 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev, · 1 unmodified line
336 dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)338 dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)
337 return 0;339 return 0;
338 340
341 mdev = mlx5_eswitch_get_core_dev(dev->port[port_num].rep->esw);
342 if (!mdev)
343 return -EOPNOTSUPP;
344
339 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);345 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
340 MLX5_SET(query_q_counter_in, in, other_vport, 1);346 MLX5_SET(query_q_counter_in, in, other_vport, 1);
341 MLX5_SET(query_q_counter_in, in, vport_number,347 MLX5_SET(query_q_counter_in, in, vport_number,
342 dev->port[port_num].rep->vport);348 dev->port[port_num].rep->vport);
343 MLX5_SET(query_q_counter_in, in, aggregate, 1);349 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);
345 if (ret)351 if (ret)
346 return ret;352 return ret;
347 353
@@ -575,43 +581,53 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev, · 227 unmodified lines
575 bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&581 bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
576 port_num != MLX5_VPORT_PF;582 port_num != MLX5_VPORT_PF;
577 const struct mlx5_ib_counter *names;583 const struct mlx5_ib_counter *names;
578 int j = 0, i;584 int j = 0, i, size;
579 585
580 names = is_vport ? vport_basic_q_cnts : basic_q_cnts;586 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++) {
582 descs[j].name = names[i].name;590 descs[j].name = names[i].name;
583 offsets[j] = basic_q_cnts[i].offset;591 offsets[j] = names[i].offset;
584 }592 }
585 593
586 names = is_vport ? vport_out_of_seq_q_cnts : out_of_seq_q_cnts;594 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);
587 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {597 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++) {
589 descs[j].name = names[i].name;599 descs[j].name = names[i].name;
590 offsets[j] = out_of_seq_q_cnts[i].offset;600 offsets[j] = names[i].offset;
591 }601 }
592 }602 }
593 603
594 names = is_vport ? vport_retrans_q_cnts : retrans_q_cnts;604 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);
595 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {607 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++) {
597 descs[j].name = names[i].name;609 descs[j].name = names[i].name;
598 offsets[j] = retrans_q_cnts[i].offset;610 offsets[j] = names[i].offset;
599 }611 }
600 }612 }
601 613
602 names = is_vport ? vport_extended_err_cnts : extended_err_cnts;614 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);
603 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {617 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++) {
605 descs[j].name = names[i].name;619 descs[j].name = names[i].name;
606 offsets[j] = extended_err_cnts[i].offset;620 offsets[j] = names[i].offset;
607 }621 }
608 }622 }
609 623
610 names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts;624 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);
611 if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {627 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++) {
613 descs[j].name = names[i].name;629 descs[j].name = names[i].name;
614 offsets[j] = roce_accl_cnts[i].offset;630 offsets[j] = names[i].offset;
615 }631 }
616 }632 }
617 633
@@ -661,25 +677,37 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev, · 43 unmodified lines
661static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,677static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
662 struct mlx5_ib_counters *cnts, u32 port_num)678 struct mlx5_ib_counters *cnts, u32 port_num)
663{679{
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;
665 683
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;
667 687
688 size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
689 ARRAY_SIZE(out_of_seq_q_cnts);
668 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))690 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))
669 num_counters += ARRAY_SIZE(out_of_seq_q_cnts);691 num_counters += size;
670 692
693 size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
694 ARRAY_SIZE(retrans_q_cnts);
671 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))695 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
672 num_counters += ARRAY_SIZE(retrans_q_cnts);696 num_counters += size;
673 697
698 size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
699 ARRAY_SIZE(extended_err_cnts);
674 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))700 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
675 num_counters += ARRAY_SIZE(extended_err_cnts);701 num_counters += size;
676 702
703 size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
704 ARRAY_SIZE(roce_accl_cnts);
677 if (MLX5_CAP_GEN(dev->mdev, roce_accl))705 if (MLX5_CAP_GEN(dev->mdev, roce_accl))
678 num_counters += ARRAY_SIZE(roce_accl_cnts);706 num_counters += size;
679 707
680 cnts->num_q_counters = num_counters;708 cnts->num_q_counters = num_counters;
681 709
682 if (is_mdev_switchdev_mode(dev->mdev) && port_num != MLX5_VPORT_PF)710 if (is_vport)
683 goto skip_non_qcounters;711 goto skip_non_qcounters;
684 712
685 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {713 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
@@ -725,11 +753,11 @@ err: · 39 unmodified lines
725static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)753static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
726{754{
727 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};755 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
728 int num_cnt_ports;756 int num_cnt_ports = dev->num_ports;
729 int i, j;757 int i, j;
730 758
731 num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||759 if (is_mdev_switchdev_mode(dev->mdev))
732 vport_qcounters_supported(dev)) ? dev->num_ports : 1;760 num_cnt_ports = min(2, num_cnt_ports);
733 761
734 MLX5_SET(dealloc_q_counter_in, in, opcode,762 MLX5_SET(dealloc_q_counter_in, in, opcode,
735 MLX5_CMD_OP_DEALLOC_Q_COUNTER);763 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
@@ -761,15 +789,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev) · 25 unmodified lines
761{789{
762 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};790 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
763 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};791 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
764 int num_cnt_ports;792 int num_cnt_ports = dev->num_ports;
765 int err = 0;793 int err = 0;
766 int i;794 int i;
767 bool is_shared;795 bool is_shared;
768 796
769 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);797 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
770 is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;798 is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
771 num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||799
772 vport_qcounters_supported(dev)) ? dev->num_ports : 1;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);
773 808
774 for (i = 0; i < num_cnt_ports; i++) {809 for (i = 0; i < num_cnt_ports; i++) {
775 err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);810 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
695 struct mlx5_flow_table_attr ft_attr = {};695 struct mlx5_flow_table_attr ft_attr = {};
696 struct mlx5_flow_table *ft;696 struct mlx5_flow_table *ft;
697 697
698 if (mlx5_ib_shared_ft_allowed(&dev->ib_dev))
699 ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
700 ft_attr.prio = priority;698 ft_attr.prio = priority;
701 ft_attr.max_fte = num_entries;699 ft_attr.max_fte = num_entries;
702 ft_attr.flags = flags;700 ft_attr.flags = flags;
@@ -2025,6 +2023,237 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject, · 1322 unmodified lines
2025 return 0;2023 return 0;
2026}2024}
2027 2025
2026static 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
2056static 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
2064static int
2065steering_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
2090out:
2091 kvfree(flow_group_in);
2092
2093 return err;
2094}
2095
2096static void
2097steering_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
2105static int
2106steering_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
2127out:
2128 kvfree(flow_group_in);
2129
2130 return err;
2131}
2132
2133static void
2134steering_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
2142static int
2143steering_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
2164static 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
2172static int
2173steering_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
2199static void
2200steering_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
2208static 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
2236destroy_rule_drop:
2237 steering_anchor_destroy_rule_drop(ft_prio);
2238destroy_fg_goto_table:
2239 steering_anchor_destroy_fg_goto_table(ft_prio);
2240destroy_fg_drop:
2241 steering_anchor_destroy_fg_drop(ft_prio);
2242destroy_ft:
2243 steering_anchor_destroy_ft(ft_prio);
2244
2245 return err;
2246}
2247
2248static 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
2028static int steering_anchor_cleanup(struct ib_uobject *uobject,2257static int steering_anchor_cleanup(struct ib_uobject *uobject,
2029 enum rdma_remove_reason why,2258 enum rdma_remove_reason why,
2030 struct uverbs_attr_bundle *attrs)2259 struct uverbs_attr_bundle *attrs)
@@ -2035,6 +2264,9 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject, · 4 unmodified lines
2035 return -EBUSY;2264 return -EBUSY;
2036 2265
2037 mutex_lock(&obj->dev->flow_db->lock);2266 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
2038 put_flow_table(obj->dev, obj->ft_prio, true);2270 put_flow_table(obj->dev, obj->ft_prio, true);
2039 mutex_unlock(&obj->dev->flow_db->lock);2271 mutex_unlock(&obj->dev->flow_db->lock);
2040 2272
@@ -2042,6 +2274,24 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject, · 1 unmodified line
2042 return 0;2274 return 0;
2043}2275}
2044 2276
2277static 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
2284void 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
2045static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,2295static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
2046 struct mlx5_ib_flow_matcher *obj)2296 struct mlx5_ib_flow_matcher *obj)
2047{2297{
@@ -2182,21 +2432,31 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)( · 134 unmodified lines
2182 return -ENOMEM;2432 return -ENOMEM;
2183 2433
2184 mutex_lock(&dev->flow_db->lock);2434 mutex_lock(&dev->flow_db->lock);
2435
2185 ft_prio = _get_flow_table(dev, priority, ns_type, 0);2436 ft_prio = _get_flow_table(dev, priority, ns_type, 0);
2186 if (IS_ERR(ft_prio)) {2437 if (IS_ERR(ft_prio)) {
2187 mutex_unlock(&dev->flow_db->lock);
2188 err = PTR_ERR(ft_prio);2438 err = PTR_ERR(ft_prio);
2189 goto free_obj;2439 goto free_obj;
2190 }2440 }
2191 2441
2192 ft_prio->refcount++;2442 ft_prio->refcount++;
2193 ft_id = mlx5_flow_table_id(ft_prio->flow_table);2443
2194 mutex_unlock(&dev->flow_db->lock);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);
2195 2453
2196 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,2454 err = uverbs_copy_to(attrs, MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,
2197 &ft_id, sizeof(ft_id));2455 &ft_id, sizeof(ft_id));
2198 if (err)2456 if (err)
2199 goto put_flow_table;2457 goto destroy_res;
2458
2459 mutex_unlock(&dev->flow_db->lock);
2200 2460
2201 uobj->object = obj;2461 uobj->object = obj;
2202 obj->dev = dev;2462 obj->dev = dev;
@@ -2205,8 +2465,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)( · 2 unmodified lines
2205 2465
2206 return 0;2466 return 0;
2207 2467
2468destroy_res:
2469 --ft_prio->anchor.rule_goto_table_ref;
2470 mlx5_steering_anchor_destroy_res(ft_prio);
2208put_flow_table:2471put_flow_table:
2209 mutex_lock(&dev->flow_db->lock);
2210 put_flow_table(dev, ft_prio, true);2472 put_flow_table(dev, ft_prio, true);
2211 mutex_unlock(&dev->flow_db->lock);2473 mutex_unlock(&dev->flow_db->lock);
2212free_obj:2474free_obj:
drivers/infiniband/hw/mlx5/fs.h+16−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
10 10
11#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)11#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
12int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);12int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);
13void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev);
13#else14#else
14static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)15static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
15{16{
@@ -21,9 +22,24 @@ static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev) · 5 unmodified lines
21 mutex_init(&dev->flow_db->lock);22 mutex_init(&dev->flow_db->lock);
22 return 0;23 return 0;
23}24}
25
26inline void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev) {}
24#endif27#endif
28
25static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)29static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)
26{30{
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);
27 kfree(dev->flow_db);43 kfree(dev->flow_db);
28}44}
29#endif /* _MLX5_IB_FS_H */45#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
4275 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,4275 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
4276 mlx5_ib_stage_post_ib_reg_umr_init,4276 mlx5_ib_stage_post_ib_reg_umr_init,
4277 NULL),4277 NULL),
4278 STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
4279 mlx5_ib_stage_delay_drop_init,
4280 mlx5_ib_stage_delay_drop_cleanup),
4278 STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,4281 STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
4279 mlx5_ib_restrack_init,4282 mlx5_ib_restrack_init,
4280 NULL),4283 NULL),
drivers/infiniband/hw/mlx5/mlx5_ib.h+14−0
@@ -237,8 +237,19 @@ enum { · 236 unmodified lines
237#define MLX5_IB_NUM_SNIFFER_FTS 2237#define MLX5_IB_NUM_SNIFFER_FTS 2
238#define MLX5_IB_NUM_EGRESS_FTS 1238#define MLX5_IB_NUM_EGRESS_FTS 1
239#define MLX5_IB_NUM_FDB_FTS MLX5_BY_PASS_NUM_REGULAR_PRIOS239#define MLX5_IB_NUM_FDB_FTS MLX5_BY_PASS_NUM_REGULAR_PRIOS
240
241struct 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
240struct mlx5_ib_flow_prio {250struct mlx5_ib_flow_prio {
241 struct mlx5_flow_table *flow_table;251 struct mlx5_flow_table *flow_table;
252 struct mlx5_ib_anchor anchor;
242 unsigned int refcount;253 unsigned int refcount;
243};254};
244 255
@@ -1587,6 +1598,9 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev) · 1342 unmodified lines
1587 MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))1598 MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))
1588 return 0;1599 return 0;
1589 1600
1601 if (mlx5_lag_is_lacp_owner(dev->mdev) && !dev->lag_active)
1602 return 0;
1603
1590 return dev->lag_active ||1604 return dev->lag_active ||
1591 (MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&1605 (MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
1592 MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));1606 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
1237 1237
1238 MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);1238 MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);
1239 MLX5_SET(tisc, tisc, transport_domain, tdn);1239 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);
1240 if (qp->flags & IB_QP_CREATE_SOURCE_QPN)1243 if (qp->flags & IB_QP_CREATE_SOURCE_QPN)
1241 MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);1244 MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
1242 1245
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
113 113
114 queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);114 queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);
115 115
116 spin_unlock_irqrestore(&cq->cq_lock, flags);
117
118 if ((cq->notify == IB_CQ_NEXT_COMP) ||116 if ((cq->notify == IB_CQ_NEXT_COMP) ||
119 (cq->notify == IB_CQ_SOLICITED && solicited)) {117 (cq->notify == IB_CQ_SOLICITED && solicited)) {
120 cq->notify = 0;118 cq->notify = 0;
@@ -122,6 +120,8 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) · 1 unmodified line
122 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);120 cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
123 }121 }
124 122
123 spin_unlock_irqrestore(&cq->cq_lock, flags);
124
125 return 0;125 return 0;
126}126}
127 127
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
159 pkt->mask = RXE_GRH_MASK;159 pkt->mask = RXE_GRH_MASK;
160 pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);160 pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);
161 161
162 /* remove udp header */
163 skb_pull(skb, sizeof(struct udphdr));
164
162 rxe_rcv(skb);165 rxe_rcv(skb);
163 166
164 return 0;167 return 0;
@@ -401,6 +404,9 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 236 unmodified lines
401 return -EIO;404 return -EIO;
402 }405 }
403 406
407 /* remove udp header */
408 skb_pull(skb, sizeof(struct udphdr));
409
404 rxe_rcv(skb);410 rxe_rcv(skb);
405 411
406 return 0;412 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
176 spin_lock_init(&qp->rq.producer_lock);176 spin_lock_init(&qp->rq.producer_lock);
177 spin_lock_init(&qp->rq.consumer_lock);177 spin_lock_init(&qp->rq.consumer_lock);
178 178
179 skb_queue_head_init(&qp->req_pkts);
180 skb_queue_head_init(&qp->resp_pkts);
181
179 atomic_set(&qp->ssn, 0);182 atomic_set(&qp->ssn, 0);
180 atomic_set(&qp->skb_out, 0);183 atomic_set(&qp->skb_out, 0);
181}184}
@@ -234,8 +237,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, · 52 unmodified lines
234 qp->req.opcode = -1;237 qp->req.opcode = -1;
235 qp->comp.opcode = -1;238 qp->comp.opcode = -1;
236 239
237 skb_queue_head_init(&qp->req_pkts);
238
239 rxe_init_task(&qp->req.task, qp, rxe_requester);240 rxe_init_task(&qp->req.task, qp, rxe_requester);
240 rxe_init_task(&qp->comp.task, qp, rxe_completer);241 rxe_init_task(&qp->comp.task, qp, rxe_completer);
241 242
@@ -279,8 +280,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, · 37 unmodified lines
279 }280 }
280 }281 }
281 282
282 skb_queue_head_init(&qp->resp_pkts);
283
284 rxe_init_task(&qp->resp.task, qp, rxe_responder);283 rxe_init_task(&qp->resp.task, qp, rxe_responder);
285 284
286 qp->resp.opcode = OPCODE_NONE;285 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
489 if (mw->access & IB_ZERO_BASED)489 if (mw->access & IB_ZERO_BASED)
490 qp->resp.offset = mw->addr;490 qp->resp.offset = mw->addr;
491 491
492 rxe_put(mw);
493 rxe_get(mr);492 rxe_get(mr);
493 rxe_put(mw);
494 mw = NULL;
494 } else {495 } else {
495 mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);496 mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
496 if (!mr) {497 if (!mr) {
drivers/infiniband/ulp/isert/ib_isert.c+12−4
@@ -657,9 +657,13 @@ static int · 656 unmodified lines
657isert_connect_error(struct rdma_cm_id *cma_id)657isert_connect_error(struct rdma_cm_id *cma_id)
658{658{
659 struct isert_conn *isert_conn = cma_id->qp->qp_context;659 struct isert_conn *isert_conn = cma_id->qp->qp_context;
660 struct isert_np *isert_np = cma_id->context;
660 661
661 ib_drain_qp(isert_conn->qp);662 ib_drain_qp(isert_conn->qp);
663
664 mutex_lock(&isert_np->mutex);
662 list_del_init(&isert_conn->node);665 list_del_init(&isert_conn->node);
666 mutex_unlock(&isert_np->mutex);
663 isert_conn->cm_id = NULL;667 isert_conn->cm_id = NULL;
664 isert_put_conn(isert_conn);668 isert_put_conn(isert_conn);
665 669
@@ -2431,6 +2435,7 @@ isert_free_np(struct iscsi_np *np) · 1765 unmodified lines
2431{2435{
2432 struct isert_np *isert_np = np->np_context;2436 struct isert_np *isert_np = np->np_context;
2433 struct isert_conn *isert_conn, *n;2437 struct isert_conn *isert_conn, *n;
2438 LIST_HEAD(drop_conn_list);
2434 2439
2435 if (isert_np->cm_id)2440 if (isert_np->cm_id)
2436 rdma_destroy_id(isert_np->cm_id);2441 rdma_destroy_id(isert_np->cm_id);
@@ -2450,7 +2455,7 @@ isert_free_np(struct iscsi_np *np) · 13 unmodified lines
2450 node) {2455 node) {
2451 isert_info("cleaning isert_conn %p state (%d)\n",2456 isert_info("cleaning isert_conn %p state (%d)\n",
2452 isert_conn, isert_conn->state);2457 isert_conn, isert_conn->state);
2453 isert_connect_release(isert_conn);2458 list_move_tail(&isert_conn->node, &drop_conn_list);
2454 }2459 }
2455 }2460 }
2456 2461
@@ -2461,11 +2466,16 @@ isert_free_np(struct iscsi_np *np) · 4 unmodified lines
2461 node) {2466 node) {
2462 isert_info("cleaning isert_conn %p state (%d)\n",2467 isert_info("cleaning isert_conn %p state (%d)\n",
2463 isert_conn, isert_conn->state);2468 isert_conn, isert_conn->state);
2464 isert_connect_release(isert_conn);2469 list_move_tail(&isert_conn->node, &drop_conn_list);
2465 }2470 }
2466 }2471 }
2467 mutex_unlock(&isert_np->mutex);2472 mutex_unlock(&isert_np->mutex);
2468 2473
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
2469 np->np_context = NULL;2479 np->np_context = NULL;
2470 kfree(isert_np);2480 kfree(isert_np);
2471}2481}
@@ -2560,8 +2570,6 @@ static void isert_wait_conn(struct iscsit_conn *conn) · 88 unmodified lines
2560 isert_put_unsol_pending_cmds(conn);2570 isert_put_unsol_pending_cmds(conn);
2561 isert_wait4cmds(conn);2571 isert_wait4cmds(conn);
2562 isert_wait4logout(isert_conn);2572 isert_wait4logout(isert_conn);
2563
2564 queue_work(isert_release_wq, &isert_conn->release_work);
2565}2573}
2566 2574
2567static void isert_free_conn(struct iscsit_conn *conn)2575static 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
2040 return 0;2040 return 0;
2041}2041}
2042 2042
2043/* The caller should do the cleanup in case of error */
2043static int create_cm(struct rtrs_clt_con *con)2044static int create_cm(struct rtrs_clt_con *con)
2044{2045{
2045 struct rtrs_path *s = con->c.path;2046 struct rtrs_path *s = con->c.path;
@@ -2062,14 +2063,14 @@ static int create_cm(struct rtrs_clt_con *con) · 16 unmodified lines
2062 err = rdma_set_reuseaddr(cm_id, 1);2063 err = rdma_set_reuseaddr(cm_id, 1);
2063 if (err != 0) {2064 if (err != 0) {
2064 rtrs_err(s, "Set address reuse failed, err: %d\n", err);2065 rtrs_err(s, "Set address reuse failed, err: %d\n", err);
2065 goto destroy_cm;2066 return err;
2066 }2067 }
2067 err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,2068 err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,
2068 (struct sockaddr *)&clt_path->s.dst_addr,2069 (struct sockaddr *)&clt_path->s.dst_addr,
2069 RTRS_CONNECT_TIMEOUT_MS);2070 RTRS_CONNECT_TIMEOUT_MS);
2070 if (err) {2071 if (err) {
2071 rtrs_err(s, "Failed to resolve address, err: %d\n", err);2072 rtrs_err(s, "Failed to resolve address, err: %d\n", err);
2072 goto destroy_cm;2073 return err;
2073 }2074 }
2074 /*2075 /*
2075 * Combine connection status and session events. This is needed2076 * 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
2084 if (err == 0)2085 if (err == 0)
2085 err = -ETIMEDOUT;2086 err = -ETIMEDOUT;
2086 /* Timedout or interrupted */2087 /* Timedout or interrupted */
2087 goto errr;2088 return err;
2088 }
2089 if (con->cm_err < 0) {
2090 err = con->cm_err;
2091 goto errr;
2092 }2089 }
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)
2094 /* Device removal */2093 /* Device removal */
2095 err = -ECONNABORTED;2094 return -ECONNABORTED;
2096 goto errr;
2097 }
2098 2095
2099 return 0;2096 return 0;
2100
2101errr:
2102 stop_cm(con);
2103 mutex_lock(&con->con_mutex);
2104 destroy_con_cq_qp(con);
2105 mutex_unlock(&con->con_mutex);
2106destroy_cm:
2107 destroy_cm(con);
2108
2109 return err;
2110}2097}
2111 2098
2112static void rtrs_clt_path_up(struct rtrs_clt_path *clt_path)2099static 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
2334static int init_conns(struct rtrs_clt_path *clt_path)2321static int init_conns(struct rtrs_clt_path *clt_path)
2335{2322{
2336 unsigned int cid;2323 unsigned int cid;
2337 int err;2324 int err, i;
2338 2325
2339 /*2326 /*
2340 * On every new session connections increase reconnect counter2327 * 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
2350 goto destroy;2337 goto destroy;
2351 2338
2352 err = create_cm(to_clt_con(clt_path->s.con[cid]));2339 err = create_cm(to_clt_con(clt_path->s.con[cid]));
2353 if (err) {2340 if (err)
2354 destroy_con(to_clt_con(clt_path->s.con[cid]));
2355 goto destroy;2341 goto destroy;
2356 }
2357 }2342 }
2358 err = alloc_path_reqs(clt_path);2343 err = alloc_path_reqs(clt_path);
2359 if (err)2344 if (err)
@@ -2364,15 +2349,21 @@ static int init_conns(struct rtrs_clt_path *clt_path) · 4 unmodified lines
2364 return 0;2349 return 0;
2365 2350
2366destroy:2351destroy:
2367 while (cid--) {2352 /* Make sure we do the cleanup in the order they are created */
2368 struct rtrs_clt_con *con = to_clt_con(clt_path->s.con[cid]);2353 for (i = 0; i <= cid; i++) {
2354 struct rtrs_clt_con *con;
2369 2355
2370 stop_cm(con);2356 if (!clt_path->s.con[i])
2357 break;
2371 2358
2372 mutex_lock(&con->con_mutex);2359 con = to_clt_con(clt_path->s.con[i]);
2373 destroy_con_cq_qp(con);2360 if (con->c.cm_id) {
2374 mutex_unlock(&con->con_mutex);2361 stop_cm(con);
2375 destroy_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 }
2376 destroy_con(con);2367 destroy_con(con);
2377 }2368 }
2378 /*2369 /*
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
37 goto err;37 goto err;
38 38
39 iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);39 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);
41 goto err;42 goto err;
43 }
42 44
43 iu->cqe.done = done;45 iu->cqe.done = done;
44 iu->size = size;46 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
276 return pci_num_vf(dev->pdev) ? true : false;276 return pci_num_vf(dev->pdev) ? true : false;
277}277}
278 278
279static 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
291int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);279int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);
292static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)280static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
293{281{
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
1238 return dev->priv.sriov.max_vfs;1238 return dev->priv.sriov.max_vfs;
1239}1239}
1240 1240
1241static 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
1241static inline int mlx5_get_gid_table_len(u16 param)1253static inline int mlx5_get_gid_table_len(u16 param)
1242{1254{
1243 if (param > 4) {1255 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
194 return 0;194 return 0;
195}195}
196 196
197static 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
220static inline int rdma_link_local_addr(struct in6_addr *addr)197static inline int rdma_link_local_addr(struct in6_addr *addr)
221{198{
222 if (addr->s6_addr32[0] == htonl(0xfe800000) &&199 if (addr->s6_addr32[0] == htonl(0xfe800000) &&