Skip to content

Commit 8a8c600

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: "The usual collection of driver bug fixes, and a few regressions from the merge window. Nothing particularly worrisome. - Various missed memory frees and error unwind bugs - Fix regressions in a few iwarp drivers from 5.4 patches - A few regressions added in past kernels - Squash a number of races in mlx5 ODP code" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/mlx5: Add missing synchronize_srcu() for MW cases RDMA/mlx5: Put live in the correct place for ODP MRs RDMA/mlx5: Order num_pending_prefetch properly with synchronize_srcu RDMA/odp: Lift umem_mutex out of ib_umem_odp_unmap_dma_pages() RDMA/mlx5: Fix a race with mlx5_ib_update_xlt on an implicit MR RDMA/mlx5: Do not allow rereg of a ODP MR IB/core: Fix wrong iterating on ports RDMA/nldev: Reshuffle the code to avoid need to rebind QP in error path RDMA/cxgb4: Do not dma memory off of the stack RDMA/cm: Fix memory leak in cm_add/remove_one RDMA/core: Fix an error handling path in 'res_get_common_doit()' RDMA/i40iw: Associate ibdev to netdev before IB device registration RDMA/iwcm: Fix a lock inversion issue RDMA/iw_cxgb4: fix SRQ access from dump_qp() RDMA/hfi1: Prevent memory leak in sdma_init RDMA/core: Fix use after free and refcnt leak on ndev in_device in iwarp_query_port RDMA/siw: Fix serialization issue in write_space() RDMA/vmw_pvrdma: Free SRQ only once
2 parents e60329c + 0417791 commit 8a8c600

File tree

18 files changed

+154
-147
lines changed

18 files changed

+154
-147
lines changed

drivers/infiniband/core/cm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4399,6 +4399,7 @@ static void cm_add_one(struct ib_device *ib_device)
43994399
error1:
44004400
port_modify.set_port_cap_mask = 0;
44014401
port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
4402+
kfree(port);
44024403
while (--i) {
44034404
if (!rdma_cap_ib_cm(ib_device, i))
44044405
continue;
@@ -4407,6 +4408,7 @@ static void cm_add_one(struct ib_device *ib_device)
44074408
ib_modify_port(ib_device, port->port_num, 0, &port_modify);
44084409
ib_unregister_mad_agent(port->mad_agent);
44094410
cm_remove_port_fs(port);
4411+
kfree(port);
44104412
}
44114413
free:
44124414
kfree(cm_dev);
@@ -4460,6 +4462,7 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
44604462
spin_unlock_irq(&cm.state_lock);
44614463
ib_unregister_mad_agent(cur_mad_agent);
44624464
cm_remove_port_fs(port);
4465+
kfree(port);
44634466
}
44644467

44654468
kfree(cm_dev);

drivers/infiniband/core/cma.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2396,9 +2396,10 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
23962396
conn_id->cm_id.iw = NULL;
23972397
cma_exch(conn_id, RDMA_CM_DESTROYING);
23982398
mutex_unlock(&conn_id->handler_mutex);
2399+
mutex_unlock(&listen_id->handler_mutex);
23992400
cma_deref_id(conn_id);
24002401
rdma_destroy_id(&conn_id->id);
2401-
goto out;
2402+
return ret;
24022403
}
24032404

24042405
mutex_unlock(&conn_id->handler_mutex);

drivers/infiniband/core/device.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,28 +1987,29 @@ static int iw_query_port(struct ib_device *device,
19871987
if (!netdev)
19881988
return -ENODEV;
19891989

1990-
dev_put(netdev);
1991-
19921990
port_attr->max_mtu = IB_MTU_4096;
19931991
port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
19941992

19951993
if (!netif_carrier_ok(netdev)) {
19961994
port_attr->state = IB_PORT_DOWN;
19971995
port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
19981996
} else {
1999-
inetdev = in_dev_get(netdev);
1997+
rcu_read_lock();
1998+
inetdev = __in_dev_get_rcu(netdev);
20001999

20012000
if (inetdev && inetdev->ifa_list) {
20022001
port_attr->state = IB_PORT_ACTIVE;
20032002
port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
2004-
in_dev_put(inetdev);
20052003
} else {
20062004
port_attr->state = IB_PORT_INIT;
20072005
port_attr->phys_state =
20082006
IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING;
20092007
}
2008+
2009+
rcu_read_unlock();
20102010
}
20112011

2012+
dev_put(netdev);
20122013
err = device->ops.query_port(device, port_num, port_attr);
20132014
if (err)
20142015
return err;

drivers/infiniband/core/nldev.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
12301230
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12311231
if (!msg) {
12321232
ret = -ENOMEM;
1233-
goto err;
1233+
goto err_get;
12341234
}
12351235

12361236
nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
@@ -1787,10 +1787,6 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
17871787

17881788
cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]);
17891789
qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]);
1790-
ret = rdma_counter_unbind_qpn(device, port, qpn, cntn);
1791-
if (ret)
1792-
goto err_unbind;
1793-
17941790
if (fill_nldev_handle(msg, device) ||
17951791
nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port) ||
17961792
nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, cntn) ||
@@ -1799,13 +1795,15 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
17991795
goto err_fill;
18001796
}
18011797

