Skip to content

Commit 7e4a6b5

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: "Several mlx5 bugs, crashers, and reports: - Limit stack usage - Fix mis-use of __xa_store/erase() without holding the lock to a locked version - Rate limit prints in the gid cache error cases - Fully initialize the event object before making it globally visible in an xarray - Fix deadlock inside the ODP code if the MMU notifier was called from a reclaim context - Include missed counters for some switchdev configurations and mulit-port MPV mode - Fix loopback packet support when in mulit-port MPV mode" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/mlx5: Fix vport loopback for MPV device RDMA/mlx5: Fix CC counters query for MPV RDMA/mlx5: Fix HW counters query for non-representor devices IB/core: Annotate umem_mutex acquisition under fs_reclaim for lockdep IB/mlx5: Fix potential deadlock in MR deregistration RDMA/mlx5: Initialize obj_event->obj_sub_list before xa_insert RDMA/core: Rate limit GID cache warning messages RDMA/mlx5: Fix unsafe xarray access in implicit ODP handling RDMA/mlx5: reduce stack usage in mlx5_ib_ufile_hw_cleanup
2 parents 65c1736 + a9a9e68 commit 7e4a6b5

File tree

7 files changed

+107
-24
lines changed

7 files changed

+107
-24
lines changed

drivers/infiniband/core/cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,8 @@ static int __ib_cache_gid_add(struct ib_device *ib_dev, u32 port,
582582
out_unlock:
583583
mutex_unlock(&table->lock);
584584
if (ret)
585-
pr_warn("%s: unable to add gid %pI6 error=%d\n",
586-
__func__, gid->raw, ret);
585+
pr_warn_ratelimited("%s: unable to add gid %pI6 error=%d\n",
586+
__func__, gid->raw, ret);
587587
return ret;
588588
}
589589

drivers/infiniband/core/umem_odp.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
7676
end = ALIGN(end, page_size);
7777
if (unlikely(end < page_size))
7878
return -EOVERFLOW;
79+
/*
80+
* The mmu notifier can be called within reclaim contexts and takes the
81+
* umem_mutex. This is rare to trigger in testing, teach lockdep about
82+
* it.
83+
*/
84+
if (IS_ENABLED(CONFIG_LOCKDEP)) {
85+
fs_reclaim_acquire(GFP_KERNEL);
86+
mutex_lock(&umem_odp->umem_mutex);
87+
mutex_unlock(&umem_odp->umem_mutex);
88+
fs_reclaim_release(GFP_KERNEL);
89+
}
7990

8091
nr_entries = (end - start) >> PAGE_SHIFT;
8192
if (!(nr_entries * PAGE_SIZE / page_size))

