Skip to content

Commit 9603e22

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: "A small collection of -rc fixes. Mostly. One API addition, but that's because we wanted to use it in a fix. There's also a bug fix that is going to render the 5.5 kernel's soft-RoCE driver incompatible with all soft-RoCE versions prior, but it's required to actually implement the protocol according to the RoCE spec and required in order for the soft-RoCE driver to be able to successfully work with actual RoCE hardware. Summary: - Update Steve Wise info - Fix for soft-RoCE crc calculations (will break back compatibility, but only with the soft-RoCE driver, which has had this bug since it was introduced and it is an on-the-wire bug, but will make soft-RoCE fully compatible with real RoCE hardware) - cma init fixup - counters oops fix - fix for mlx4 init/teardown sequence - fix for mkx5 steering rules - introduce a cleanup API, which isn't a fix, but we want to use it in the next fix - fix for mlx5 memory management that uses API in previous patch" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: IB/mlx5: Fix device memory flows IB/core: Introduce rdma_user_mmap_entry_insert_range() API IB/mlx5: Fix steering rule of drop and count IB/mlx4: Follow mirror sequence of device add during device removal RDMA/counter: Prevent auto-binding a QP which are not tracked with res rxe: correctly calculate iCRC for unaligned payloads Update mailmap info for Steve Wise RDMA/cma: add missed unregister_pernet_subsys in init failure
2 parents 1522d9d + dc2316e commit 9603e22

File tree

13 files changed

+180
-73
lines changed

13 files changed

+180
-73
lines changed

.mailmap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,5 @@ Gustavo Padovan <[email protected]>
276276
Gustavo Padovan <[email protected]>
277277
278278
279+
280+

drivers/infiniband/core/cma.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4763,6 +4763,7 @@ static int __init cma_init(void)
47634763
err:
47644764
unregister_netdevice_notifier(&cma_nb);
47654765
ib_sa_unregister_client(&sa_client);
4766+
unregister_pernet_subsys(&cma_pernet_operations);
47664767
err_wq:
47674768
destroy_workqueue(cma_wq);
47684769
return ret;

drivers/infiniband/core/counters.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port)
286286
struct rdma_counter *counter;
287287
int ret;
288288

289+
if (!qp->res.valid)
290+
return 0;
291+
289292
if (!rdma_is_port_valid(dev, port))
290293
return -EINVAL;
291294

drivers/infiniband/core/ib_core_uverbs.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,28 +238,32 @@ void rdma_user_mmap_entry_remove(struct rdma_user_mmap_entry *entry)
238238
EXPORT_SYMBOL(rdma_user_mmap_entry_remove);
239239

240240
/**
241-
* rdma_user_mmap_entry_insert() - Insert an entry to the mmap_xa
241+
* rdma_user_mmap_entry_insert_range() - Insert an entry to the mmap_xa
242+
* in a given range.
242243
*
243244
* @ucontext: associated user context.
244245
* @entry: the entry to insert into the mmap_xa
245246
* @length: length of the address that will be mmapped
247+
* @min_pgoff: minimum pgoff to be returned
248+
* @max_pgoff: maximum pgoff to be returned
246249
*
247250
* This function should be called by drivers that use the rdma_user_mmap
248251
* interface for implementing their mmap syscall A database of mmap offsets is
249252
* handled in the core and helper functions are provided to insert entries
250253
* into the database and extract entries when the user calls mmap with the
251-
* given offset. The function allocates a unique page offset that should be
252-
* provided to user, the user will use the offset to retrieve information such
253-
* as address to be mapped and how.
254+
* given offset. The function allocates a unique page offset in a given range
255+
* that should be provided to user, the user will use the offset to retrieve
256+
* information such as address to be mapped and how.
254257
*
255258
* Return: 0 on success and -ENOMEM on failure
256259
*/
257-
int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
258-
struct rdma_user_mmap_entry *entry,
259-
size_t length)
260+
int rdma_user_mmap_entry_insert_range(struct ib_ucontext *ucontext,
261+
struct rdma_user_mmap_entry *entry,
262+
size_t length, u32 min_pgoff,
263+
u32 max_pgoff)
260264
{
261265
struct ib_uverbs_file *ufile = ucontext->ufile;
262-
XA_STATE(xas, &ucontext->mmap_xa, 0);
266+
XA_STATE(xas, &ucontext->mmap_xa, min_pgoff);
263267
u32 xa_first, xa_last, npages;
264268
int err;
265269
u32 i;
@@ -285,7 +289,7 @@ int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
285289
entry->npages = npages;
286290
while (true) {
287291
/* First find an empty index */
288-
xas_find_marked(&xas, U32_MAX, XA_FREE_MARK);
292+
xas_find_marked(&xas, max_pgoff, XA_FREE_MARK);
289293
if (xas.xa_node == XAS_RESTART)
290294
goto err_unlock;
291295

@@ -332,4 +336,30 @@ int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
332336
mutex_unlock(&ufile->umap_lock);
333337
return -ENOMEM;
334338
}
339+
EXPORT_SYMBOL(rdma_user_mmap_entry_insert_range);
340+
341+
/**
342+
* rdma_user_mmap_entry_insert() - Insert an entry to the mmap_xa.
343+
*
344+
* @ucontext: associated user context.
345+
* @entry: the entry to insert into the mmap_xa
346+
* @length: length of the address that will be mmapped
347+
*
348+
* This function should be called by drivers that use the rdma_user_mmap
349+
* interface for handling user mmapped addresses. The database is handled in
350+
* the core and helper functions are provided to insert entries into the
351+
* database and extract entries when the user calls mmap with the given offset.
352+
* The function allocates a unique page offset that should be provided to user,
353+
* the user will use the offset to retrieve information such as address to
354+
* be mapped and how.
355+
*
356+
* Return: 0 on success and -ENOMEM on failure
357+
*/
358+
int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
359+
struct rdma_user_mmap_entry *entry,
360+
size_t length)
361+
{
362+
return rdma_user_mmap_entry_insert_range(ucontext, entry, length, 0,
363+
U32_MAX);
364+
}
335365
EXPORT_SYMBOL(rdma_user_mmap_entry_insert);

