Skip to content

Commit 2f64e70

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Doug Ledford: - Various driver bug fixes in mlx5, mlx4, bnxt_re and qedr, ranging from bugs under load to bad error case handling - There in one largish patch fixing the locking in bnxt_re to avoid a machine hard lock situation - A few core bugs on error paths - A patch to reduce stack usage in the new CQ API - One mlx5 regression introduced in this merge window - There were new syzkaller scripts written for the RDMA subsystem and we are fixing issues found by the bot - One of the commits (aa0de36 “RDMA/mlx5: Fix integer overflow while resizing CQ”) is missing part of the commit log message and one of the SOB lines. The original patch was from Leon Romanovsky, and a cut-n-paste separator in the commit message confused patchworks which then put the end of message separator in the wrong place in the downloaded patch, and I didn’t notice in time. The patch made it into the official branch, and the only way to fix it in-place was to rebase. Given the pain that a rebase causes, and the fact that the patch has relevant tags for stable and syzkaller, a revert of the munged patch and a reapplication of the original patch with the log message intact was done. * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (25 commits) RDMA/mlx5: Fix integer overflow while resizing CQ Revert "RDMA/mlx5: Fix integer overflow while resizing CQ" RDMA/ucma: Check that user doesn't overflow QP state RDMA/mlx5: Fix integer overflow while resizing CQ RDMA/ucma: Limit possible option size IB/core: Fix possible crash to access NULL netdev RDMA/bnxt_re: Avoid Hard lockup during error CQE processing RDMA/core: Reduce poll batch for direct cq polling IB/mlx5: Fix an error code in __mlx5_ib_modify_qp() IB/mlx5: When not in dual port RoCE mode, use provided port as native IB/mlx4: Include GID type when deleting GIDs from HW table under RoCE IB/mlx4: Fix corruption of RoCEv2 IPv4 GIDs RDMA/qedr: Fix iWARP write and send with immediate RDMA/qedr: Fix kernel panic when running fio over NFSoRDMA RDMA/qedr: Fix iWARP connect with port mapper RDMA/qedr: Fix ipv6 destination address resolution IB/core : Add null pointer check in addr_resolve RDMA/bnxt_re: Fix the ib_reg failure cleanup RDMA/bnxt_re: Fix incorrect DB offset calculation RDMA/bnxt_re: Unconditionly fence non wire memory operations ...
2 parents b3337a6 + 28e9091 commit 2f64e70

File tree

23 files changed

+192
-156
lines changed

23 files changed

+192
-156
lines changed

drivers/infiniband/core/addr.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in,
550550
dst_release(dst);
551551
}
552552

553-
if (ndev->flags & IFF_LOOPBACK) {
554-
ret = rdma_translate_ip(dst_in, addr);
555-
/*
556-
* Put the loopback device and get the translated
557-
* device instead.
558-
*/
553+
if (ndev) {
554+
if (ndev->flags & IFF_LOOPBACK)
555+
ret = rdma_translate_ip(dst_in, addr);
556+
else
557+
addr->bound_dev_if = ndev->ifindex;
559558
dev_put(ndev);
560-
ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
561-
} else {
562-
addr->bound_dev_if = ndev->ifindex;
563559
}
564-
dev_put(ndev);
565560

566561
return ret;
567562
}

drivers/infiniband/core/cq.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
/* # of WCs to poll for with a single call to ib_poll_cq */
1919
#define IB_POLL_BATCH 16
20+
#define IB_POLL_BATCH_DIRECT 8
2021

2122
/* # of WCs to iterate over before yielding */
2223
#define IB_POLL_BUDGET_IRQ 256
@@ -25,18 +26,18 @@
2526
#define IB_POLL_FLAGS \
2627
(IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)
2728

