Skip to content

Commit ac9c34d

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: - Fix a mlx5 malfunction if the UMR QP gets an error - Return the correct port number to userspace for a mlx5 DCT - Don't cause a UMR QP error if DMABUF teardown races with invalidation - Fix a WARN splat when unregisering so mlx5 device memory MR types - Use the correct alignment for the mana doorbell so that two processes do not share the same physical page on non-4k page systems - MAINTAINERS updates for MANA - Retry failed HNS FW commands because some can take a long time - Cast void * handle to the correct type in bnxt to fix corruption - Avoid a NULL pointer crash in bnxt_re - Fix skipped ib_device_unregsiter() for bnxt_re due to some earlier rework - Correctly detect if the bnxt supports extended statistics - Fix refcount leak in mlx5 odp introduced by a previous fix - Map the FW result for the port rate to the userspace values properly in mlx5, returns correct values for newer 800G ports - Don't wrongly destroy counters objects that were not automatically created during mlx5 bind qp - Set page size/shift members of kernel owned SRQs to fix a crash in nvme target * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/bnxt_re: Fix the page details for the srq created by kernel consumers RDMA/mlx5: Fix bind QP error cleanup flow RDMA/mlx5: Fix AH static rate parsing RDMA/mlx5: Fix implicit ODP hang on parent deregistration RDMA/bnxt_re: Fix the statistics for Gen P7 VF RDMA/bnxt_re: Fix issue in the unload path RDMA/bnxt_re: Add sanity checks on rdev validity RDMA/bnxt_re: Fix an issue in bnxt_re_async_notifier RDMA/hns: Fix mbox timing out by adding retry mechanism MAINTAINERS: update maintainer for Microsoft MANA RDMA driver RDMA/mana_ib: Allocate PAGE aligned doorbell index RDMA/mlx5: Fix a WARN during dereg_mr for DM type RDMA/mlx5: Fix a race for DMABUF MR which can lead to CQE with error IB/mlx5: Set and get correct qp_num for a DCT QP RDMA/mlx5: Fix the recovery flow of the UMR QP
2 parents 9f5270d + b665353 commit ac9c34d

16 files changed

+161
-68
lines changed

MAINTAINERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -15680,7 +15680,7 @@ F: include/uapi/linux/cciss*.h
1568015680

1568115681
MICROSOFT MANA RDMA DRIVER
1568215682
M: Long Li <[email protected]>
15683-
M: Ajay Sharma <sharmaajay@microsoft.com>
15683+
M: Konstantin Taranov <kotaranov@microsoft.com>
1568415684
1568515685
S: Supported
1568615686
F: drivers/infiniband/hw/mana/

drivers/infiniband/hw/bnxt_re/bnxt_re.h