1798+
ret = rdma_counter_unbind_qpn(device, port, qpn, cntn);
1799+
if (ret)
1800+
goto err_fill;
1801+
18021802
nlmsg_end(msg, nlh);
18031803
ib_device_put(device);
18041804
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
18051805

18061806
err_fill:
1807-
rdma_counter_bind_qpn(device, port, qpn, cntn);
1808-
err_unbind:
18091807
nlmsg_free(msg);
18101808
err:
18111809
ib_device_put(device);

drivers/infiniband/core/security.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev)
426426
int ret;
427427

428428
rdma_for_each_port (dev, i) {
429-
is_ib = rdma_protocol_ib(dev, i++);
429+
is_ib = rdma_protocol_ib(dev, i);
430430
if (is_ib)
431431
break;
432432
}

drivers/infiniband/core/umem_odp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,10 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
451451
* that the hardware will not attempt to access the MR any more.
452452
*/
453453
if (!umem_odp->is_implicit_odp) {
454+
mutex_lock(&umem_odp->umem_mutex);
454455
ib_umem_odp_unmap_dma_pages(umem_odp, ib_umem_start(umem_odp),
455456
ib_umem_end(umem_odp));
457+
mutex_unlock(&umem_odp->umem_mutex);
456458
kvfree(umem_odp->dma_list);
457459
kvfree(umem_odp->page_list);
458460
}
@@ -719,14 +721,15 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
719721
u64 addr;
720722
struct ib_device *dev = umem_odp->umem.ibdev;
721723

724+
lockdep_assert_held(&umem_odp->umem_mutex);
725+
722726
virt = max_t(u64, virt, ib_umem_start(umem_odp));
723727
bound = min_t(u64, bound, ib_umem_end(umem_odp));
724728
/* Note that during the run of this function, the
725729
* notifiers_count of the MR is > 0, preventing any racing
726730
* faults from completion. We might be racing with other
727731
* invalidations, so we must make sure we free each page only
728732
* once. */
729-
mutex_lock(&umem_odp->umem_mutex);
730733
for (addr = virt; addr < bound; addr += BIT(umem_odp->page_shift)) {
731734
idx = (addr - ib_umem_start(umem_odp)) >> umem_odp->page_shift;
732735
if (umem_odp->page_list[idx]) {
@@ -757,7 +760,6 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
757760
umem_odp->npages--;
758761
}
759762
}
760-
mutex_unlock(&umem_odp->umem_mutex);
761763
}
762764
EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages);
763765

drivers/infiniband/hw/cxgb4/device.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,13 @@ static void set_ep_sin6_addrs(struct c4iw_ep *ep,
242242
}
243243
}
244244

245-
static int dump_qp(struct c4iw_qp *qp, struct c4iw_debugfs_data *qpd)
245+
static int dump_qp(unsigned long id, struct c4iw_qp *qp,
246+
struct c4iw_debugfs_data *qpd)
246247
{
247248
int space;
248249
int cc;
250+
if (id != qp->wq.sq.qid)
251+
return 0;
249252

250253
space = qpd->bufsize - qpd->pos - 1;
251254
if (space == 0)
@@ -350,7 +353,7 @@ static int qp_open(struct inode *inode, struct file *file)
350353

351354
xa_lock_irq(&qpd->devp->qps);
352355
xa_for_each(&qpd->devp->qps, index, qp)
353-
dump_qp(qp, qpd);
356+
dump_qp(index, qp, qpd);
354357
xa_unlock_irq(&qpd->devp->qps);
355358

356359
qpd->buf[qpd->pos++] = 0;

drivers/infiniband/hw/cxgb4/mem.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,17 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
275275
struct sk_buff *skb, struct c4iw_wr_wait *wr_waitp)
276276
{
277277
int err;
278-
struct fw_ri_tpte tpt;
278+
struct fw_ri_tpte *tpt;
279279
u32 stag_idx;
280280
static atomic_t key;
281281

282282
if (c4iw_fatal_error(rdev))
283283
return -EIO;
284284

285+
tpt = kmalloc(sizeof(*tpt), GFP_KERNEL);
286+
if (!tpt)
287+
return -ENOMEM;
288+
285289
stag_state = stag_state > 0;
286290
stag_idx = (*stag) >> 8;
287291

@@ -291,6 +295,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
291295
mutex_lock(&rdev->stats.lock);
292296
rdev->stats.stag.fail++;
293297
mutex_unlock(&rdev->stats.lock);
298+
kfree(tpt);
294299
return -ENOMEM;
295300
}
296301
mutex_lock(&rdev->stats.lock);
@@ -305,35 +310,36 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
305310