28-
static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
29+
static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs,
30+
int batch)
2931
{
3032
int i, n, completed = 0;
31-
struct ib_wc *wcs = poll_wc ? : cq->wc;
3233

3334
/*
3435
* budget might be (-1) if the caller does not
3536
* want to bound this call, thus we need unsigned
3637
* minimum here.
3738
*/
38-
while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,
39-
budget - completed), wcs)) > 0) {
39+
while ((n = ib_poll_cq(cq, min_t(u32, batch,
40+
budget - completed), wcs)) > 0) {
4041
for (i = 0; i < n; i++) {
4142
struct ib_wc *wc = &wcs[i];
4243

@@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
4849

4950
completed += n;
5051

51-
if (n != IB_POLL_BATCH ||
52-
(budget != -1 && completed >= budget))
52+
if (n != batch || (budget != -1 && completed >= budget))
5353
break;
5454
}
5555

@@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
7272
*/
7373
int ib_process_cq_direct(struct ib_cq *cq, int budget)
7474
{
75-
struct ib_wc wcs[IB_POLL_BATCH];
75+
struct ib_wc wcs[IB_POLL_BATCH_DIRECT];
7676

77-
return __ib_process_cq(cq, budget, wcs);
77+
return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT);
7878
}
7979
EXPORT_SYMBOL(ib_process_cq_direct);
8080

@@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget)
8888
struct ib_cq *cq = container_of(iop, struct ib_cq, iop);
8989
int completed;
9090

91-
completed = __ib_process_cq(cq, budget, NULL);
91+
completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH);
9292
if (completed < budget) {
9393
irq_poll_complete(&cq->iop);
9494
if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
@@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work)
108108
struct ib_cq *cq = container_of(work, struct ib_cq, work);
109109
int completed;
110110

111-
completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL);
111+
completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc,
112+
IB_POLL_BATCH);
112113
if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
113114
ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
114115
queue_work(ib_comp_wq, &cq->work);

drivers/infiniband/core/device.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device,
536536
ret = device->query_device(device, &device->attrs, &uhw);
537537
if (ret) {
538538
pr_warn("Couldn't query the device attributes\n");
539-
goto cache_cleanup;
539+
goto cg_cleanup;
540540
}
541541

542542
ret = ib_device_register_sysfs(device, port_callback);
543543
if (ret) {
544544
pr_warn("Couldn't register device %s with driver model\n",
545545
device->name);
546-
goto cache_cleanup;
546+
goto cg_cleanup;
547547
}
548548

549549
device->reg_state = IB_DEV_REGISTERED;
@@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device,
559559
mutex_unlock(&device_mutex);
560560
return 0;
561561

562+
cg_cleanup:
563+
ib_device_unregister_rdmacg(device);
562564
cache_cleanup:
563565
ib_cache_cleanup_one(device);
564566
ib_cache_release_one(device);

drivers/infiniband/core/sa_query.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,
12911291

12921292
resolved_dev = dev_get_by_index(dev_addr.net,
12931293
dev_addr.bound_dev_if);
1294-
if (resolved_dev->flags & IFF_LOOPBACK) {
1295-
dev_put(resolved_dev);
1296-
resolved_dev = idev;
1297-
dev_hold(resolved_dev);
1294+
if (!resolved_dev) {
1295+
dev_put(idev);
1296+
return -ENODEV;
12981297
}
12991298
ndev = ib_get_ndev_from_path(rec);
13001299
rcu_read_lock();

drivers/infiniband/core/ucma.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
11491149
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
11501150
return -EFAULT;
11511151

1152+
if (cmd.qp_state > IB_QPS_ERR)
1153+
return -EINVAL;
1154+
11521155
ctx = ucma_get_ctx(file, cmd.id);
11531156
if (IS_ERR(ctx))
11541157
return PTR_ERR(ctx);
@@ -1294,6 +1297,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
12941297
if (IS_ERR(ctx))
12951298
return PTR_ERR(ctx);
12961299

1300+
if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
1301+
return -EINVAL;
1302+
12971303
optval = memdup_user((void __user *) (unsigned long) cmd.optval,
12981304
cmd.optlen);
12991305
if (IS_ERR(optval)) {

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ int bnxt_re_query_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
785785
return 0;
786786
}
787787

788-
static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)
788+
unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)
789789
__acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock)
790790
{
791791
unsigned long flags;
@@ -799,8 +799,8 @@ static unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)
799799
return flags;
800800
}
801801