drivers/infiniband/hw/mlx5/counters.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ static int do_get_hw_stats(struct ib_device *ibdev,
398398
return ret;
399399

400400
/* We don't expose device counters over Vports */
401-
if (is_mdev_switchdev_mode(dev->mdev) && port_num != 0)
401+
if (is_mdev_switchdev_mode(dev->mdev) && dev->is_rep && port_num != 0)
402402
goto done;
403403

404404
if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
@@ -418,7 +418,7 @@ static int do_get_hw_stats(struct ib_device *ibdev,
418418
*/
419419
goto done;
420420
}
421-
ret = mlx5_lag_query_cong_counters(dev->mdev,
421+
ret = mlx5_lag_query_cong_counters(mdev,
422422
stats->value +
423423
cnts->num_q_counters,
424424
cnts->num_cong_counters,

drivers/infiniband/hw/mlx5/devx.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,7 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table,
19581958
/* Level1 is valid for future use, no need to free */
19591959
return -ENOMEM;
19601960

1961+
INIT_LIST_HEAD(&obj_event->obj_sub_list);
19611962
err = xa_insert(&event->object_ids,
19621963
key_level2,
19631964
obj_event,
@@ -1966,7 +1967,6 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table,
19661967
kfree(obj_event);
19671968
return err;
19681969
}
1969-
INIT_LIST_HEAD(&obj_event->obj_sub_list);
19701970
}
19711971

19721972
return 0;
@@ -2669,7 +2669,7 @@ static void devx_wait_async_destroy(struct mlx5_async_cmd *cmd)
26692669

26702670
void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
26712671
{
2672-
struct mlx5_async_cmd async_cmd[MAX_ASYNC_CMDS];
2672+
struct mlx5_async_cmd *async_cmd;
26732673
struct ib_ucontext *ucontext = ufile->ucontext;
26742674
struct ib_device *device = ucontext->device;
26752675
struct mlx5_ib_dev *dev = to_mdev(device);
@@ -2678,6 +2678,10 @@ void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
26782678
int head = 0;
26792679
int tail = 0;
26802680

2681+
async_cmd = kcalloc(MAX_ASYNC_CMDS, sizeof(*async_cmd), GFP_KERNEL);
2682+
if (!async_cmd)
2683+
return;
2684+
26812685
list_for_each_entry(uobject, &ufile->uobjects, list) {
26822686
WARN_ON(uverbs_try_lock_object(uobject, UVERBS_LOOKUP_WRITE));
26832687

@@ -2713,6 +2717,8 @@ void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
27132717
devx_wait_async_destroy(&async_cmd[head % MAX_ASYNC_CMDS]);
27142718
head++;
27152719
}
2720+
2721+
kfree(async_cmd);
27162722
}
27172723

27182724
static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,

drivers/infiniband/hw/mlx5/main.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,6 +1791,33 @@ static void deallocate_uars(struct mlx5_ib_dev *dev,
17911791
context->devx_uid);
17921792
}
17931793

1794+
static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master,
1795+
struct mlx5_core_dev *slave)
1796+
{
1797+
int err;
1798+
1799+
err = mlx5_nic_vport_update_local_lb(master, true);
1800+
if (err)
1801+
return err;
1802+
1803+
err = mlx5_nic_vport_update_local_lb(slave, true);
1804+
if (err)
1805+
goto out;
1806+
1807+
return 0;
1808+
1809+
out:
1810+
mlx5_nic_vport_update_local_lb(master, false);
1811+
return err;
1812+
}
1813+
1814+
static void mlx5_ib_disable_lb_mp(struct mlx5_core_dev *master,
1815+
struct mlx5_core_dev *slave)
1816+
{
1817+
mlx5_nic_vport_update_local_lb(slave, false);
1818+
mlx5_nic_vport_update_local_lb(master, false);
1819+
}
1820+
17941821
int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp)
17951822
{
17961823
int err = 0;
@@ -3495,6 +3522,8 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
34953522

34963523
lockdep_assert_held(&mlx5_ib_multiport_mutex);
34973524

3525+
mlx5_ib_disable_lb_mp(ibdev->mdev, mpi->mdev);
3526+
34983527
mlx5_core_mp_event_replay(ibdev->mdev,
34993528
MLX5_DRIVER_EVENT_AFFILIATION_REMOVED,
35003529
NULL);
@@ -3590,6 +3619,10 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
35903619
MLX5_DRIVER_EVENT_AFFILIATION_DONE,
35913620
&key);
35923621

3622+
err = mlx5_ib_enable_lb_mp(ibdev->mdev, mpi->mdev);
3623+
if (err)
3624+
goto unbind;
3625+
35933626
return true;
35943627

35953628
unbind:

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,23 +2027,50 @@ void mlx5_ib_revoke_data_direct_mrs(struct mlx5_ib_dev *dev)
20272027
}
20282028
}
20292029