306311
/* write TPT entry */
307312
if (reset_tpt_entry)
308-
memset(&tpt, 0, sizeof(tpt));
313+
memset(tpt, 0, sizeof(*tpt));
309314
else {
310-
tpt.valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
315+
tpt->valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F |
311316
FW_RI_TPTE_STAGKEY_V((*stag & FW_RI_TPTE_STAGKEY_M)) |
312317
FW_RI_TPTE_STAGSTATE_V(stag_state) |
313318
FW_RI_TPTE_STAGTYPE_V(type) | FW_RI_TPTE_PDID_V(pdid));
314-
tpt.locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
319+
tpt->locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) |
315320
(bind_enabled ? FW_RI_TPTE_MWBINDEN_F : 0) |
316321
FW_RI_TPTE_ADDRTYPE_V((zbva ? FW_RI_ZERO_BASED_TO :
317322
FW_RI_VA_BASED_TO))|
318323
FW_RI_TPTE_PS_V(page_size));
319-
tpt.nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
324+
tpt->nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
320325
FW_RI_TPTE_PBLADDR_V(PBL_OFF(rdev, pbl_addr)>>3));
321-
tpt.len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
322-
tpt.va_hi = cpu_to_be32((u32)(to >> 32));
323-
tpt.va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
324-
tpt.dca_mwbcnt_pstag = cpu_to_be32(0);
325-
tpt.len_hi = cpu_to_be32((u32)(len >> 32));
326+
tpt->len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
327+
tpt->va_hi = cpu_to_be32((u32)(to >> 32));
328+
tpt->va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
329+
tpt->dca_mwbcnt_pstag = cpu_to_be32(0);
330+
tpt->len_hi = cpu_to_be32((u32)(len >> 32));
326331
}
327332
err = write_adapter_mem(rdev, stag_idx +
328333
(rdev->lldi.vr->stag.start >> 5),
329-
sizeof(tpt), &tpt, skb, wr_waitp);
334+
sizeof(*tpt), tpt, skb, wr_waitp);
330335

331336
if (reset_tpt_entry) {
332337
c4iw_put_resource(&rdev->resource.tpt_table, stag_idx);
333338
mutex_lock(&rdev->stats.lock);
334339
rdev->stats.stag.cur -= 32;
335340
mutex_unlock(&rdev->stats.lock);
336341
}
342+
kfree(tpt);
337343
return err;
338344
}
339345

drivers/infiniband/hw/cxgb4/qp.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2737,15 +2737,11 @@ int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs,
27372737
if (CHELSIO_CHIP_VERSION(rhp->rdev.lldi.adapter_type) > CHELSIO_T6)
27382738
srq->flags = T4_SRQ_LIMIT_SUPPORT;
27392739

2740-
ret = xa_insert_irq(&rhp->qps, srq->wq.qid, srq, GFP_KERNEL);
2741-
if (ret)
2742-
goto err_free_queue;
2743-
27442740
if (udata) {
27452741
srq_key_mm = kmalloc(sizeof(*srq_key_mm), GFP_KERNEL);
27462742
if (!srq_key_mm) {
27472743
ret = -ENOMEM;
2748-
goto err_remove_handle;
2744+
goto err_free_queue;
27492745
}
27502746
srq_db_key_mm = kmalloc(sizeof(*srq_db_key_mm), GFP_KERNEL);
27512747
if (!srq_db_key_mm) {
@@ -2789,8 +2785,6 @@ int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs,
27892785
kfree(srq_db_key_mm);
27902786
err_free_srq_key_mm:
27912787
kfree(srq_key_mm);
2792-
err_remove_handle:
2793-
xa_erase_irq(&rhp->qps, srq->wq.qid);
27942788
err_free_queue:
27952789
free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx,
27962790
srq->wr_waitp);
@@ -2813,8 +2807,6 @@ void c4iw_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
28132807
rhp = srq->rhp;
28142808

28152809
pr_debug("%s id %d\n", __func__, srq->wq.qid);
2816-
2817-
xa_erase_irq(&rhp->qps, srq->wq.qid);
28182810
ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext,
28192811
ibucontext);
28202812
free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx,

drivers/infiniband/hw/hfi1/sdma.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1526,8 +1526,11 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
15261526
}
15271527

15281528
ret = rhashtable_init(tmp_sdma_rht, &sdma_rht_params);
1529-
if (ret < 0)
1529+
if (ret < 0) {
1530+
kfree(tmp_sdma_rht);
15301531
goto bail;
1532+
}
1533+
15311534
dd->sdma_rht = tmp_sdma_rht;
15321535

15331536
dd_dev_info(dd, "SDMA num_sdma: %u\n", dd->num_sdma);

0 commit comments

Comments
 (0)