+ for (i = 0; i < priv->mr_n; ++i) {
+ mr = &(*priv->mr)[i];
+ mr->memseg = &ms[i];
+ mr->ibv_mr = ibv_reg_mr(priv->pd,
+ mr->memseg->addr, mr->memseg->len,
+ IBV_ACCESS_LOCAL_WRITE);
+ if (mr->ibv_mr == NULL) {
+ rte_dump_physmem_layout(stderr);
+ DRV_LOG(ERR, "port %u cannot register memseg[%u]",
+ dev->data->port_id, i);
+ goto error;
+ }
+ }
+ /* Sort by virtual address. */
+ qsort(*priv->mr, priv->mr_n, sizeof(struct mlx5_mr), mr_comp_addr);
+ /* First entry must be NULL for comparison. */
+ (*priv->mr_cache)[0] = (struct mlx5_mr_cache) {
+ .lkey = UINT32_MAX,
+ };
+ /* Compile global all-inclusive MR cache table. */
+ for (i = 0; i < priv->mr_n; ++i) {
+ mr = &(*priv->mr)[i];
+ mr_cache = &(*priv->mr_cache)[i + 1];
+ /* Paranoid, mr[] must be sorted. */
+ assert(i == 0 || mr->memseg->addr > (mr - 1)->memseg->addr);
+ *mr_cache = (struct mlx5_mr_cache) {
+ .start = (uintptr_t)mr->memseg->addr,
+ .end = (uintptr_t)mr->memseg->addr + mr->memseg->len,
+ .lkey = rte_cpu_to_be_32(mr->ibv_mr->lkey)
+ };
+ }
+ return 0;
+error:
+ for (i = 0; i < priv->mr_n; ++i) {
+ mr = &(*priv->mr)[i];
+ if (mr->ibv_mr != NULL)
+ ibv_dereg_mr(mr->ibv_mr);
+ }
+ rte_free(priv->mr);
+ rte_free(priv->mr_cache);
+ rte_errno = ENOMEM;
+ return -rte_errno;