-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ struct bnxt_re_dev {
187187
#define BNXT_RE_FLAG_ISSUE_ROCE_STATS 29
188188
struct net_device *netdev;
189189
struct auxiliary_device *adev;
190-
struct notifier_block nb;
191190
unsigned int version, major, minor;
192191
struct bnxt_qplib_chip_ctx *chip_ctx;
193192
struct bnxt_en_dev *en_dev;

drivers/infiniband/hw/bnxt_re/hw_counters.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
348348
goto done;
349349
}
350350
bnxt_re_copy_err_stats(rdev, stats, err_s);
351-
if (_is_ext_stats_supported(rdev->dev_attr->dev_cap_flags) &&
352-
!rdev->is_virtfn) {
351+
if (bnxt_ext_stats_supported(rdev->chip_ctx, rdev->dev_attr->dev_cap_flags,
352+
rdev->is_virtfn)) {
353353
rc = bnxt_re_get_ext_stat(rdev, stats);
354354
if (rc) {
355355
clear_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS,

drivers/infiniband/hw/bnxt_re/ib_verbs.c

+2
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,8 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
18701870
srq->qplib_srq.threshold = srq_init_attr->attr.srq_limit;
18711871
srq->srq_limit = srq_init_attr->attr.srq_limit;
18721872
srq->qplib_srq.eventq_hw_ring_id = rdev->nqr->nq[0].ring_id;
1873+
srq->qplib_srq.sg_info.pgsize = PAGE_SIZE;
1874+
srq->qplib_srq.sg_info.pgshft = PAGE_SHIFT;
18731875
nq = &rdev->nqr->nq[0];
18741876

18751877
if (udata) {

drivers/infiniband/hw/bnxt_re/main.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,16 @@ static void bnxt_re_dcb_wq_task(struct work_struct *work)
396396

397397
static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *cmpl)
398398
{
399-
struct bnxt_re_dev *rdev = (struct bnxt_re_dev *)handle;
399+
struct bnxt_re_en_dev_info *en_info = auxiliary_get_drvdata(handle);
400400
struct bnxt_re_dcb_work *dcb_work;
401+
struct bnxt_re_dev *rdev;
401402
u32 data1, data2;
402403
u16 event_id;
403404

405+
rdev = en_info->rdev;
406+
if (!rdev)
407+
return;
408+
404409
event_id = le16_to_cpu(cmpl->event_id);
405410
data1 = le32_to_cpu(cmpl->event_data1);
406411
data2 = le32_to_cpu(cmpl->event_data2);
@@ -433,6 +438,8 @@ static void bnxt_re_stop_irq(void *handle, bool reset)
433438
int indx;
434439

435440
rdev = en_info->rdev;
441+
if (!rdev)
442+
return;
436443
rcfw = &rdev->rcfw;
437444

438445
if (reset) {
@@ -461,6 +468,8 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent)
461468
int indx, rc;
462469

463470
rdev = en_info->rdev;
471+
if (!rdev)
472+
return;
464473
msix_ent = rdev->nqr->msix_entries;
465474
rcfw = &rdev->rcfw;
466475
if (!ent) {
@@ -1350,7 +1359,6 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct auxiliary_device *adev,
13501359
return NULL;
13511360
}
13521361
/* Default values */
1353-
rdev->nb.notifier_call = NULL;
13541362
rdev->netdev = en_dev->net;
13551363
rdev->en_dev = en_dev;
13561364
rdev->adev = adev;
@@ -2345,15 +2353,6 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
23452353
static void bnxt_re_remove_device(struct bnxt_re_dev *rdev, u8 op_type,
23462354
struct auxiliary_device *aux_dev)
23472355
{
2348-
if (rdev->nb.notifier_call) {
2349-
unregister_netdevice_notifier(&rdev->nb);
2350-
rdev->nb.notifier_call = NULL;
2351-
} else {
2352-
/* If notifier is null, we should have already done a
2353-
* clean up before coming here.
2354-
*/
2355-
return;
2356-
}
23572356
bnxt_re_setup_cc(rdev, false);
23582357
ib_unregister_device(&rdev->ibdev);
23592358
bnxt_re_dev_uninit(rdev, op_type);
@@ -2433,6 +2432,7 @@ static int bnxt_re_suspend(struct auxiliary_device *adev, pm_message_t state)
24332432
ibdev_info(&rdev->ibdev, "%s: L2 driver notified to stop en_state 0x%lx",
24342433
__func__, en_dev->en_state);
24352434
bnxt_re_remove_device(rdev, BNXT_RE_PRE_RECOVERY_REMOVE, adev);
2435+
bnxt_re_update_en_info_rdev(NULL, en_info, adev);
24362436
mutex_unlock(&bnxt_re_mutex);
24372437

24382438
return 0;

drivers/infiniband/hw/bnxt_re/qplib_res.h

+8
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,14 @@ static inline bool _is_ext_stats_supported(u16 dev_cap_flags)
547547
CREQ_QUERY_FUNC_RESP_SB_EXT_STATS;
548548
}
549549

550+
static inline int bnxt_ext_stats_supported(struct bnxt_qplib_chip_ctx *ctx,
551+
u16 flags, bool virtfn)
552+
{
553+
/* ext stats supported if cap flag is set AND is a PF OR a Thor2 VF */
554+
return (_is_ext_stats_supported(flags) &&
555+
((virtfn && bnxt_qplib_is_chip_gen_p7(ctx)) || (!virtfn)));
556+
}
557+
550558
static inline bool _is_hw_retx_supported(u16 dev_cap_flags)
551559
{
552560
return dev_cap_flags &

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

+48-16
Original file line numberDiff line numberDiff line change
@@ -1286,10 +1286,8 @@ static u32 hns_roce_cmdq_tx_timeout(u16 opcode, u32 tx_timeout)
12861286
return tx_timeout;
12871287
}
12881288

1289-
static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
1289+
static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u32 tx_timeout)
12901290
{
1291-
struct hns_roce_v2_priv *priv = hr_dev->priv;
1292-
u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
12931291
u32 timeout = 0;
12941292

12951293
do {
@@ -1299,8 +1297,9 @@ static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
12991297
} while (++timeout < tx_timeout);
13001298
}
13011299

1302-
static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
1303-
struct hns_roce_cmq_desc *desc, int num)
1300+
static int __hns_roce_cmq_send_one(struct hns_roce_dev *hr_dev,
1301+
struct hns_roce_cmq_desc *desc,
1302+
int num, u32 tx_timeout)
13041303
{
13051304
struct hns_roce_v2_priv *priv = hr_dev->priv;
13061305
struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
@@ -1309,8 +1308,6 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
13091308
int ret;
13101309
int i;
13111310

1312-
spin_lock_bh(&csq->lock);
1313-
13141311
tail = csq->head;
13151312

13161313
for (i = 0; i < num; i++) {
@@ -1324,22 +1321,17 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
13241321

13251322
atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_CNT]);
13261323

1327-
hns_roce_wait_csq_done(hr_dev, le16_to_cpu(desc->opcode));
1324+
hns_roce_wait_csq_done(hr_dev, tx_timeout);
13281325
if (hns_roce_cmq_csq_done(hr_dev)) {
13291326
ret = 0;
13301327
for (i = 0; i < num; i++) {
13311328
/* check the result of hardware write back */
1332-
desc[i] = csq->desc[tail++];
1329+
desc_ret = le16_to_cpu(csq->desc[tail++].retval);
13331330
if (tail == csq->desc_num)
13341331
tail = 0;
1335-
1336-
desc_ret = le16_to_cpu(desc[i].retval);
13371332
if (likely(desc_ret == CMD_EXEC_SUCCESS))
13381333
continue;
13391334

1340-
dev_err_ratelimited(hr_dev->dev,
1341-
"Cmdq IO error, opcode = 0x%x, return = 0x%x.\n",
1342-
desc->opcode, desc_ret);
13431335
ret = hns_roce_cmd_err_convert_errno(desc_ret);
13441336
}
13451337
} else {
@@ -1354,14 +1346,54 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
13541346
ret = -EAGAIN;
13551347
}
13561348

1357-
spin_unlock_bh(&csq->lock);
1358-
13591349
if (ret)
13601350
atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_ERR_CNT]);
13611351