drivers/infiniband/hw/mlx4/main.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3018,16 +3018,17 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
30183018
ibdev->ib_active = false;
30193019
flush_workqueue(wq);
30203020

3021-
mlx4_ib_close_sriov(ibdev);
3022-
mlx4_ib_mad_cleanup(ibdev);
3023-
ib_unregister_device(&ibdev->ib_dev);
3024-
mlx4_ib_diag_cleanup(ibdev);
30253021
if (ibdev->iboe.nb.notifier_call) {
30263022
if (unregister_netdevice_notifier(&ibdev->iboe.nb))
30273023
pr_warn("failure unregistering notifier\n");
30283024
ibdev->iboe.nb.notifier_call = NULL;
30293025
}
30303026

3027+
mlx4_ib_close_sriov(ibdev);
3028+
mlx4_ib_mad_cleanup(ibdev);
3029+
ib_unregister_device(&ibdev->ib_dev);
3030+
mlx4_ib_diag_cleanup(ibdev);
3031+
30313032
mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
30323033
ibdev->steer_qpn_count);
30333034
kfree(ibdev->ib_uc_qpns_bitmap);

drivers/infiniband/hw/mlx5/cmd.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
157157
return -ENOMEM;
158158
}
159159

160-
int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
160+
void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
161161
{
162162
struct mlx5_core_dev *dev = dm->dev;
163163
u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
@@ -175,15 +175,13 @@ int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length)
175175
MLX5_SET(dealloc_memic_in, in, memic_size, length);
176176

177177
err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
178+
if (err)
179+
return;
178180

179-
if (!err) {
180-
spin_lock(&dm->lock);
181-
bitmap_clear(dm->memic_alloc_pages,
182-
start_page_idx, num_pages);
183-
spin_unlock(&dm->lock);
184-
}
185-
186-
return err;
181+
spin_lock(&dm->lock);
182+
bitmap_clear(dm->memic_alloc_pages,
183+
start_page_idx, num_pages);
184+
spin_unlock(&dm->lock);
187185
}
188186

189187
int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out)

drivers/infiniband/hw/mlx5/cmd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
4646
void *in, int in_size);
4747
int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
4848
u64 length, u32 alignment);
49-
int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
49+
void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
5050
void mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid);
5151
void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid);
5252
void mlx5_cmd_destroy_tis(struct mlx5_core_dev *dev, u32 tisn, u16 uid);

drivers/infiniband/hw/mlx5/main.c

Lines changed: 85 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,24 @@ static int mlx5_ib_mmap_clock_info_page(struct mlx5_ib_dev *dev,
20742074
virt_to_page(dev->mdev->clock_info));
20752075
}
20762076

2077+
static void mlx5_ib_mmap_free(struct rdma_user_mmap_entry *entry)
2078+
{
2079+
struct mlx5_user_mmap_entry *mentry = to_mmmap(entry);
2080+
struct mlx5_ib_dev *dev = to_mdev(entry->ucontext->device);
2081+
struct mlx5_ib_dm *mdm;
2082+
2083+
switch (mentry->mmap_flag) {
2084+
case MLX5_IB_MMAP_TYPE_MEMIC:
2085+
mdm = container_of(mentry, struct mlx5_ib_dm, mentry);
2086+
mlx5_cmd_dealloc_memic(&dev->dm, mdm->dev_addr,
2087+
mdm->size);
2088+
kfree(mdm);
2089+
break;
2090+
default:
2091+
WARN_ON(true);
2092+
}
2093+
}
2094+
20772095
static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
20782096
struct vm_area_struct *vma,
20792097
struct mlx5_ib_ucontext *context)
@@ -2186,26 +2204,55 @@ static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
21862204
return err;
21872205
}
21882206

