Skip to content

Commit 3b113a1

Browse files
Awik84jgunthorpe
authored andcommitted
IB/mlx5: Support device memory type attribute
This patch intoruduces a new mlx5_ib driver attribute to the DM allocation method - the DM type. In order to allow addition of new types in downstream patches this patch also refactors the allocation, deallocation and registration handlers to consider the requested type and perform the necessary actions according to it. Since not all future device memory types will be such that are mapped to user memory, the mandatory page index output attribute is modified to be optional. Signed-off-by: Ariel Levkovich <[email protected]> Reviewed-by: Eli Cohen <[email protected]> Reviewed-by: Mark Bloch <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 3a4ef2e commit 3b113a1

File tree

7 files changed

+145
-84
lines changed

7 files changed

+145
-84
lines changed

drivers/infiniband/hw/mlx5/cmd.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *dev,
8282
return mlx5_cmd_exec(dev, in, in_size, out, sizeof(out));
8383
}
8484

85-
int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
86-
u64 length, u32 alignment)
85+
int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
86+
u64 length, u32 alignment)
8787
{
88-
struct mlx5_core_dev *dev = memic->dev;
88+
struct mlx5_core_dev *dev = dm->dev;
8989
u64 num_memic_hw_pages = MLX5_CAP_DEV_MEM(dev, memic_bar_size)
9090
>> PAGE_SHIFT;
9191
u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
@@ -115,17 +115,17 @@ int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
115115
mlx5_alignment);
116116