13621352
return ret;
13631353
}
13641354

1355+
static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
1356+
struct hns_roce_cmq_desc *desc, int num)
1357+
{
1358+
struct hns_roce_v2_priv *priv = hr_dev->priv;
1359+
struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
1360+
u16 opcode = le16_to_cpu(desc->opcode);
1361+
u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
1362+
u8 try_cnt = HNS_ROCE_OPC_POST_MB_TRY_CNT;
1363+
u32 rsv_tail;
1364+
int ret;
1365+
int i;
1366+
1367+
while (try_cnt) {
1368+
try_cnt--;
1369+
1370+
spin_lock_bh(&csq->lock);
1371+
rsv_tail = csq->head;
1372+
ret = __hns_roce_cmq_send_one(hr_dev, desc, num, tx_timeout);
1373+
if (opcode == HNS_ROCE_OPC_POST_MB && ret == -ETIME &&
1374+
try_cnt) {
1375+
spin_unlock_bh(&csq->lock);
1376+
mdelay(HNS_ROCE_OPC_POST_MB_RETRY_GAP_MSEC);
1377+
continue;
1378+
}
1379+
1380+
for (i = 0; i < num; i++) {
1381+
desc[i] = csq->desc[rsv_tail++];
1382+
if (rsv_tail == csq->desc_num)
1383+
rsv_tail = 0;
1384+
}
1385+
spin_unlock_bh(&csq->lock);
1386+
break;
1387+
}
1388+
1389+
if (ret)
1390+
dev_err_ratelimited(hr_dev->dev,
1391+
"Cmdq IO error, opcode = 0x%x, return = %d.\n",
1392+
opcode, ret);
1393+
1394+
return ret;
1395+
}
1396+
13651397
static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
13661398
struct hns_roce_cmq_desc *desc, int num)
13671399
{

drivers/infiniband/hw/hns/hns_roce_hw_v2.h

+2
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ enum hns_roce_opcode_type {
230230
};
231231

232232
#define HNS_ROCE_OPC_POST_MB_TIMEOUT 35000
233+
#define HNS_ROCE_OPC_POST_MB_TRY_CNT 8
234+
#define HNS_ROCE_OPC_POST_MB_RETRY_GAP_MSEC 5
233235
struct hns_roce_cmdq_tx_timeout_map {
234236
u16 opcode;
235237
u32 tx_timeout;

drivers/infiniband/hw/mana/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static int mana_gd_allocate_doorbell_page(struct gdma_context *gc,
174174

175175
req.resource_type = GDMA_RESOURCE_DOORBELL_PAGE;
176176
req.num_resources = 1;
177-
req.alignment = 1;
177+
req.alignment = PAGE_SIZE / MANA_PAGE_SIZE;
178178

179179
/* Have GDMA start searching from 0 */
180180
req.allocated_resources = 0;

drivers/infiniband/hw/mlx5/ah.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
6767
ah->av.tclass = grh->traffic_class;
6868
}
6969

70-
ah->av.stat_rate_sl = (rdma_ah_get_static_rate(ah_attr) << 4);
70+
ah->av.stat_rate_sl =
71+
(mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah_attr)) << 4);
7172

