Skip to content

Commit fcef104

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma into master
Pull rdma fixes from Jason Gunthorpe: "One merge window regression, some corruption bugs in HNS and a few more syzkaller fixes: - Two long standing syzkaller races - Fix incorrect HW configuration in HNS - Restore accidentally dropped locking in IB CM - Fix ODP prefetch bug added in the big rework several versions ago" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/mlx5: Prevent prefetch from racing with implicit destruction RDMA/cm: Protect access to remote_sidr_table RDMA/core: Fix race in rdma_alloc_commit_uobject() RDMA/hns: Fix wrong PBL offset when VA is not aligned to PAGE_SIZE RDMA/hns: Fix wrong assignment of lp_pktn_ini in QPC RDMA/mlx5: Use xa_lock_irq when access to SRQ table
2 parents a38a19e + a862192 commit fcef104

File tree

6 files changed

+49
-21
lines changed

6 files changed

+49
-21
lines changed

drivers/infiniband/core/cm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3676,10 +3676,12 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv,
36763676
return ret;
36773677
}
36783678
cm_id_priv->id.state = IB_CM_IDLE;
3679+
spin_lock_irq(&cm.lock);
36793680
if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
36803681
rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
36813682
RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
36823683
}
3684+
spin_unlock_irq(&cm.lock);
36833685
return 0;
36843686
}
36853687

drivers/infiniband/core/rdma_core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,6 @@ void rdma_alloc_commit_uobject(struct ib_uobject *uobj,
649649
{
650650
struct ib_uverbs_file *ufile = attrs->ufile;
651651

652-
/* alloc_commit consumes the uobj kref */
653-
uobj->uapi_object->type_class->alloc_commit(uobj);
654-
655652
/* kref is held so long as the uobj is on the uobj list. */
656653
uverbs_uobject_get(uobj);
657654
spin_lock_irq(&ufile->uobjects_lock);
@@ -661,6 +658,9 @@ void rdma_alloc_commit_uobject(struct ib_uobject *uobj,
661658
/* matches atomic_set(-1) in alloc_uobj */
662659
atomic_set(&uobj->usecnt, 0);
663660

661+
/* alloc_commit consumes the uobj kref */
662+
uobj->uapi_object->type_class->alloc_commit(uobj);
663+
664664
/* Matches the down_read in rdma_alloc_begin_uobject */
665665
up_read(&ufile->hw_destroy_rwsem);
666666
}

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3954,6 +3954,15 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev,
39543954
return 0;
39553955
}
39563956

3957+
static inline enum ib_mtu get_mtu(struct ib_qp *ibqp,
3958+
const struct ib_qp_attr *attr)
3959+
{
3960+
if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD)
3961+
return IB_MTU_4096;
3962+
3963+
return attr->path_mtu;
3964+
}
3965+
39573966
static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
39583967
const struct ib_qp_attr *attr, int attr_mask,
39593968
struct hns_roce_v2_qp_context *context,
@@ -3965,6 +3974,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
39653974
struct ib_device *ibdev = &hr_dev->ib_dev;
39663975
dma_addr_t trrl_ba;
39673976
dma_addr_t irrl_ba;
3977+
enum ib_mtu mtu;
39683978
u8 port_num;
39693979
u64 *mtts;
39703980
u8 *dmac;
@@ -4062,23 +4072,23 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
40624072
roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M,
40634073
V2_QPC_BYTE_52_DMAC_S, 0);
40644074

4065-
/* mtu*(2^LP_PKTN_INI) should not bigger than 1 message length 64kb */
4075+
mtu = get_mtu(ibqp, attr);
4076+
4077+
if (attr_mask & IB_QP_PATH_MTU) {
4078+
roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
4079+
V2_QPC_BYTE_24_MTU_S, mtu);
4080+
roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
4081+
V2_QPC_BYTE_24_MTU_S, 0);
4082+
}
4083+
4084+
#define MAX_LP_MSG_LEN 65536
4085+
/* MTU*(2^LP_PKTN_INI) shouldn't be bigger than 64kb */
40664086
roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M,
40674087
V2_QPC_BYTE_56_LP_PKTN_INI_S,
4068-
ilog2(hr_dev->caps.max_sq_inline / IB_MTU_4096));
4088+
ilog2(MAX_LP_MSG_LEN / ib_mtu_enum_to_int(mtu)));
40694089
roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M,
40704090
V2_QPC_BYTE_56_LP_PKTN_INI_S, 0);
40714091