802-
static void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
803-
unsigned long flags)
802+
void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
803+
unsigned long flags)
804804
__releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock)
805805
{
806806
if (qp->rcq != qp->scq)
@@ -1606,6 +1606,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
16061606
int status;
16071607
union ib_gid sgid;
16081608
struct ib_gid_attr sgid_attr;
1609+
unsigned int flags;
16091610
u8 nw_type;
16101611

16111612
qp->qplib_qp.modify_flags = 0;
@@ -1634,14 +1635,18 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
16341635
dev_dbg(rdev_to_dev(rdev),
16351636
"Move QP = %p to flush list\n",
16361637
qp);
1638+
flags = bnxt_re_lock_cqs(qp);
16371639
bnxt_qplib_add_flush_qp(&qp->qplib_qp);
1640+
bnxt_re_unlock_cqs(qp, flags);
16381641
}
16391642
if (!qp->sumem &&
16401643
qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {
16411644
dev_dbg(rdev_to_dev(rdev),
16421645
"Move QP = %p out of flush list\n",
16431646
qp);
1647+
flags = bnxt_re_lock_cqs(qp);
16441648
bnxt_qplib_clean_qp(&qp->qplib_qp);
1649+
bnxt_re_unlock_cqs(qp, flags);
16451650
}
16461651
}
16471652
if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {
@@ -2227,10 +2232,13 @@ static int bnxt_re_build_inv_wqe(struct ib_send_wr *wr,
22272232
wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV;
22282233
wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey;
22292234

2235+
/* Need unconditional fence for local invalidate
2236+
* opcode to work as expected.
2237+
*/
2238+
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2239+
22302240
if (wr->send_flags & IB_SEND_SIGNALED)
22312241
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
2232-
if (wr->send_flags & IB_SEND_FENCE)
2233-
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
22342242
if (wr->send_flags & IB_SEND_SOLICITED)
22352243
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT;
22362244

@@ -2251,8 +2259,12 @@ static int bnxt_re_build_reg_wqe(struct ib_reg_wr *wr,
22512259
wqe->frmr.levels = qplib_frpl->hwq.level + 1;
22522260
wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;
22532261

2254-
if (wr->wr.send_flags & IB_SEND_FENCE)
2255-
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2262+
/* Need unconditional fence for reg_mr
2263+
* opcode to function as expected.
2264+
*/
2265+
2266+
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
2267+
22562268
if (wr->wr.send_flags & IB_SEND_SIGNALED)
22572269
wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
22582270

drivers/infiniband/hw/bnxt_re/ib_verbs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,7 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
222222
struct ib_udata *udata);
223223
int bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
224224
int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
225+
226+
unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
227+
void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
225228
#endif /* __BNXT_RE_IB_VERBS_H__ */

drivers/infiniband/hw/bnxt_re/main.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,13 @@ static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event,
730730
struct bnxt_re_qp *qp)
731731
{
732732
struct ib_event event;
733+
unsigned int flags;
734+
735+
if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
736+
flags = bnxt_re_lock_cqs(qp);
737+
bnxt_qplib_add_flush_qp(&qp->qplib_qp);
738+
bnxt_re_unlock_cqs(qp, flags);
739+
}
733740

734741
memset(&event, 0, sizeof(event));
735742
if (qp->qplib_qp.srq) {
@@ -1416,9 +1423,12 @@ static void bnxt_re_task(struct work_struct *work)
14161423
switch (re_work->event) {
14171424
case NETDEV_REGISTER:
14181425
rc = bnxt_re_ib_reg(rdev);
1419-
if (rc)
1426+
if (rc) {
14201427
dev_err(rdev_to_dev(rdev),
14211428
"Failed to register with IB: %#x", rc);
1429+
bnxt_re_remove_one(rdev);
1430+
bnxt_re_dev_unreg(rdev);
1431+
}
14221432
break;
14231433
case NETDEV_UP:
14241434
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,

0 commit comments

Comments
 (0)