@@ -1184,40 +1184,87 @@ struct mlx5_virtq_attr {
1184
1184
u16 used_index ;
1185
1185
};
1186
1186
1187
- static int query_virtqueue (struct mlx5_vdpa_net * ndev , struct mlx5_vdpa_virtqueue * mvq ,
1188
- struct mlx5_virtq_attr * attr )
1189
- {
1190
- int outlen = MLX5_ST_SZ_BYTES (query_virtio_net_q_out );
1191
- u32 in [MLX5_ST_SZ_DW (query_virtio_net_q_in )] = {};
1192
- void * out ;
1193
- void * obj_context ;
1194
- void * cmd_hdr ;
1195
- int err ;
1196
-
1197
- out = kzalloc (outlen , GFP_KERNEL );
1198
- if (!out )
1199
- return - ENOMEM ;
1187
+ struct mlx5_virtqueue_query_mem {
1188
+ u8 in [MLX5_ST_SZ_BYTES (query_virtio_net_q_in )];
1189
+ u8 out [MLX5_ST_SZ_BYTES (query_virtio_net_q_out )];
1190
+ };
1200
1191
1201
- cmd_hdr = MLX5_ADDR_OF (query_virtio_net_q_in , in , general_obj_in_cmd_hdr );
1192
+ static void fill_query_virtqueue_cmd (struct mlx5_vdpa_net * ndev ,
1193
+ struct mlx5_vdpa_virtqueue * mvq ,
1194
+ struct mlx5_virtqueue_query_mem * cmd )
1195
+ {
1196
+ void * cmd_hdr = MLX5_ADDR_OF (query_virtio_net_q_in , cmd -> in , general_obj_in_cmd_hdr );
1202
1197
1203
1198
MLX5_SET (general_obj_in_cmd_hdr , cmd_hdr , opcode , MLX5_CMD_OP_QUERY_GENERAL_OBJECT );
1204
1199
MLX5_SET (general_obj_in_cmd_hdr , cmd_hdr , obj_type , MLX5_OBJ_TYPE_VIRTIO_NET_Q );
1205
1200
MLX5_SET (general_obj_in_cmd_hdr , cmd_hdr , obj_id , mvq -> virtq_id );
1206
1201
MLX5_SET (general_obj_in_cmd_hdr , cmd_hdr , uid , ndev -> mvdev .res .uid );
1207
- err = mlx5_cmd_exec (ndev -> mvdev .mdev , in , sizeof (in ), out , outlen );
1208
- if (err )
1209
- goto err_cmd ;
1202
+ }
1203
+
1204
+ static void query_virtqueue_end (struct mlx5_vdpa_net * ndev ,
1205
+ struct mlx5_virtqueue_query_mem * cmd ,
1206
+ struct mlx5_virtq_attr * attr )
1207
+ {
1208
+ void * obj_context = MLX5_ADDR_OF (query_virtio_net_q_out , cmd -> out , obj_context );
1210
1209
1211
- obj_context = MLX5_ADDR_OF (query_virtio_net_q_out , out , obj_context );
1212
1210
memset (attr , 0 , sizeof (* attr ));
1213
1211
attr -> state = MLX5_GET (virtio_net_q_object , obj_context , state );
1214
1212
attr -> available_index = MLX5_GET (virtio_net_q_object , obj_context , hw_available_index );
1215
1213
attr -> used_index = MLX5_GET (virtio_net_q_object , obj_context , hw_used_index );
1216
- kfree (out );
1217
- return 0 ;
1214
+ }
1218
1215
1219
- err_cmd :
1220
- kfree (out );
1216
+ static int query_virtqueues (struct mlx5_vdpa_net * ndev ,
1217
+ int start_vq ,
1218
+ int num_vqs ,
1219
+ struct mlx5_virtq_attr * attrs )
1220
+ {
1221
+ struct mlx5_vdpa_dev * mvdev = & ndev -> mvdev ;
1222
+ struct mlx5_virtqueue_query_mem * cmd_mem ;
1223
+ struct mlx5_vdpa_async_cmd * cmds ;
1224
+ int err = 0 ;
1225
+
1226
+ WARN (start_vq + num_vqs > mvdev -> max_vqs , "query vq range invalid [%d, %d), max_vqs: %u\n" ,
1227
+ start_vq , start_vq + num_vqs , mvdev -> max_vqs );
1228
+
1229
+ cmds = kvcalloc (num_vqs , sizeof (* cmds ), GFP_KERNEL );
1230
+ cmd_mem = kvcalloc (num_vqs , sizeof (* cmd_mem ), GFP_KERNEL );
1231
+ if (!cmds || !cmd_mem ) {
1232
+ err = - ENOMEM ;
1233
+ goto done ;
1234
+ }
1235
+
1236
+ for (int i = 0 ; i < num_vqs ; i ++ ) {
1237
+ cmds [i ].in = & cmd_mem [i ].in ;
1238
+ cmds [i ].inlen = sizeof (cmd_mem [i ].in );
1239
+ cmds [i ].out = & cmd_mem [i ].out ;
1240
+ cmds [i ].outlen = sizeof (cmd_mem [i ].out );
1241
+ fill_query_virtqueue_cmd (ndev , & ndev -> vqs [start_vq + i ], & cmd_mem [i ]);
1242
+ }
1243
+
1244
+ err = mlx5_vdpa_exec_async_cmds (& ndev -> mvdev , cmds , num_vqs );
1245
+ if (err ) {
1246
+ mlx5_vdpa_err (mvdev , "error issuing query cmd for vq range [%d, %d): %d\n" ,
1247
+ start_vq , start_vq + num_vqs , err );
1248
+ goto done ;
1249
+ }
1250
+
1251
+ for (int i = 0 ; i < num_vqs ; i ++ ) {
1252
+ struct mlx5_vdpa_async_cmd * cmd = & cmds [i ];
1253
+ int vq_idx = start_vq + i ;
1254
+
1255
+ if (cmd -> err ) {
1256
+ mlx5_vdpa_err (mvdev , "query vq %d failed, err: %d\n" , vq_idx , err );
1257
+ if (!err )
1258
+ err = cmd -> err ;
1259
+ continue ;
1260
+ }
1261
+
1262
+ query_virtqueue_end (ndev , & cmd_mem [i ], & attrs [i ]);
1263
+ }
1264
+
1265
+ done :
1266
+ kvfree (cmd_mem );
1267
+ kvfree (cmds );
1221
1268
return err ;
1222
1269
}
1223
1270
@@ -1542,7 +1589,7 @@ static int suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mv
1542
1589
return err ;
1543
1590
}
1544
1591
1545
- err = query_virtqueue (ndev , mvq , & attr );
1592
+ err = query_virtqueues (ndev , mvq -> index , 1 , & attr );
1546
1593
if (err ) {
1547
1594
mlx5_vdpa_err (& ndev -> mvdev , "failed to query virtqueue, err: %d\n" , err );
1548
1595
return err ;
@@ -2528,7 +2575,7 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa
2528
2575
return 0 ;
2529
2576
}
2530
2577
2531
- err = query_virtqueue (ndev , mvq , & attr );
2578
+ err = query_virtqueues (ndev , mvq -> index , 1 , & attr );
2532
2579
if (err ) {
2533
2580
mlx5_vdpa_err (mvdev , "failed to query virtqueue\n" );
2534
2581
return err ;
@@ -2879,7 +2926,7 @@ static int save_channel_info(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqu
2879
2926
int err ;
2880
2927
2881
2928
if (mvq -> initialized ) {
2882
- err = query_virtqueue (ndev , mvq , & attr );
2929
+ err = query_virtqueues (ndev , mvq -> index , 1 , & attr );
2883
2930
if (err )
2884
2931
return err ;
2885
2932
}
@@ -3854,6 +3901,8 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
3854
3901
ndev -> rqt_size = 1 ;
3855
3902
}
3856
3903
3904
+ mlx5_cmd_init_async_ctx (mdev , & mvdev -> async_ctx );
3905
+
3857
3906
ndev -> mvdev .mlx_features = device_features ;
3858
3907
mvdev -> vdev .dma_dev = & mdev -> pdev -> dev ;
3859
3908
err = mlx5_vdpa_alloc_resources (& ndev -> mvdev );
@@ -3935,6 +3984,8 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *
3935
3984
mvdev -> wq = NULL ;
3936
3985
destroy_workqueue (wq );
3937
3986
mgtdev -> ndev = NULL ;
3987
+
3988
+ mlx5_cmd_cleanup_async_ctx (& mvdev -> async_ctx );
3938
3989
}
3939
3990
3940
3991
static int mlx5_vdpa_set_attr (struct vdpa_mgmt_dev * v_mdev , struct vdpa_device * dev ,
0 commit comments