4072-
if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD)
4073-
roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
4074-
V2_QPC_BYTE_24_MTU_S, IB_MTU_4096);
4075-
else if (attr_mask & IB_QP_PATH_MTU)
4076-
roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
4077-
V2_QPC_BYTE_24_MTU_S, attr->path_mtu);
4078-
4079-
roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M,
4080-
V2_QPC_BYTE_24_MTU_S, 0);
4081-
40824092
roce_set_bit(qpc_mask->byte_108_rx_reqepsn,
40834093
V2_QPC_BYTE_108_RX_REQ_PSN_ERR_S, 0);
40844094
roce_set_field(qpc_mask->byte_96_rx_reqmsn, V2_QPC_BYTE_96_RX_REQ_MSN_M,

drivers/infiniband/hw/hns/hns_roce_mr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int alloc_mr_pbl(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
120120

121121
mr->pbl_hop_num = is_fast ? 1 : hr_dev->caps.pbl_hop_num;
122122
buf_attr.page_shift = is_fast ? PAGE_SHIFT :
123-
hr_dev->caps.pbl_buf_pg_sz + HNS_HW_PAGE_SHIFT;
123+
hr_dev->caps.pbl_buf_pg_sz + PAGE_SHIFT;
124124
buf_attr.region[0].size = length;
125125
buf_attr.region[0].hopnum = mr->pbl_hop_num;
126126
buf_attr.region_count = 1;

drivers/infiniband/hw/mlx5/odp.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,23 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr)
601601
*/
602602
synchronize_srcu(&dev->odp_srcu);
603603

604+
/*
605+
* All work on the prefetch list must be completed, xa_erase() prevented
606+
* new work from being created.
607+
*/
608+
wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work));
609+
610+
/*
611+
* At this point it is forbidden for any other thread to enter
612+
* pagefault_mr() on this imr. It is already forbidden to call
613+
* pagefault_mr() on an implicit child. Due to this additions to
614+
* implicit_children are prevented.
615+
*/
616+
617+
/*
618+
* Block destroy_unused_implicit_child_mr() from incrementing
619+
* num_deferred_work.
620+
*/
604621
xa_lock(&imr->implicit_children);
605622
xa_for_each (&imr->implicit_children, idx, mtt) {
606623
__xa_erase(&imr->implicit_children, idx);
@@ -609,9 +626,8 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr)
609626
xa_unlock(&imr->implicit_children);
610627

611628
/*
612-
* num_deferred_work can only be incremented inside the odp_srcu, or
613-
* under xa_lock while the child is in the xarray. Thus at this point
614-
* it is only decreasing, and all work holding it is now on the wq.
629+
* Wait for any concurrent destroy_unused_implicit_child_mr() to
630+
* complete.
615631
*/
616632
wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work));
617633

drivers/infiniband/hw/mlx5/srq_cmd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ struct mlx5_core_srq *mlx5_cmd_get_srq(struct mlx5_ib_dev *dev, u32 srqn)
8383
struct mlx5_srq_table *table = &dev->srq_table;
8484
struct mlx5_core_srq *srq;
8585

86-
xa_lock(&table->array);
86+
xa_lock_irq(&table->array);
8787
srq = xa_load(&table->array, srqn);
8888
if (srq)
8989
refcount_inc(&srq->common.refcount);
90-
xa_unlock(&table->array);
90+
xa_unlock_irq(&table->array);
9191

9292
return srq;
9393
}

0 commit comments

Comments
 (0)