117117
while (page_idx < num_memic_hw_pages) {
118-
spin_lock(&memic->memic_lock);
119-
page_idx = bitmap_find_next_zero_area(memic->memic_alloc_pages,
118+
spin_lock(&dm->lock);
119+
page_idx = bitmap_find_next_zero_area(dm->memic_alloc_pages,
120120
num_memic_hw_pages,
121121
page_idx,
122122
num_pages, 0);
123123

124124
if (page_idx < num_memic_hw_pages)
125-
bitmap_set(memic->memic_alloc_pages,
125+
bitmap_set(dm->memic_alloc_pages,
126126
page_idx, num_pages);
127127

128-
spin_unlock(&memic->memic_lock);
128+
spin_unlock(&dm->lock);
129129

130130
if (page_idx >= num_memic_hw_pages)
131131
break;
@@ -135,10 +135,10 @@ int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
135135

136136
ret = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
137137
if (ret) {
138-
spin_lock(&memic->memic_lock);
139-
bitmap_clear(memic->memic_alloc_pages,
138+
spin_lock(&dm->lock);
139+
bitmap_clear(dm->memic_alloc_pages,
140140
page_idx, num_pages);
141-
spin_unlock(&memic->memic_lock);
141+
spin_unlock(&dm->lock);
142142

143143
if (ret == -EAGAIN) {
144144
page_idx++;
@@ -157,9 +157,9 @@ int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
157157
return -ENOMEM;
158158
}
159159

160-
int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length)
160+
int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, u64 addr, u64 length)
161161
{
162-
struct mlx5_core_dev *dev = memic->dev;
162+
struct mlx5_core_dev *dev = dm->dev;
163163
u64 hw_start_addr = MLX5_CAP64_DEV_MEM(dev, memic_bar_start_addr);
164164
u32 num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
165165
u32 out[MLX5_ST_SZ_DW(dealloc_memic_out)] = {0};
@@ -177,10 +177,10 @@ int mlx5_cmd_dealloc_memic(struct mlx5_memic *memic, u64 addr, u64 length)
177177
err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
178178

179179
if (!err) {
180-
spin_lock(&memic->memic_lock);
181-
bitmap_clear(memic->memic_alloc_pages,
180+
spin_lock(&dm->lock);
181+
bitmap_clear(dm->memic_alloc_pages,
182182
start_page_idx, num_pages);
183-
spin_unlock(&memic->memic_lock);
183+
spin_unlock(&dm->lock);
184184
}
185185

186186
return err;

drivers/infiniband/hw/mlx5/cmd.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
4444
int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out);
4545
int mlx5_cmd_modify_cong_params(struct mlx5_core_dev *mdev,
4646
void *in, int in_size);
47-
int mlx5_cmd_alloc_memic(struct mlx5_memic *memic, phys_addr_t *addr,
47+
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_memic *memic, u64 addr, u64 length);
49+
int mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, u64 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: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,84 +2264,122 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
22642264
return 0;
22652265
}
22662266

2267-
struct ib_dm *mlx5_ib_alloc_dm(struct ib_device *ibdev,
2268-
struct ib_ucontext *context,
2269-
struct ib_dm_alloc_attr *attr,
2270-
struct uverbs_attr_bundle *attrs)
2267+
static int handle_alloc_dm_memic(struct ib_ucontext *ctx,
2268+
struct mlx5_ib_dm *dm,
2269+
struct ib_dm_alloc_attr *attr,
2270+
struct uverbs_attr_bundle *attrs)
22712271
{
2272-
u64 act_size = roundup(attr->length, MLX5_MEMIC_BASE_SIZE);
2273-
struct mlx5_memic *memic = &to_mdev(ibdev)->memic;
2274-
phys_addr_t memic_addr;
2275-
struct mlx5_ib_dm *dm;
2272+
struct mlx5_dm *dm_db = &to_mdev(ctx->device)->dm;
22762273
u64 start_offset;
22772274
u32 page_idx;
22782275
int err;
22792276

2280-
dm = kzalloc(sizeof(*dm), GFP_KERNEL);
2281-
if (!dm)
2282-
return ERR_PTR(-ENOMEM);
2283-
2284-
mlx5_ib_dbg(to_mdev(ibdev), "alloc_memic req: user_length=0x%llx act_length=0x%llx log_alignment=%d\n",
2285-
attr->length, act_size, attr->alignment);
2277+
dm->size = roundup(attr->length, MLX5_MEMIC_BASE_SIZE);
22862278

2287-
err = mlx5_cmd_alloc_memic(memic, &memic_addr,
2288-
act_size, attr->alignment);
2279+
err = mlx5_cmd_alloc_memic(dm_db, &dm->dev_addr,
2280+
dm->size, attr->alignment);
22892281
if (err)
2290-
goto err_free;
2282+
return err;
22912283

2292-
start_offset = memic_addr & ~PAGE_MASK;
2293-
page_idx = (memic_addr - memic->dev->bar_addr -
2294-
MLX5_CAP64_DEV_MEM(memic->dev, memic_bar_start_addr)) >>
2284+
page_idx = (dm->dev_addr - pci_resource_start(dm_db->dev->pdev, 0) -
2285+
MLX5_CAP64_DEV_MEM(dm_db->dev, memic_bar_start_addr)) >>
22952286
PAGE_SHIFT;
22962287

22972288
err = uverbs_copy_to(attrs,
2298-
MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET,
2299-
&start_offset, sizeof(start_offset));
2289+
MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
2290+
&page_idx, sizeof(page_idx));
23002291
if (err)
23012292
goto err_dealloc;
23022293

2294+
start_offset = dm->dev_addr & ~PAGE_MASK;
23032295
err = uverbs_copy_to(attrs,
2304-
MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
2305-
&page_idx, sizeof(page_idx));
2296+
MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET,
2297+
&start_offset, sizeof(start_offset));
23062298
if (err)
23072299
goto err_dealloc;
23082300

2309-
bitmap_set(to_mucontext(context)->dm_pages, page_idx,
2310-
DIV_ROUND_UP(act_size, PAGE_SIZE));
2301+
bitmap_set(to_mucontext(ctx)->dm_pages, page_idx,
2302+
DIV_ROUND_UP(dm->size, PAGE_SIZE));
2303+
2304+
return 0;
2305+
2306+
err_dealloc:
2307+
mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
2308+
2309+
return err;
2310+
}
2311+
2312+
struct ib_dm *mlx5_ib_alloc_dm(struct ib_device *ibdev,
2313+
struct ib_ucontext *context,
2314+
struct ib_dm_alloc_attr *attr,
2315+
struct uverbs_attr_bundle *attrs)
2316+
{
2317+
struct mlx5_ib_dm *dm;
2318+
enum mlx5_ib_uapi_dm_type type;
2319+
int err;
2320+
2321+
err = uverbs_get_const_default(&type, attrs,
2322+
MLX5_IB_ATTR_ALLOC_DM_REQ_TYPE,
2323+
MLX5_IB_UAPI_DM_TYPE_MEMIC);
2324+
if (err)
2325+
return ERR_PTR(err);
2326+
2327+
mlx5_ib_dbg(to_mdev(ibdev), "alloc_dm req: dm_type=%d user_length=0x%llx log_alignment=%d\n",
2328+
type, attr->length, attr->alignment);
2329+
2330+
dm = kzalloc(sizeof(*dm), GFP_KERNEL);
2331+
if (!dm)
2332+
return ERR_PTR(-ENOMEM);
2333+
2334+
dm->type = type;
2335+
2336+
switch (type) {
2337+
case MLX5_IB_UAPI_DM_TYPE_MEMIC:
2338+
err = handle_alloc_dm_memic(context, dm,
2339+
attr,
2340+
attrs);
2341+
break;
2342+
default:
2343+
err = -EOPNOTSUPP;
2344+
}
23112345

2312-
dm->dev_addr = memic_addr;
2346+
if (err)
2347+
goto err_free;
23132348

23142349
return &dm->ibdm;
23152350

2316-
err_dealloc:
2317-
mlx5_cmd_dealloc_memic(memic, memic_addr,
2318-
act_size);
23192351
err_free:
23202352
kfree(dm);
23212353
return ERR_PTR(err);
23222354
}
23232355

23242356
int mlx5_ib_dealloc_dm(struct ib_dm *ibdm, struct uverbs_attr_bundle *attrs)
23252357
{
2326-
struct mlx5_memic *memic = &to_mdev(ibdm->device)->memic;
2358+
struct mlx5_dm *dm_db = &to_mdev(ibdm->device)->dm;
23272359
struct mlx5_ib_dm *dm = to_mdm(ibdm);
2328-
u64 act_size = roundup(dm->ibdm.length, MLX5_MEMIC_BASE_SIZE);
23292360
u32 page_idx;
23302361
int ret;
23312362

2332-
ret = mlx5_cmd_dealloc_memic(memic, dm->dev_addr, act_size);
2333-
if (ret)
2334-
return ret;
2363+
switch (dm->type) {
2364+
case MLX5_IB_UAPI_DM_TYPE_MEMIC:
2365+
ret = mlx5_cmd_dealloc_memic(dm_db, dm->dev_addr, dm->size);
2366+
if (ret)
2367+
return ret;
23352368

2336-
page_idx = (dm->dev_addr - memic->dev->bar_addr -
2337-
MLX5_CAP64_DEV_MEM(memic->dev, memic_bar_start_addr)) >>
2338-
PAGE_SHIFT;
2339-
bitmap_clear(rdma_udata_to_drv_context(
2340-
&attrs->driver_udata,
2341-
struct mlx5_ib_ucontext,
2342-
ibucontext)->dm_pages,
2343-
page_idx,
2344-
DIV_ROUND_UP(act_size, PAGE_SIZE));
2369+
page_idx = (dm->dev_addr -
2370+
pci_resource_start(dm_db->dev->pdev, 0) -
2371+
MLX5_CAP64_DEV_MEM(dm_db->dev,
2372+
memic_bar_start_addr)) >>
2373+
PAGE_SHIFT;
2374+
bitmap_clear(rdma_udata_to_drv_context(&attrs->driver_udata,
2375+
struct mlx5_ib_ucontext,
2376+
ibucontext)
2377+
->dm_pages,
2378+
page_idx, DIV_ROUND_UP(dm->size, PAGE_SIZE));
2379+
break;
2380+
default:
2381+
return -EOPNOTSUPP;
2382+
}
23452383

23462384
kfree(dm);
23472385

@@ -5768,7 +5806,10 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
57685806
UA_MANDATORY),
57695807
UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
57705808
UVERBS_ATTR_TYPE(u16),
5771-
UA_MANDATORY));
5809+
UA_OPTIONAL),
5810+
UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_ALLOC_DM_REQ_TYPE,
5811+
enum mlx5_ib_uapi_dm_type,
5812+
UA_OPTIONAL));
57725813

