@@ -163,6 +163,7 @@ struct mlx5_vdpa_net {
163163 u32 cur_num_vqs ;
164164 struct notifier_block nb ;
165165 struct vdpa_callback config_cb ;
166+ struct mlx5_vdpa_wq_ent cvq_ent ;
166167};
167168
168169static void free_resources (struct mlx5_vdpa_net * ndev );
@@ -1658,6 +1659,12 @@ static void mlx5_cvq_kick_handler(struct work_struct *work)
16581659 mvdev = wqent -> mvdev ;
16591660 ndev = to_mlx5_vdpa_ndev (mvdev );
16601661 cvq = & mvdev -> cvq ;
1662+
1663+ mutex_lock (& ndev -> reslock );
1664+
1665+ if (!(mvdev -> status & VIRTIO_CONFIG_S_DRIVER_OK ))
1666+ goto out ;
1667+
16611668 if (!(ndev -> mvdev .actual_features & BIT_ULL (VIRTIO_NET_F_CTRL_VQ )))
16621669 goto out ;
16631670
@@ -1696,17 +1703,20 @@ static void mlx5_cvq_kick_handler(struct work_struct *work)
16961703
16971704 if (vringh_need_notify_iotlb (& cvq -> vring ))
16981705 vringh_notify (& cvq -> vring );
1706+
1707+ queue_work (mvdev -> wq , & wqent -> work );
1708+ break ;
16991709 }
1710+
17001711out :
1701- kfree ( wqent );
1712+ mutex_unlock ( & ndev -> reslock );
17021713}
17031714
17041715static void mlx5_vdpa_kick_vq (struct vdpa_device * vdev , u16 idx )
17051716{
17061717 struct mlx5_vdpa_dev * mvdev = to_mvdev (vdev );
17071718 struct mlx5_vdpa_net * ndev = to_mlx5_vdpa_ndev (mvdev );
17081719 struct mlx5_vdpa_virtqueue * mvq ;
1709- struct mlx5_vdpa_wq_ent * wqent ;
17101720
17111721 if (!is_index_valid (mvdev , idx ))
17121722 return ;
@@ -1715,13 +1725,7 @@ static void mlx5_vdpa_kick_vq(struct vdpa_device *vdev, u16 idx)
17151725 if (!mvdev -> wq || !mvdev -> cvq .ready )
17161726 return ;
17171727
1718- wqent = kzalloc (sizeof (* wqent ), GFP_ATOMIC );
1719- if (!wqent )
1720- return ;
1721-
1722- wqent -> mvdev = mvdev ;
1723- INIT_WORK (& wqent -> work , mlx5_cvq_kick_handler );
1724- queue_work (mvdev -> wq , & wqent -> work );
1728+ queue_work (mvdev -> wq , & ndev -> cvq_ent .work );
17251729 return ;
17261730 }
17271731
@@ -2180,7 +2184,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
21802184 goto err_mr ;
21812185
21822186 if (!(mvdev -> status & VIRTIO_CONFIG_S_DRIVER_OK ))
2183- return 0 ;
2187+ goto err_mr ;
21842188
21852189 restore_channels_info (ndev );
21862190 err = setup_driver (mvdev );
@@ -2195,12 +2199,14 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
21952199 return err ;
21962200}
21972201
2202+ /* reslock must be held for this function */
21982203static int setup_driver (struct mlx5_vdpa_dev * mvdev )
21992204{
22002205 struct mlx5_vdpa_net * ndev = to_mlx5_vdpa_ndev (mvdev );
22012206 int err ;
22022207
2203- mutex_lock (& ndev -> reslock );
2208+ WARN_ON (!mutex_is_locked (& ndev -> reslock ));
2209+
22042210 if (ndev -> setup ) {
22052211 mlx5_vdpa_warn (mvdev , "setup driver called for already setup driver\n" );
22062212 err = 0 ;
@@ -2230,7 +2236,6 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
22302236 goto err_fwd ;
22312237 }
22322238 ndev -> setup = true;
2233- mutex_unlock (& ndev -> reslock );
22342239
22352240 return 0 ;
22362241
@@ -2241,23 +2246,23 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
22412246err_rqt :
22422247 teardown_virtqueues (ndev );
22432248out :
2244- mutex_unlock (& ndev -> reslock );
22452249 return err ;
22462250}
22472251
2252+ /* reslock must be held for this function */
22482253static void teardown_driver (struct mlx5_vdpa_net * ndev )
22492254{
2250- mutex_lock (& ndev -> reslock );
2255+
2256+ WARN_ON (!mutex_is_locked (& ndev -> reslock ));
2257+
22512258 if (!ndev -> setup )
2252- goto out ;
2259+ return ;
22532260
22542261 remove_fwd_to_tir (ndev );
22552262 destroy_tir (ndev );
22562263 destroy_rqt (ndev );
22572264 teardown_virtqueues (ndev );
22582265 ndev -> setup = false;
2259- out :
2260- mutex_unlock (& ndev -> reslock );
22612266}
22622267
22632268static void clear_vqs_ready (struct mlx5_vdpa_net * ndev )
@@ -2278,6 +2283,8 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
22782283
22792284 print_status (mvdev , status , true);
22802285
2286+ mutex_lock (& ndev -> reslock );
2287+
22812288 if ((status ^ ndev -> mvdev .status ) & VIRTIO_CONFIG_S_DRIVER_OK ) {
22822289 if (status & VIRTIO_CONFIG_S_DRIVER_OK ) {
22832290 err = setup_driver (mvdev );
@@ -2287,16 +2294,19 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
22872294 }
22882295 } else {
22892296 mlx5_vdpa_warn (mvdev , "did not expect DRIVER_OK to be cleared\n" );
2290- return ;
2297+ goto err_clear ;
22912298 }
22922299 }
22932300
22942301 ndev -> mvdev .status = status ;
2302+ mutex_unlock (& ndev -> reslock );
22952303 return ;
22962304
22972305err_setup :
22982306 mlx5_vdpa_destroy_mr (& ndev -> mvdev );
22992307 ndev -> mvdev .status |= VIRTIO_CONFIG_S_FAILED ;
2308+ err_clear :
2309+ mutex_unlock (& ndev -> reslock );
23002310}
23012311
23022312static int mlx5_vdpa_reset (struct vdpa_device * vdev )
@@ -2306,6 +2316,8 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
23062316
23072317 print_status (mvdev , 0 , true);
23082318 mlx5_vdpa_info (mvdev , "performing device reset\n" );
2319+
2320+ mutex_lock (& ndev -> reslock );
23092321 teardown_driver (ndev );
23102322 clear_vqs_ready (ndev );
23112323 mlx5_vdpa_destroy_mr (& ndev -> mvdev );
@@ -2318,6 +2330,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
23182330 if (mlx5_vdpa_create_mr (mvdev , NULL ))
23192331 mlx5_vdpa_warn (mvdev , "create MR failed\n" );
23202332 }
2333+ mutex_unlock (& ndev -> reslock );
23212334
23222335 return 0 ;
23232336}
@@ -2353,19 +2366,24 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
23532366static int mlx5_vdpa_set_map (struct vdpa_device * vdev , struct vhost_iotlb * iotlb )
23542367{
23552368 struct mlx5_vdpa_dev * mvdev = to_mvdev (vdev );
2369+ struct mlx5_vdpa_net * ndev = to_mlx5_vdpa_ndev (mvdev );
23562370 bool change_map ;
23572371 int err ;
23582372
2373+ mutex_lock (& ndev -> reslock );
2374+
23592375 err = mlx5_vdpa_handle_set_map (mvdev , iotlb , & change_map );
23602376 if (err ) {
23612377 mlx5_vdpa_warn (mvdev , "set map failed(%d)\n" , err );
2362- return err ;
2378+ goto err ;
23632379 }
23642380
23652381 if (change_map )
2366- return mlx5_vdpa_change_map (mvdev , iotlb );
2382+ err = mlx5_vdpa_change_map (mvdev , iotlb );
23672383
2368- return 0 ;
2384+ err :
2385+ mutex_unlock (& ndev -> reslock );
2386+ return err ;
23692387}
23702388
23712389static void mlx5_vdpa_free (struct vdpa_device * vdev )
@@ -2740,6 +2758,8 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
27402758 if (err )
27412759 goto err_mr ;
27422760
2761+ ndev -> cvq_ent .mvdev = mvdev ;
2762+ INIT_WORK (& ndev -> cvq_ent .work , mlx5_cvq_kick_handler );
27432763 mvdev -> wq = create_singlethread_workqueue ("mlx5_vdpa_wq" );
27442764 if (!mvdev -> wq ) {
27452765 err = - ENOMEM ;
0 commit comments