7273
if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
7374
if (init_attr->xmit_slave)

drivers/infiniband/hw/mlx5/counters.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
546546
struct ib_qp *qp)
547547
{
548548
struct mlx5_ib_dev *dev = to_mdev(qp->device);
549+
bool new = false;
549550
int err;
550551

551552
if (!counter->id) {
@@ -560,6 +561,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
560561
return err;
561562
counter->id =
562563
MLX5_GET(alloc_q_counter_out, out, counter_set_id);
564+
new = true;
563565
}
564566

565567
err = mlx5_ib_qp_set_counter(qp, counter);
@@ -569,8 +571,10 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
569571
return 0;
570572

571573
fail_set_counter:
572-
mlx5_ib_counter_dealloc(counter);
573-
counter->id = 0;
574+
if (new) {
575+
mlx5_ib_counter_dealloc(counter);
576+
counter->id = 0;
577+
}
574578

575579
return err;
576580
}

drivers/infiniband/hw/mlx5/mr.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@ static void mlx5_ib_dmabuf_invalidate_cb(struct dma_buf_attachment *attach)
15501550

15511551
dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
15521552

1553-
if (!umem_dmabuf->sgt)
1553+
if (!umem_dmabuf->sgt || !mr)
15541554
return;
15551555

15561556
mlx5r_umr_update_mr_pas(mr, MLX5_IB_UPD_XLT_ZAP);
@@ -1935,7 +1935,8 @@ mlx5_alloc_priv_descs(struct ib_device *device,
19351935
static void
19361936
mlx5_free_priv_descs(struct mlx5_ib_mr *mr)
19371937
{
1938-
if (!mr->umem && !mr->data_direct && mr->descs) {
1938+
if (!mr->umem && !mr->data_direct &&
1939+
mr->ibmr.type != IB_MR_TYPE_DM && mr->descs) {
19391940
struct ib_device *device = mr->ibmr.device;
19401941
int size = mr->max_descs * mr->desc_size;
19411942
struct mlx5_ib_dev *dev = to_mdev(device);
@@ -2022,11 +2023,16 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
20222023
struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
20232024
struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
20242025
bool is_odp = is_odp_mr(mr);
2026+
bool is_odp_dma_buf = is_dmabuf_mr(mr) &&
2027+
!to_ib_umem_dmabuf(mr->umem)->pinned;
20252028
int ret = 0;
20262029

20272030
if (is_odp)
20282031
mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
20292032

2033+
if (is_odp_dma_buf)
2034+
dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv, NULL);
2035+
20302036
if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) {
20312037
ent = mr->mmkey.cache_ent;
20322038
/* upon storing to a clean temp entry - schedule its cleanup */
@@ -2054,6 +2060,12 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
20542060
mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
20552061
}
20562062

2063+
if (is_odp_dma_buf) {
2064+
if (!ret)
2065+
to_ib_umem_dmabuf(mr->umem)->private = NULL;
2066+
dma_resv_unlock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
2067+
}
2068+
20572069
return ret;
20582070
}
20592071

drivers/infiniband/hw/mlx5/odp.c

+1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ static void destroy_unused_implicit_child_mr(struct mlx5_ib_mr *mr)
242242
if (__xa_cmpxchg(&imr->implicit_children, idx, mr, NULL, GFP_KERNEL) !=
243243
mr) {
244244
xa_unlock(&imr->implicit_children);
245+
mlx5r_deref_odp_mkey(&imr->mmkey);
245246
return;
246247
}
247248

drivers/infiniband/hw/mlx5/qp.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -3447,11 +3447,11 @@ static int ib_to_mlx5_rate_map(u8 rate)
34473447
return 0;
34483448
}
34493449

