#include <rte_errno.h>
#include <rte_string_fns.h>
#include <rte_bus_pci.h>
+#include <rte_eal_paging.h>
#include <mlx5_glue.h>
#include <mlx5_common.h>
DRV_LOG(ERR, "Invalid vDPA device: %s.", vdev->device->name);
return -1;
}
- *queue_num = priv->caps.max_num_virtio_queues;
+ *queue_num = priv->caps.max_num_virtio_queues / 2;
return 0;
}
DRV_LOG(ERR, "Invalid vDPA device: %s.", vdev->device->name);
return -EINVAL;
}
- if (vring >= (int)priv->caps.max_num_virtio_queues * 2) {
+ if (vring >= (int)priv->caps.max_num_virtio_queues) {
DRV_LOG(ERR, "Too big vring id: %d.", vring);
return -E2BIG;
}
if (priv->lm_mr.addr)
mlx5_os_wrapped_mkey_destroy(&priv->lm_mr);
priv->state = MLX5_VDPA_STATE_PROBED;
+ if (!priv->connected)
+ mlx5_vdpa_dev_cache_clean(priv);
priv->vid = 0;
/* The mutex may stay locked after event thread cancel - initiate it. */
pthread_mutex_init(&priv->vq_config_lock, NULL);
return -1;
}
priv->vid = vid;
+ priv->connected = true;
if (mlx5_vdpa_mtu_set(priv))
DRV_LOG(WARNING, "MTU cannot be set on device %s.",
vdev->device->name);
DRV_LOG(ERR, "Invalid device: %s.", vdev->device->name);
return -ENODEV;
}
- if (priv->state == MLX5_VDPA_STATE_PROBED) {
- DRV_LOG(ERR, "Device %s was not configured.",
- vdev->device->name);
- return -ENODATA;
- }
- if (qid >= (int)priv->nr_virtqs) {
+ if (qid >= (int)priv->caps.max_num_virtio_queues) {
DRV_LOG(ERR, "Too big vring id: %d for device %s.", qid,
vdev->device->name);
return -E2BIG;
DRV_LOG(ERR, "Invalid device: %s.", vdev->device->name);
return -ENODEV;
}
- if (priv->state == MLX5_VDPA_STATE_PROBED) {
- DRV_LOG(ERR, "Device %s was not configured.",
- vdev->device->name);
- return -ENODATA;
- }
- if (qid >= (int)priv->nr_virtqs) {
+ if (qid >= (int)priv->caps.max_num_virtio_queues) {
DRV_LOG(ERR, "Too big vring id: %d for device %s.", qid,
vdev->device->name);
return -E2BIG;
return mlx5_vdpa_virtq_stats_reset(priv, qid);
}
+static int
+mlx5_vdpa_dev_cleanup(int vid)
+{
+ struct rte_vdpa_device *vdev = rte_vhost_get_vdpa_device(vid);
+ struct mlx5_vdpa_priv *priv;
+
+ if (vdev == NULL)
+ return -1;
+ priv = mlx5_vdpa_find_priv_resource_by_vdev(vdev);
+ if (priv == NULL) {
+ DRV_LOG(ERR, "Invalid vDPA device: %s.", vdev->device->name);
+ return -1;
+ }
+ if (priv->state == MLX5_VDPA_STATE_PROBED)
+ mlx5_vdpa_dev_cache_clean(priv);
+ priv->connected = false;
+ return 0;
+}
+
static struct rte_vdpa_dev_ops mlx5_vdpa_ops = {
.get_queue_num = mlx5_vdpa_get_queue_num,
.get_features = mlx5_vdpa_get_vdpa_features,
.get_protocol_features = mlx5_vdpa_get_protocol_features,
.dev_conf = mlx5_vdpa_dev_config,
.dev_close = mlx5_vdpa_dev_close,
+ .dev_cleanup = mlx5_vdpa_dev_cleanup,
.set_vring_state = mlx5_vdpa_set_vring_state,
.set_features = mlx5_vdpa_features_set,
.migration_done = NULL,
rte_errno = errno;
return -rte_errno;
}
+ /* Add within page offset for 64K page system. */
+ priv->virtq_db_addr = (char *)priv->virtq_db_addr +
+ ((rte_mem_page_size() - 1) & priv->caps.doorbell_bar_offset);
DRV_LOG(DEBUG, "VAR address of doorbell mapping is %p.",
priv->virtq_db_addr);
priv->td = mlx5_devx_cmd_create_td(ctx);
DRV_LOG(DEBUG, "No capability to support virtq statistics.");
priv = rte_zmalloc("mlx5 vDPA device private", sizeof(*priv) +
sizeof(struct mlx5_vdpa_virtq) *
- attr->vdpa.max_num_virtio_queues * 2,
+ attr->vdpa.max_num_virtio_queues,
RTE_CACHE_LINE_SIZE);
if (!priv) {
DRV_LOG(ERR, "Failed to allocate private memory.");
uint32_t i;
mlx5_vdpa_dev_cache_clean(priv);
+ for (i = 0; i < priv->caps.max_num_virtio_queues; i++) {
+ if (!priv->virtqs[i].counters)
+ continue;
+ claim_zero(mlx5_devx_cmd_destroy(priv->virtqs[i].counters));
+ }
mlx5_vdpa_event_qp_global_release(priv);
mlx5_vdpa_err_event_unset(priv);
if (priv->steer.tbl)
if (priv->td)
claim_zero(mlx5_devx_cmd_destroy(priv->td));
if (priv->virtq_db_addr)
- claim_zero(munmap(priv->virtq_db_addr, priv->var->length));
+ /* Mask out the within page offset for munmap. */
+ claim_zero(munmap((void *)((uintptr_t)priv->virtq_db_addr &
+ ~(rte_mem_page_size() - 1)), priv->var->length));
if (priv->var)
mlx5_glue->dv_free_var(priv->var);
}