57735814
ADD_UVERBS_ATTRIBUTES_SIMPLE(
57745815
mlx5_ib_flow_action,
@@ -5916,8 +5957,8 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
59165957
INIT_LIST_HEAD(&dev->qp_list);
59175958
spin_lock_init(&dev->reset_flow_resource_lock);
59185959

5919-
spin_lock_init(&dev->memic.memic_lock);
5920-
dev->memic.dev = mdev;
5960+
spin_lock_init(&dev->dm.lock);
5961+
dev->dm.dev = mdev;
59215962

59225963
if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) {
59235964
err = init_srcu_struct(&dev->mr_srcu);

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <rdma/mlx5-abi.h>
4949
#include <rdma/uverbs_ioctl.h>
5050
#include <rdma/mlx5_user_ioctl_cmds.h>
51+
#include <rdma/mlx5_user_ioctl_verbs.h>
5152

5253
#include "srq.h"
5354

@@ -554,15 +555,17 @@ enum mlx5_ib_mtt_access_flags {
554555
struct mlx5_ib_dm {
555556
struct ib_dm ibdm;
556557
phys_addr_t dev_addr;
558+
u32 type;
559+
size_t size;
557560
};
558561

559562
#define MLX5_IB_MTT_PRESENT (MLX5_IB_MTT_READ | MLX5_IB_MTT_WRITE)
560563

561-
#define MLX5_IB_DM_ALLOWED_ACCESS (IB_ACCESS_LOCAL_WRITE |\
562-
IB_ACCESS_REMOTE_WRITE |\
563-
IB_ACCESS_REMOTE_READ |\
564-
IB_ACCESS_REMOTE_ATOMIC |\
565-
IB_ZERO_BASED)
564+
#define MLX5_IB_DM_MEMIC_ALLOWED_ACCESS (IB_ACCESS_LOCAL_WRITE |\
565+
IB_ACCESS_REMOTE_WRITE |\
566+
IB_ACCESS_REMOTE_READ |\
567+
IB_ACCESS_REMOTE_ATOMIC |\
568+
IB_ZERO_BASED)
566569

