Skip to content

Commit dcf3eac

Browse files
dtatuleamstsirkin
authored andcommitted
vdpa/mlx5: Parallelize device suspend
Currently device suspend works on vqs serially. Building up on previous changes that converted vq operations to the async api, this patch parallelizes the device suspend: 1) Suspend all active vqs parallel. 2) Query suspended vqs in parallel. For 1 vDPA device x 32 VQs (16 VQPs) attached to a large VM (256 GB RAM, 32 CPUs x 2 threads per core), the device suspend time is reduced from ~37 ms to ~13 ms. A later patch will remove the link unregister operation which will make it even faster. Signed-off-by: Dragos Tatulea <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Acked-by: Eugenio Pérez <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Tested-by: Lei Yang <[email protected]>
1 parent 61674c1 commit dcf3eac

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,49 +1630,51 @@ static int modify_virtqueues(struct mlx5_vdpa_net *ndev, int start_vq, int num_v
16301630
return err;
16311631
}
16321632

1633-
static int suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1633+
static int suspend_vqs(struct mlx5_vdpa_net *ndev, int start_vq, int num_vqs)
16341634
{
1635-
struct mlx5_virtq_attr attr;
1635+
struct mlx5_vdpa_virtqueue *mvq;
1636+
struct mlx5_virtq_attr *attrs;
1637+
int vq_idx, i;
16361638
int err;
16371639

1640+
if (start_vq >= ndev->cur_num_vqs)
1641+
return -EINVAL;
1642+
1643+
mvq = &ndev->vqs[start_vq];
16381644
if (!mvq->initialized)
16391645
return 0;
16401646

16411647
if (mvq->fw_state != MLX5_VIRTIO_NET_Q_OBJECT_STATE_RDY)
16421648
return 0;
16431649

1644-
err = modify_virtqueues(ndev, mvq->index, 1, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND);
1645-
if (err) {
1646-
mlx5_vdpa_err(&ndev->mvdev, "modify to suspend failed, err: %d\n", err);
1647-
return err;
1648-
}
1649-
1650-
err = query_virtqueues(ndev, mvq->index, 1, &attr);
1651-
if (err) {
1652-
mlx5_vdpa_err(&ndev->mvdev, "failed to query virtqueue, err: %d\n", err);
1650+
err = modify_virtqueues(ndev, start_vq, num_vqs, MLX5_VIRTIO_NET_Q_OBJECT_STATE_SUSPEND);
1651+
if (err)
16531652
return err;
1654-
}
1655-
1656-
mvq->avail_idx = attr.available_index;
1657-
mvq->used_idx = attr.used_index;
1658-
1659-
return 0;
1660-
}
16611653

1662-
static int suspend_vqs(struct mlx5_vdpa_net *ndev)
1663-
{
1664-
int err = 0;
1665-
int i;
1654+
attrs = kcalloc(num_vqs, sizeof(struct mlx5_virtq_attr), GFP_KERNEL);
1655+
if (!attrs)
1656+
return -ENOMEM;
16661657

1667-
for (i = 0; i < ndev->cur_num_vqs; i++) {
1668-
int local_err = suspend_vq(ndev, &ndev->vqs[i]);
1658+
err = query_virtqueues(ndev, start_vq, num_vqs, attrs);
1659+
if (err)
1660+
goto done;
16691661

1670-
err = local_err ? local_err : err;
1662+
for (i = 0, vq_idx = start_vq; i < num_vqs; i++, vq_idx++) {
1663+
mvq = &ndev->vqs[vq_idx];
1664+
mvq->avail_idx = attrs[i].available_index;
1665+
mvq->used_idx = attrs[i].used_index;
16711666
}
16721667

1668+
done:
1669+
kfree(attrs);
16731670
return err;
16741671
}
16751672

1673+
static int suspend_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
1674+
{
1675+
return suspend_vqs(ndev, mvq->index, 1);
1676+
}
1677+
16761678
static int resume_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq)
16771679
{
16781680
int err;
@@ -3053,7 +3055,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
30533055
bool teardown = !is_resumable(ndev);
30543056
int err;
30553057

3056-
suspend_vqs(ndev);
3058+
suspend_vqs(ndev, 0, ndev->cur_num_vqs);
30573059
if (teardown) {
30583060
err = save_channels_info(ndev);
30593061
if (err)
@@ -3606,7 +3608,7 @@ static int mlx5_vdpa_suspend(struct vdpa_device *vdev)
36063608

36073609
down_write(&ndev->reslock);
36083610
unregister_link_notifier(ndev);
3609-
err = suspend_vqs(ndev);
3611+
err = suspend_vqs(ndev, 0, ndev->cur_num_vqs);
36103612
mlx5_vdpa_cvq_suspend(mvdev);
36113613
mvdev->suspended = true;
36123614
up_write(&ndev->reslock);

0 commit comments

Comments
 (0)