entry = SLIST_FIRST(&priv->mr_list);
while (entry) {
next = SLIST_NEXT(entry, next);
- claim_zero(mlx5_devx_cmd_destroy(entry->mkey));
- if (!entry->is_indirect)
- claim_zero(mlx5_glue->devx_umem_dereg(entry->umem));
+ if (entry->is_indirect)
+ claim_zero(mlx5_devx_cmd_destroy(entry->mkey));
+ else
+ claim_zero(mlx5_glue->dereg_mr(entry->mr));
SLIST_REMOVE(&priv->mr_list, entry, mlx5_vdpa_query_mr, next);
rte_free(entry);
entry = next;
}
SLIST_INIT(&priv->mr_list);
- if (priv->null_mr) {
- claim_zero(mlx5_glue->dereg_mr(priv->null_mr));
- priv->null_mr = NULL;
- }
if (priv->vmem) {
free(priv->vmem);
priv->vmem = NULL;
size = mem->regions[i].guest_phys_addr -
(mem->regions[i - 1].guest_phys_addr +
mem->regions[i - 1].size);
- *gcd = rte_get_gcd(*gcd, size);
+ *gcd = rte_get_gcd64(*gcd, size);
klm_entries_num += KLM_NUM_MAX_ALIGN(size);
}
size = mem->regions[i].size;
- *gcd = rte_get_gcd(*gcd, size);
+ *gcd = rte_get_gcd64(*gcd, size);
klm_entries_num += KLM_NUM_MAX_ALIGN(size);
}
if (*gcd > MLX5_MAX_KLM_BYTE_COUNT)
- *gcd = rte_get_gcd(*gcd, MLX5_MAX_KLM_BYTE_COUNT);
+ *gcd = rte_get_gcd64(*gcd, MLX5_MAX_KLM_BYTE_COUNT);
if (!RTE_IS_POWER_OF_2(*gcd)) {
uint64_t candidate_gcd = rte_align64prevpow2(*gcd);
return mem;
}
+static int
+mlx5_vdpa_mem_cmp(struct rte_vhost_memory *mem1, struct rte_vhost_memory *mem2)
+{
+ uint32_t i;
+
+ if (mem1->nregions != mem2->nregions)
+ return -1;
+ for (i = 0; i < mem1->nregions; i++) {
+ if (mem1->regions[i].guest_phys_addr !=
+ mem2->regions[i].guest_phys_addr)
+ return -1;
+ if (mem1->regions[i].size != mem2->regions[i].size)
+ return -1;
+ }
+ return 0;
+}
+
#define KLM_SIZE_MAX_ALIGN(sz) ((sz) > MLX5_MAX_KLM_BYTE_COUNT ? \
MLX5_MAX_KLM_BYTE_COUNT : (sz))
* The target here is to group all the physical memory regions of the
* virtio device in one indirect mkey.
* For KLM Fixed Buffer Size mode (HW find the translation entry in one
- * read according to the guest phisical address):
+ * read according to the guest physical address):
* All the sub-direct mkeys of it must be in the same size, hence, each
* one of them should be in the GCD size of all the virtio memory
* regions and the holes between them.
struct mlx5_devx_mkey_attr mkey_attr;
struct mlx5_vdpa_query_mr *entry = NULL;
struct rte_vhost_mem_region *reg = NULL;
- uint8_t mode;
+ uint8_t mode = 0;
uint32_t entries_num = 0;
uint32_t i;
- uint64_t gcd;
+ uint64_t gcd = 0;
uint64_t klm_size;
uint64_t mem_size;
uint64_t k;
if (!mem)
return -rte_errno;
- priv->vmem = mem;
- priv->null_mr = mlx5_glue->alloc_null_mr(priv->pd);
- if (!priv->null_mr) {
- DRV_LOG(ERR, "Failed to allocate null MR.");
- ret = -errno;
- goto error;
+ if (priv->vmem != NULL) {
+ if (mlx5_vdpa_mem_cmp(mem, priv->vmem) == 0) {
+ /* VM memory not changed, reuse resources. */
+ free(mem);
+ return 0;
+ }
+ mlx5_vdpa_mem_dereg(priv);
}
- DRV_LOG(DEBUG, "Dump fill Mkey = %u.", priv->null_mr->lkey);
- memset(&mkey_attr, 0, sizeof(mkey_attr));
+ priv->vmem = mem;
for (i = 0; i < mem->nregions; i++) {
reg = &mem->regions[i];
entry = rte_zmalloc(__func__, sizeof(*entry), 0);
DRV_LOG(ERR, "Failed to allocate mem entry memory.");
goto error;
}
- entry->umem = mlx5_glue->devx_umem_reg(priv->ctx,
- (void *)(uintptr_t)reg->host_user_addr,
- reg->size, IBV_ACCESS_LOCAL_WRITE);
- if (!entry->umem) {
- DRV_LOG(ERR, "Failed to register Umem by Devx.");
- ret = -errno;
- goto error;
- }
- mkey_attr.addr = (uintptr_t)(reg->guest_phys_addr);
- mkey_attr.size = reg->size;
- mkey_attr.umem_id = entry->umem->umem_id;
- mkey_attr.pd = priv->pdn;
- mkey_attr.pg_access = 1;
- entry->mkey = mlx5_devx_cmd_mkey_create(priv->ctx, &mkey_attr);
- if (!entry->mkey) {
+ entry->mr = mlx5_glue->reg_mr_iova(priv->cdev->pd,
+ (void *)(uintptr_t)(reg->host_user_addr),
+ reg->size, reg->guest_phys_addr,
+ IBV_ACCESS_LOCAL_WRITE);
+ if (!entry->mr) {
DRV_LOG(ERR, "Failed to create direct Mkey.");
ret = -rte_errno;
goto error;
}
- entry->addr = (void *)(uintptr_t)(reg->host_user_addr);
- entry->length = reg->size;
entry->is_indirect = 0;
if (i > 0) {
uint64_t sadd;
for (k = 0; k < reg->size; k += klm_size) {
klm_array[klm_index].byte_count = k + klm_size >
reg->size ? reg->size - k : klm_size;
- klm_array[klm_index].mkey = entry->mkey->id;
+ klm_array[klm_index].mkey = entry->mr->lkey;
klm_array[klm_index].address = reg->guest_phys_addr + k;
klm_index++;
}
SLIST_INSERT_HEAD(&priv->mr_list, entry, next);
}
+ memset(&mkey_attr, 0, sizeof(mkey_attr));
mkey_attr.addr = (uintptr_t)(mem->regions[0].guest_phys_addr);
mkey_attr.size = mem_size;
- mkey_attr.pd = priv->pdn;
+ mkey_attr.pd = priv->cdev->pdn;
mkey_attr.umem_id = 0;
/* Must be zero for KLM mode. */
mkey_attr.log_entity_size = mode == MLX5_MKC_ACCESS_MODE_KLM_FBS ?
ret = -ENOMEM;
goto error;
}
- entry->mkey = mlx5_devx_cmd_mkey_create(priv->ctx, &mkey_attr);
+ entry->mkey = mlx5_devx_cmd_mkey_create(priv->cdev->ctx, &mkey_attr);
if (!entry->mkey) {
DRV_LOG(ERR, "Failed to create indirect Mkey.");
ret = -rte_errno;
priv->gpa_mkey_index = entry->mkey->id;
return 0;
error:
- if (entry) {
- if (entry->mkey)
- mlx5_devx_cmd_destroy(entry->mkey);
- if (entry->umem)
- mlx5_glue->devx_umem_dereg(entry->umem);
- rte_free(entry);
- }
+ rte_free(entry);
mlx5_vdpa_mem_dereg(priv);
rte_errno = -ret;
return ret;