567570
struct mlx5_ib_mr {
568571
struct ib_mr ibmr;
@@ -843,9 +846,13 @@ struct mlx5_ib_flow_action {
843846
};
844847
};
845848

846-
struct mlx5_memic {
849+
struct mlx5_dm {
847850
struct mlx5_core_dev *dev;
848-
spinlock_t memic_lock;
851+
/* This lock is used to protect the access to the shared
852+
* allocation map when concurrent requests by different
853+
* processes are handled.
854+
*/
855+
spinlock_t lock;
849856
DECLARE_BITMAP(memic_alloc_pages, MLX5_MAX_MEMIC_PAGES);
850857
};
851858

@@ -949,7 +956,7 @@ struct mlx5_ib_dev {
949956
u8 umr_fence;
950957
struct list_head ib_dev_list;
951958
u64 sys_image_guid;
952-
struct mlx5_memic memic;
959+
struct mlx5_dm dm;
953960
u16 devx_whitelist_uid;
954961
struct mlx5_srq_table srq_table;
955962
struct mlx5_async_ctx async_ctx;

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,8 +1159,8 @@ static void set_mr_fields(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr,
11591159
mr->access_flags = access_flags;
11601160
}
11611161

1162-
static struct ib_mr *mlx5_ib_get_memic_mr(struct ib_pd *pd, u64 memic_addr,
1163-
u64 length, int acc)
1162+
static struct ib_mr *mlx5_ib_get_dm_mr(struct ib_pd *pd, u64 start_addr,
1163+
u64 length, int acc, int mode)
11641164
{
11651165
struct mlx5_ib_dev *dev = to_mdev(pd->device);
11661166
int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
@@ -1182,9 +1182,8 @@ static struct ib_mr *mlx5_ib_get_memic_mr(struct ib_pd *pd, u64 memic_addr,
11821182

11831183
mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
11841184

1185-
MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MEMIC & 0x3);
1186-
MLX5_SET(mkc, mkc, access_mode_4_2,
1187-
(MLX5_MKC_ACCESS_MODE_MEMIC >> 2) & 0x7);
1185+
MLX5_SET(mkc, mkc, access_mode_1_0, mode & 0x3);
1186+
MLX5_SET(mkc, mkc, access_mode_4_2, (mode >> 2) & 0x7);
11881187
MLX5_SET(mkc, mkc, a, !!(acc & IB_ACCESS_REMOTE_ATOMIC));
11891188
MLX5_SET(mkc, mkc, rw, !!(acc & IB_ACCESS_REMOTE_WRITE));
11901189
MLX5_SET(mkc, mkc, rr, !!(acc & IB_ACCESS_REMOTE_READ));
@@ -1194,7 +1193,7 @@ static struct ib_mr *mlx5_ib_get_memic_mr(struct ib_pd *pd, u64 memic_addr,
11941193
MLX5_SET64(mkc, mkc, len, length);
11951194
MLX5_SET(mkc, mkc, pd, to_mpd(pd)->pdn);
11961195
MLX5_SET(mkc, mkc, qpn, 0xffffff);
1197-
MLX5_SET64(mkc, mkc, start_addr, memic_addr - dev->mdev->bar_addr);
1196+
MLX5_SET64(mkc, mkc, start_addr, start_addr);
11981197

11991198
err = mlx5_core_create_mkey(mdev, &mr->mmkey, in, inlen);
12001199
if (err)
@@ -1236,15 +1235,24 @@ struct ib_mr *mlx5_ib_reg_dm_mr(struct ib_pd *pd, struct ib_dm *dm,
12361235
struct uverbs_attr_bundle *attrs)
12371236
{
12381237
struct mlx5_ib_dm *mdm = to_mdm(dm);
1239-
u64 memic_addr;
1238+
struct mlx5_core_dev *dev = to_mdev(dm->device)->mdev;
1239+
u64 start_addr = mdm->dev_addr + attr->offset;
1240+
int mode;
12401241

1241-
if (attr->access_flags & ~MLX5_IB_DM_ALLOWED_ACCESS)
1242-
return ERR_PTR(-EINVAL);
1242+
switch (mdm->type) {
1243+
case MLX5_IB_UAPI_DM_TYPE_MEMIC:
1244+
if (attr->access_flags & ~MLX5_IB_DM_MEMIC_ALLOWED_ACCESS)
1245+
return ERR_PTR(-EINVAL);
12431246

1244-
memic_addr = mdm->dev_addr + attr->offset;
1247+
mode = MLX5_MKC_ACCESS_MODE_MEMIC;
1248+
start_addr -= pci_resource_start(dev->pdev, 0);
1249+
break;
1250+
default:
1251+
return ERR_PTR(-EINVAL);
1252+
}
12451253

1246-
return mlx5_ib_get_memic_mr(pd, memic_addr, attr->length,
1247-
attr->access_flags);
1254+
return mlx5_ib_get_dm_mr(pd, start_addr, attr->length,
1255+
attr->access_flags, mode);
12481256
}
12491257

12501258
struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,

0 commit comments

Comments
 (0)