2189-
static int dm_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
2207+
static int add_dm_mmap_entry(struct ib_ucontext *context,
2208+
struct mlx5_ib_dm *mdm,
2209+
u64 address)
2210+
{
2211+
mdm->mentry.mmap_flag = MLX5_IB_MMAP_TYPE_MEMIC;
2212+
mdm->mentry.address = address;
2213+
return rdma_user_mmap_entry_insert_range(
2214+
context, &mdm->mentry.rdma_entry,
2215+
mdm->size,
2216+
MLX5_IB_MMAP_DEVICE_MEM << 16,
2217+
(MLX5_IB_MMAP_DEVICE_MEM << 16) + (1UL << 16) - 1);
2218+
}
2219+
2220+
static unsigned long mlx5_vma_to_pgoff(struct vm_area_struct *vma)
2221+
{
2222+
unsigned long idx;
2223+
u8 command;
2224+
2225+
command = get_command(vma->vm_pgoff);
2226+
idx = get_extended_index(vma->vm_pgoff);
2227+
2228+
return (command << 16 | idx);
2229+
}
2230+
2231+
static int mlx5_ib_mmap_offset(struct mlx5_ib_dev *dev,
2232+
struct vm_area_struct *vma,
2233+
struct ib_ucontext *ucontext)
21902234
{
2191-
struct mlx5_ib_ucontext *mctx = to_mucontext(context);
2192-
struct mlx5_ib_dev *dev = to_mdev(context->device);
2193-
u16 page_idx = get_extended_index(vma->vm_pgoff);
2194-
size_t map_size = vma->vm_end - vma->vm_start;
2195-
u32 npages = map_size >> PAGE_SHIFT;
2235+
struct mlx5_user_mmap_entry *mentry;
2236+
struct rdma_user_mmap_entry *entry;
2237+
unsigned long pgoff;
2238+
pgprot_t prot;
21962239
phys_addr_t pfn;
2240+
int ret;
21972241

2198-
if (find_next_zero_bit(mctx->dm_pages, page_idx + npages, page_idx) !=
2199-
page_idx + npages)
2242+
pgoff = mlx5_vma_to_pgoff(vma);
2243+
entry = rdma_user_mmap_entry_get_pgoff(ucontext, pgoff);
2244+
if (!entry)
22002245
return -EINVAL;
22012246

2202-
pfn = ((dev->mdev->bar_addr +
2203-
MLX5_CAP64_DEV_MEM(dev->mdev, memic_bar_start_addr)) >>
2204-
PAGE_SHIFT) +
2205-
page_idx;
2206-
return rdma_user_mmap_io(context, vma, pfn, map_size,
2207-
pgprot_writecombine(vma->vm_page_prot),
2208-
NULL);
2247+
mentry = to_mmmap(entry);
2248+
pfn = (mentry->address >> PAGE_SHIFT);
2249+
prot = pgprot_writecombine(vma->vm_page_prot);
2250+
ret = rdma_user_mmap_io(ucontext, vma, pfn,
2251+
entry->npages * PAGE_SIZE,
2252+
prot,
2253+
entry);
2254+
rdma_user_mmap_entry_put(&mentry->rdma_entry);
2255+
return ret;
22092256
}
22102257

22112258
static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
@@ -2248,11 +2295,8 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
22482295
case MLX5_IB_MMAP_CLOCK_INFO:
22492296
return mlx5_ib_mmap_clock_info_page(dev, vma, context);
22502297

2251-
case MLX5_IB_MMAP_DEVICE_MEM:
2252-
return dm_mmap(ibcontext, vma);
2253-
22542298
default:
2255-
return -EINVAL;
2299+
return mlx5_ib_mmap_offset(dev, vma, ibcontext);
22562300
}
22572301

