Currently, CVQ vringh is initialized inside setup_virtqueues() which is called every time a memory update is done. This is undesirable since it resets all the context of the vring, including the available and used indices. Move the initialization to mlx5_vdpa_set_status() when VIRTIO_CONFIG_S_DRIVER_OK is set.
Unified · Split
| @@ -2176,7 +2176,6 @@ static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features) · 2175 unmodified lines | ||
| 2176 | 2176 | static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev) |
| 2177 | 2177 | { |
| 2178 | 2178 | struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); |
| 2179 | − struct mlx5_control_vq *cvq = &mvdev->cvq; | |
| 2180 | 2179 | int err; |
| 2181 | 2180 | int i; |
| 2182 | 2181 | |
| @@ -2186,16 +2185,6 @@ static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev) · 3 unmodified lines | ||
| 2186 | 2185 | goto err_vq; |
| 2187 | 2186 | } |
| 2188 | 2187 | |
| 2189 | − if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) { | |
| 2190 | − err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features, | |
| 2191 | − MLX5_CVQ_MAX_ENT, false, | |
| 2192 | − (struct vring_desc *)(uintptr_t)cvq->desc_addr, | |
| 2193 | − (struct vring_avail *)(uintptr_t)cvq->driver_addr, | |
| 2194 | − (struct vring_used *)(uintptr_t)cvq->device_addr); | |
| 2195 | − if (err) | |
| 2196 | − goto err_vq; | |
| 2197 | − } | |
| 2198 | − | |
| 2199 | 2188 | return 0; |
| 2200 | 2189 | |
| 2201 | 2190 | err_vq: |
| @@ -2468,6 +2457,21 @@ static void clear_vqs_ready(struct mlx5_vdpa_net *ndev) · 266 unmodified lines | ||
| 2468 | 2457 | ndev->mvdev.cvq.ready = false; |
| 2469 | 2458 | } |
| 2470 | 2459 | |
| 2460 | +static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev) | |
| 2461 | +{ | |
| 2462 | + struct mlx5_control_vq *cvq = &mvdev->cvq; | |
| 2463 | + int err = 0; | |
| 2464 | + | |
| 2465 | + if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) | |
| 2466 | + err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features, | |
| 2467 | + MLX5_CVQ_MAX_ENT, false, | |
| 2468 | + (struct vring_desc *)(uintptr_t)cvq->desc_addr, | |
| 2469 | + (struct vring_avail *)(uintptr_t)cvq->driver_addr, | |
| 2470 | + (struct vring_used *)(uintptr_t)cvq->device_addr); | |
| 2471 | + | |
| 2472 | + return err; | |
| 2473 | +} | |
| 2474 | + | |
| 2471 | 2475 | static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) |
| 2472 | 2476 | { |
| 2473 | 2477 | struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); |
| @@ -2480,6 +2484,11 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) · 6 unmodified lines | ||
| 2480 | 2484 | |
| 2481 | 2485 | if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) { |
| 2482 | 2486 | if (status & VIRTIO_CONFIG_S_DRIVER_OK) { |
| 2487 | + err = setup_cvq_vring(mvdev); | |
| 2488 | + if (err) { | |
| 2489 | + mlx5_vdpa_warn(mvdev, "failed to setup control VQ vring\n"); | |
| 2490 | + goto err_setup; | |
| 2491 | + } | |
| 2483 | 2492 | err = setup_driver(mvdev); |
| 2484 | 2493 | if (err) { |
| 2485 | 2494 | mlx5_vdpa_warn(mvdev, "failed to setup driver\n"); |