@@ -49,17 +49,18 @@ static void populate_mtts(struct mlx5_vdpa_direct_mr *mr, __be64 *mtt)
4949 }
5050}
5151
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 )
5361{
54- int inlen ;
62+ void * in = & mem -> in ;
5563 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 ;
6364
6465 MLX5_SET (create_mkey_in , in , uid , mvdev -> res .uid );
6566 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
7677 MLX5_SET (create_mkey_in , in , translations_octword_actual_size ,
7778 get_octo_len (mr -> end - mr -> start , mr -> log_size ));
7879 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- }
8580
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 );
8792}
8893
8994static void destroy_direct_mr (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_direct_mr * mr )
9095{
96+ if (!mr -> mr )
97+ return ;
98+
9199 mlx5_vdpa_destroy_mkey (mvdev , mr -> mr );
92100}
93101
@@ -179,6 +187,76 @@ static int klm_byte_size(int nklms)
179187 return 16 * ALIGN (nklms , 4 );
180188}
181189
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+
182260static int create_indirect_key (struct mlx5_vdpa_dev * mvdev , struct mlx5_vdpa_mr * mr )
183261{
184262 int inlen ;
@@ -279,14 +357,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
279357 goto err_map ;
280358 }
281359
282- err = create_direct_mr (mvdev , mr );
283- if (err )
284- goto err_direct ;
285-
286360 return 0 ;
287361
288- err_direct :
289- dma_unmap_sg_attrs (dma , mr -> sg_head .sgl , mr -> nsg , DMA_BIDIRECTIONAL , 0 );
290362err_map :
291363 sg_free_table (& mr -> sg_head );
292364 return err ;
@@ -401,6 +473,10 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
401473 if (err )
402474 goto err_chain ;
403475
476+ err = create_direct_keys (mvdev , mr );
477+ if (err )
478+ goto err_chain ;
479+
404480 /* Create the memory key that defines the guests's address space. This
405481 * memory key refers to the direct keys that contain the MTT
406482 * translations
0 commit comments