3450-
static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
3450+
int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate)
34513451
{
34523452
u32 stat_rate_support;
34533453

3454-
if (rate == IB_RATE_PORT_CURRENT)
3454+
if (rate == IB_RATE_PORT_CURRENT || rate == IB_RATE_800_GBPS)
34553455
return 0;
34563456

34573457
if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_800_GBPS)
@@ -3596,7 +3596,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
35963596
sizeof(grh->dgid.raw));
35973597
}
35983598

3599-
err = ib_rate_to_mlx5(dev, rdma_ah_get_static_rate(ah));
3599+
err = mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah));
36003600
if (err < 0)
36013601
return err;
36023602
MLX5_SET(ads, path, stat_rate, err);
@@ -4579,6 +4579,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
45794579

45804580
set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1);
45814581
MLX5_SET(dctc, dctc, counter_set_id, set_id);
4582+
4583+
qp->port = attr->port_num;
45824584
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
45834585
struct mlx5_ib_modify_qp_resp resp = {};
45844586
u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {};
@@ -5074,7 +5076,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp,
50745076
}
50755077

50765078
if (qp_attr_mask & IB_QP_PORT)
5077-
qp_attr->port_num = MLX5_GET(dctc, dctc, port);
5079+
qp_attr->port_num = mqp->port;
50785080
if (qp_attr_mask & IB_QP_MIN_RNR_TIMER)
50795081
qp_attr->min_rnr_timer = MLX5_GET(dctc, dctc, min_rnr_nak);
50805082
if (qp_attr_mask & IB_QP_AV) {

drivers/infiniband/hw/mlx5/qp.h

+1
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);
5656
int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
5757
int mlx5_ib_qp_event_init(void);
5858
void mlx5_ib_qp_event_cleanup(void);
59+
int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate);
5960
#endif /* _MLX5_IB_QP_H */

0 commit comments

Comments
 (0)