22582302
return 0;
@@ -2288,8 +2332,9 @@ static int handle_alloc_dm_memic(struct ib_ucontext *ctx,
22882332
{
22892333
struct mlx5_dm *dm_db = &to_mdev(ctx->device)->dm;
22902334
u64 start_offset;
2291-
u32 page_idx;
2335+
u16 page_idx;
22922336
int err;
2337+
u64 address;
22932338

22942339
dm->size = roundup(attr->length, MLX5_MEMIC_BASE_SIZE);
22952340

@@ -2298,28 +2343,30 @@ static int handle_alloc_dm_memic(struct ib_ucontext *ctx,
22982343
if (err)
22992344
return err;
23002345

2301-
page_idx = (dm->dev_addr - pci_resource_start(dm_db->dev->pdev, 0) -
2302-
MLX5_CAP64_DEV_MEM(dm_db->dev, memic_bar_start_addr)) >>
2303-
PAGE_SHIFT;
2346+
address = dm->dev_addr & PAGE_MASK;
2347+
err = add_dm_mmap_entry(ctx, dm, address);
2348+
if (err)
2349+
goto err_dealloc;
23042350

2351+
page_idx = dm->mentry.rdma_entry.start_pgoff & 0xFFFF;
23052352
err = uverbs_copy_to(attrs,
23062353
MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
2307-
&page_idx, sizeof(page_idx));
2354+
&page_idx,
2355+
sizeof(page_idx));
23082356
if (err)
2309-
goto err_dealloc;
2357+
goto err_copy;
23102358

23112359
start_offset = dm->dev_addr & ~PAGE_MASK;
23122360
err = uverbs_copy_to(attrs,
23132361
MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET,
23142362
&start_offset, sizeof(start_offset));
23152363
if (err)
2316-
goto err_dealloc;
2317-
2318-
bitmap_set(to_mucontext(ctx)->dm_pages, page_idx,
2319-
DIV_ROUND_UP(dm->size, PAGE_SIZE));
2364+
goto err_copy;
23202365

23212366
return 0;
23222367

2368+
err_copy:
2369+
rdma_user_mmap_entry_remove(&dm->mentry.rdma_entry);
23232370
err_dealloc:
23242371
mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
23252372

@@ -2423,23 +2470,13 @@ int mlx5_ib_dealloc_dm(struct ib_dm *ibdm, struct uverbs_attr_bundle *attrs)
24232470
struct mlx5_ib_ucontext *ctx = rdma_udata_to_drv_context(
24242471
&attrs->driver_udata, struct mlx5_ib_ucontext, ibucontext);
24252472
struct mlx5_core_dev *dev = to_mdev(ibdm->device)->mdev;
2426-
struct mlx5_dm *dm_db = &to_mdev(ibdm->device)->dm;
24272473
struct mlx5_ib_dm *dm = to_mdm(ibdm);
2428-
u32 page_idx;
24292474
int ret;
24302475

24312476
switch (dm->type) {
24322477
case MLX5_IB_UAPI_DM_TYPE_MEMIC:
2433-
ret = mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
2434-
if (ret)
2435-
return ret;
2436-
2437-
page_idx = (dm->dev_addr - pci_resource_start(dev->pdev, 0) -
2438-
MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr)) >>
2439-
PAGE_SHIFT;
2440-
bitmap_clear(ctx->dm_pages, page_idx,
2441-
DIV_ROUND_UP(dm->size, PAGE_SIZE));
2442-
break;
2478+
rdma_user_mmap_entry_remove(&dm->mentry.rdma_entry);
2479+
return 0;
24432480
case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM:
24442481
ret = mlx5_dm_sw_icm_dealloc(dev, MLX5_SW_ICM_TYPE_STEERING,
24452482
dm->size, ctx->devx_uid, dm->dev_addr,
@@ -3544,10 +3581,6 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
35443581
}
35453582

35463583
INIT_LIST_HEAD(&handler->list);
3547-
if (dst) {
3548-
memcpy(&dest_arr[0], dst, sizeof(*dst));
3549-
dest_num++;
3550-
}
35513584

35523585
for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
35533586
err = parse_flow_attr(dev->mdev, spec,
@@ -3560,6 +3593,11 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
35603593
ib_flow += ((union ib_flow_spec *)ib_flow)->size;
35613594
}
35623595

3596+
if (dst && !(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP)) {
3597+
memcpy(&dest_arr[0], dst, sizeof(*dst));
3598+
dest_num++;
3599+
}
3600+
35633601
if (!flow_is_multicast_only(flow_attr))
35643602
set_underlay_qp(dev, spec, underlay_qpn);
35653603

@@ -3600,10 +3638,8 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
36003638
}
36013639

36023640
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
3603-
if (!(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT)) {
3641+
if (!dest_num)
36043642
rule_dst = NULL;
3605-
dest_num = 0;
3606-
}
36073643
} else {
36083644
if (is_egress)
36093645
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
@@ -6236,6 +6272,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
62366272
.map_mr_sg = mlx5_ib_map_mr_sg,
62376273
.map_mr_sg_pi = mlx5_ib_map_mr_sg_pi,
62386274
.mmap = mlx5_ib_mmap,
6275+
.mmap_free = mlx5_ib_mmap_free,
62396276
.modify_cq = mlx5_ib_modify_cq,
62406277
.modify_device = mlx5_ib_modify_device,
62416278
.modify_port = mlx5_ib_modify_port,

0 commit comments

Comments
 (0)