Skip to content

Commit 3e732eb

Browse files
committed
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio fixes from Michael Tsirkin: "Fixes and cleanups: - A couple of mlx5 fixes related to cvq - A couple of reverts dropping useless code (code that used it got reverted earlier)" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: vdpa: mlx5: synchronize driver status with CVQ vdpa: mlx5: prevent cvq work from hogging CPU Revert "virtio_config: introduce a new .enable_cbs method" Revert "virtio: use virtio_device_ready() in virtio_device_restore()"
2 parents e2a1256 + 1c80cf0 commit 3e732eb

3 files changed

Lines changed: 43 additions & 30 deletions

File tree

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

168169
static 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+
17001711
out:
1701-
kfree(wqent);
1712+
mutex_unlock(&ndev->reslock);
17021713
}
17031714

17041715
static 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 */
21982203
static 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)
22412246
err_rqt:
22422247
teardown_virtqueues(ndev);
22432248
out:
2244-
mutex_unlock(&ndev->reslock);
22452249
return err;
22462250
}
22472251

2252+
/* reslock must be held for this function */
22482253
static 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

22632268
static 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

22972305
err_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

23022312
static 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)
23532366
static 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

23712389
static 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;

drivers/virtio/virtio.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,9 +526,8 @@ int virtio_device_restore(struct virtio_device *dev)
526526
goto err;
527527
}
528528

529-
/* If restore didn't do it, mark device DRIVER_OK ourselves. */
530-
if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
531-
virtio_device_ready(dev);
529+
/* Finally, tell the device we're all set */
530+
virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
532531

533532
virtio_config_enable(dev);
534533

include/linux/virtio_config.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ struct virtio_shm_region {
2323
* any of @get/@set, @get_status/@set_status, or @get_features/
2424
* @finalize_features are NOT safe to be called from an atomic
2525
* context.
26-
* @enable_cbs: enable the callbacks
27-
* vdev: the virtio_device
2826
* @get: read the value of a configuration field
2927
* vdev: the virtio_device
3028
* offset: the offset of the configuration field
@@ -78,7 +76,6 @@ struct virtio_shm_region {
7876
*/
7977
typedef void vq_callback_t(struct virtqueue *);
8078
struct virtio_config_ops {
81-
void (*enable_cbs)(struct virtio_device *vdev);
8279
void (*get)(struct virtio_device *vdev, unsigned offset,
8380
void *buf, unsigned len);
8481
void (*set)(struct virtio_device *vdev, unsigned offset,
@@ -233,9 +230,6 @@ void virtio_device_ready(struct virtio_device *dev)
233230
{
234231
unsigned status = dev->config->get_status(dev);
235232

236-
if (dev->config->enable_cbs)
237-
dev->config->enable_cbs(dev);
238-
239233
BUG_ON(status & VIRTIO_CONFIG_S_DRIVER_OK);
240234
dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK);
241235
}

0 commit comments

Comments
 (0)