@@ -49,17 +49,18 @@ static void populate_mtts(struct mlx5_vdpa_direct_mr *mr, __be64 *mtt)
49
49
}
50
50
}
51
51
52
- static int create_direct_mr (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_direct_mr * mr )
52
+ struct mlx5_create_mkey_mem {
53
+ u8 out [MLX5_ST_SZ_BYTES (create_mkey_out )];
54
+ u8 in [MLX5_ST_SZ_BYTES (create_mkey_in )];
55
+ __be64 mtt [];
56
+ };
57
+
58
+ static void fill_create_direct_mr (struct mlx5_vdpa_dev * mvdev ,
59
+ struct mlx5_vdpa_direct_mr * mr ,
60
+ struct mlx5_create_mkey_mem * mem )
53
61
{
54
- int inlen ;
62
+ void * in = & mem -> in ;
55
63
void * mkc ;
56
- void * in ;
57
- int err ;
58
-
59
- inlen = MLX5_ST_SZ_BYTES (create_mkey_in ) + roundup (MLX5_ST_SZ_BYTES (mtt ) * mr -> nsg , 16 );
60
- in = kvzalloc (inlen , GFP_KERNEL );
61
- if (!in )
62
- return - ENOMEM ;
63
64
64
65
MLX5_SET (create_mkey_in , in , uid , mvdev -> res .uid );
65
66
mkc = MLX5_ADDR_OF (create_mkey_in , in , memory_key_mkey_entry );
@@ -76,18 +77,25 @@ static int create_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct
76
77
MLX5_SET (create_mkey_in , in , translations_octword_actual_size ,
77
78
get_octo_len (mr -> end - mr -> start , mr -> log_size ));
78
79
populate_mtts (mr , MLX5_ADDR_OF (create_mkey_in , in , klm_pas_mtt ));
79
- err = mlx5_vdpa_create_mkey (mvdev , & mr -> mr , in , inlen );
80
- kvfree (in );
81
- if (err ) {
82
- mlx5_vdpa_warn (mvdev , "Failed to create direct MR\n" );
83
- return err ;
84
- }
85
80
86
- return 0 ;
81
+ MLX5_SET (create_mkey_in , in , opcode , MLX5_CMD_OP_CREATE_MKEY );
82
+ MLX5_SET (create_mkey_in , in , uid , mvdev -> res .uid );
83
+ }
84
+
85
+ static void create_direct_mr_end (struct mlx5_vdpa_dev * mvdev ,
86
+ struct mlx5_vdpa_direct_mr * mr ,
87
+ struct mlx5_create_mkey_mem * mem )
88
+ {
89
+ u32 mkey_index = MLX5_GET (create_mkey_out , mem -> out , mkey_index );
90
+
91
+ mr -> mr = mlx5_idx_to_mkey (mkey_index );
87
92
}
88
93
89
94
static void destroy_direct_mr (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_direct_mr * mr )
90
95
{
96
+ if (!mr -> mr )
97
+ return ;
98
+
91
99
mlx5_vdpa_destroy_mkey (mvdev , mr -> mr );
92
100
}
93
101
@@ -179,6 +187,76 @@ static int klm_byte_size(int nklms)
179
187
return 16 * ALIGN (nklms , 4 );
180
188
}
181
189
190
+ #define MLX5_VDPA_MTT_ALIGN 16
191
+
192
+ static int create_direct_keys (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_mr * mr )
193
+ {
194
+ struct mlx5_vdpa_async_cmd * cmds ;
195
+ struct mlx5_vdpa_direct_mr * dmr ;
196
+ int err = 0 ;
197
+ int i = 0 ;
198
+
199
+ cmds = kvcalloc (mr -> num_directs , sizeof (* cmds ), GFP_KERNEL );
200
+ if (!cmds )
201
+ return - ENOMEM ;
202
+
203
+ list_for_each_entry (dmr , & mr -> head , list ) {
204
+ struct mlx5_create_mkey_mem * cmd_mem ;
205
+ int mttlen , mttcount ;
206
+
207
+ mttlen = roundup (MLX5_ST_SZ_BYTES (mtt ) * dmr -> nsg , MLX5_VDPA_MTT_ALIGN );
208
+ mttcount = mttlen / sizeof (cmd_mem -> mtt [0 ]);
209
+ cmd_mem = kvcalloc (1 , struct_size (cmd_mem , mtt , mttcount ), GFP_KERNEL );
210
+ if (!cmd_mem ) {
211
+ err = - ENOMEM ;
212
+ goto done ;
213
+ }
214
+
215
+ cmds [i ].out = cmd_mem -> out ;
216
+ cmds [i ].outlen = sizeof (cmd_mem -> out );
217
+ cmds [i ].in = cmd_mem -> in ;
218
+ cmds [i ].inlen = struct_size (cmd_mem , mtt , mttcount );
219
+
220
+ fill_create_direct_mr (mvdev , dmr , cmd_mem );
221
+
222
+ i ++ ;
223
+ }
224
+
225
+ err = mlx5_vdpa_exec_async_cmds (mvdev , cmds , mr -> num_directs );
226
+ if (err ) {
227
+
228
+ mlx5_vdpa_err (mvdev , "error issuing MTT mkey creation for direct mrs: %d\n" , err );
229
+ goto done ;
230
+ }
231
+
232
+ i = 0 ;
233
+ list_for_each_entry (dmr , & mr -> head , list ) {
234
+ struct mlx5_vdpa_async_cmd * cmd = & cmds [i ++ ];
235
+ struct mlx5_create_mkey_mem * cmd_mem ;
236
+
237
+ cmd_mem = container_of (cmd -> out , struct mlx5_create_mkey_mem , out );
238
+
239
+ if (!cmd -> err ) {
240
+ create_direct_mr_end (mvdev , dmr , cmd_mem );
241
+ } else {
242
+ err = err ? err : cmd -> err ;
243
+ mlx5_vdpa_err (mvdev , "error creating MTT mkey [0x%llx, 0x%llx]: %d\n" ,
244
+ dmr -> start , dmr -> end , cmd -> err );
245
+ }
246
+ }
247
+
248
+ done :
249
+ for (i = i - 1 ; i >= 0 ; i -- ) {
250
+ struct mlx5_create_mkey_mem * cmd_mem ;
251
+
252
+ cmd_mem = container_of (cmds [i ].out , struct mlx5_create_mkey_mem , out );
253
+ kvfree (cmd_mem );
254
+ }
255
+
256
+ kvfree (cmds );
257
+ return err ;
258
+ }
259
+
182
260
static int create_indirect_key (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_mr * mr )
183
261
{
184
262
int inlen ;
@@ -279,14 +357,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
279
357
goto err_map ;
280
358
}
281
359
282
- err = create_direct_mr (mvdev , mr );
283
- if (err )
284
- goto err_direct ;
285
-
286
360
return 0 ;
287
361
288
- err_direct :
289
- dma_unmap_sg_attrs (dma , mr -> sg_head .sgl , mr -> nsg , DMA_BIDIRECTIONAL , 0 );
290
362
err_map :
291
363
sg_free_table (& mr -> sg_head );
292
364
return err ;
@@ -401,6 +473,10 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
401
473
if (err )
402
474
goto err_chain ;
403
475
476
+ err = create_direct_keys (mvdev , mr );
477
+ if (err )
478
+ goto err_chain ;
479
+
404
480
/* Create the memory key that defines the guests's address space. This
405
481
* memory key refers to the direct keys that contain the MTT
406
482
* translations
0 commit comments