2030-
static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
2030+
static int mlx5_umr_revoke_mr_with_lock(struct mlx5_ib_mr *mr)
20312031
{
2032-
struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
2033-
struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
2034-
bool is_odp = is_odp_mr(mr);
20352032
bool is_odp_dma_buf = is_dmabuf_mr(mr) &&
2036-
!to_ib_umem_dmabuf(mr->umem)->pinned;
2037-
bool from_cache = !!ent;
2038-
int ret = 0;
2033+
!to_ib_umem_dmabuf(mr->umem)->pinned;
2034+
bool is_odp = is_odp_mr(mr);
2035+
int ret;
20392036

20402037
if (is_odp)
20412038
mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
20422039

20432040
if (is_odp_dma_buf)
2044-
dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv, NULL);
2041+
dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv,
2042+
NULL);
2043+
2044+
ret = mlx5r_umr_revoke_mr(mr);
2045+
2046+
if (is_odp) {
2047+
if (!ret)
2048+
to_ib_umem_odp(mr->umem)->private = NULL;
2049+
mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
2050+
}
2051+
2052+
if (is_odp_dma_buf) {
2053+
if (!ret)
2054+
to_ib_umem_dmabuf(mr->umem)->private = NULL;
2055+
dma_resv_unlock(
2056+
to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
2057+
}
20452058

2046-
if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) {
2059+
return ret;
2060+
}
2061+
2062+
static int mlx5r_handle_mkey_cleanup(struct mlx5_ib_mr *mr)
2063+
{
2064+
bool is_odp_dma_buf = is_dmabuf_mr(mr) &&
2065+
!to_ib_umem_dmabuf(mr->umem)->pinned;
2066+
struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
2067+
struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
2068+
bool is_odp = is_odp_mr(mr);
2069+
bool from_cache = !!ent;
2070+
int ret;
2071+
2072+
if (mr->mmkey.cacheable && !mlx5_umr_revoke_mr_with_lock(mr) &&
2073+
!cache_ent_find_and_store(dev, mr)) {
20472074
ent = mr->mmkey.cache_ent;
20482075
/* upon storing to a clean temp entry - schedule its cleanup */
20492076
spin_lock_irq(&ent->mkeys_queue.lock);
@@ -2055,7 +2082,7 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
20552082
ent->tmp_cleanup_scheduled = true;
20562083
}
20572084
spin_unlock_irq(&ent->mkeys_queue.lock);
2058-
goto out;
2085+
return 0;
20592086
}
20602087

20612088
if (ent) {
@@ -2064,8 +2091,14 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
20642091
mr->mmkey.cache_ent = NULL;
20652092
spin_unlock_irq(&ent->mkeys_queue.lock);
20662093
}
2094+
2095+
if (is_odp)
2096+
mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
2097+
2098+
if (is_odp_dma_buf)
2099+
dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv,
2100+
NULL);
20672101
ret = destroy_mkey(dev, mr);
2068-
out:
20692102
if (is_odp) {
20702103
if (!ret)
20712104
to_ib_umem_odp(mr->umem)->private = NULL;
@@ -2075,9 +2108,9 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
20752108
if (is_odp_dma_buf) {
20762109
if (!ret)
20772110
to_ib_umem_dmabuf(mr->umem)->private = NULL;
2078-
dma_resv_unlock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
2111+
dma_resv_unlock(
2112+
to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
20792113
}
2080-
20812114
return ret;
20822115
}
20832116

@@ -2126,7 +2159,7 @@ static int __mlx5_ib_dereg_mr(struct ib_mr *ibmr)
21262159
}
21272160

21282161
/* Stop DMA */
2129-
rc = mlx5_revoke_mr(mr);
2162+
rc = mlx5r_handle_mkey_cleanup(mr);
21302163
if (rc)
21312164
return rc;
21322165

drivers/infiniband/hw/mlx5/odp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ static void destroy_unused_implicit_child_mr(struct mlx5_ib_mr *mr)
259259
}
260260

261261
if (MLX5_CAP_ODP(mr_to_mdev(mr)->mdev, mem_page_fault))
262-
__xa_erase(&mr_to_mdev(mr)->odp_mkeys,
263-
mlx5_base_mkey(mr->mmkey.key));
262+
xa_erase(&mr_to_mdev(mr)->odp_mkeys,
263+
mlx5_base_mkey(mr->mmkey.key));
264264
xa_unlock(&imr->implicit_children);
265265

266266
/* Freeing a MR is a sleeping operation, so bounce to a work queue */
@@ -532,8 +532,8 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr,
532532
}
533533

534534
if (MLX5_CAP_ODP(dev->mdev, mem_page_fault)) {
535-
ret = __xa_store(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key),
536-
&mr->mmkey, GFP_KERNEL);
535+
ret = xa_store(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key),
536+
&mr->mmkey, GFP_KERNEL);
537537
if (xa_is_err(ret)) {
538538
ret = ERR_PTR(xa_err(ret));
539539
__xa_erase(&imr->implicit_children, idx);

0 commit comments

Comments
 (0)