|
@@ -992,6 +992,117 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
|
|
|
+ struct ib_mr_init_attr *mr_init_attr)
|
|
|
+{
|
|
|
+ struct mlx5_ib_dev *dev = to_mdev(pd->device);
|
|
|
+ struct mlx5_create_mkey_mbox_in *in;
|
|
|
+ struct mlx5_ib_mr *mr;
|
|
|
+ int access_mode, err;
|
|
|
+ int ndescs = roundup(mr_init_attr->max_reg_descriptors, 4);
|
|
|
+
|
|
|
+ mr = kzalloc(sizeof(*mr), GFP_KERNEL);
|
|
|
+ if (!mr)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ in = kzalloc(sizeof(*in), GFP_KERNEL);
|
|
|
+ if (!in) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto err_free;
|
|
|
+ }
|
|
|
+
|
|
|
+ in->seg.status = 1 << 6; /* free */
|
|
|
+ in->seg.xlt_oct_size = cpu_to_be32(ndescs);
|
|
|
+ in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
|
|
|
+ in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
|
|
|
+ access_mode = MLX5_ACCESS_MODE_MTT;
|
|
|
+
|
|
|
+ if (mr_init_attr->flags & IB_MR_SIGNATURE_EN) {
|
|
|
+ u32 psv_index[2];
|
|
|
+
|
|
|
+ in->seg.flags_pd = cpu_to_be32(be32_to_cpu(in->seg.flags_pd) |
|
|
|
+ MLX5_MKEY_BSF_EN);
|
|
|
+ in->seg.bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
|
|
|
+ mr->sig = kzalloc(sizeof(*mr->sig), GFP_KERNEL);
|
|
|
+ if (!mr->sig) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto err_free_in;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* create mem & wire PSVs */
|
|
|
+ err = mlx5_core_create_psv(&dev->mdev, to_mpd(pd)->pdn,
|
|
|
+ 2, psv_index);
|
|
|
+ if (err)
|
|
|
+ goto err_free_sig;
|
|
|
+
|
|
|
+ access_mode = MLX5_ACCESS_MODE_KLM;
|
|
|
+ mr->sig->psv_memory.psv_idx = psv_index[0];
|
|
|
+ mr->sig->psv_wire.psv_idx = psv_index[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ in->seg.flags = MLX5_PERM_UMR_EN | access_mode;
|
|
|
+ err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in),
|
|
|
+ NULL, NULL, NULL);
|
|
|
+ if (err)
|
|
|
+ goto err_destroy_psv;
|
|
|
+
|
|
|
+ mr->ibmr.lkey = mr->mmr.key;
|
|
|
+ mr->ibmr.rkey = mr->mmr.key;
|
|
|
+ mr->umem = NULL;
|
|
|
+ kfree(in);
|
|
|
+
|
|
|
+ return &mr->ibmr;
|
|
|
+
|
|
|
+err_destroy_psv:
|
|
|
+ if (mr->sig) {
|
|
|
+ if (mlx5_core_destroy_psv(&dev->mdev,
|
|
|
+ mr->sig->psv_memory.psv_idx))
|
|
|
+ mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
|
|
|
+ mr->sig->psv_memory.psv_idx);
|
|
|
+ if (mlx5_core_destroy_psv(&dev->mdev,
|
|
|
+ mr->sig->psv_wire.psv_idx))
|
|
|
+ mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
|
|
|
+ mr->sig->psv_wire.psv_idx);
|
|
|
+ }
|
|
|
+err_free_sig:
|
|
|
+ kfree(mr->sig);
|
|
|
+err_free_in:
|
|
|
+ kfree(in);
|
|
|
+err_free:
|
|
|
+ kfree(mr);
|
|
|
+ return ERR_PTR(err);
|
|
|
+}
|
|
|
+
|
|
|
+int mlx5_ib_destroy_mr(struct ib_mr *ibmr)
|
|
|
+{
|
|
|
+ struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
|
|
|
+ struct mlx5_ib_mr *mr = to_mmr(ibmr);
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (mr->sig) {
|
|
|
+ if (mlx5_core_destroy_psv(&dev->mdev,
|
|
|
+ mr->sig->psv_memory.psv_idx))
|
|
|
+ mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
|
|
|
+ mr->sig->psv_memory.psv_idx);
|
|
|
+ if (mlx5_core_destroy_psv(&dev->mdev,
|
|
|
+ mr->sig->psv_wire.psv_idx))
|
|
|
+ mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
|
|
|
+ mr->sig->psv_wire.psv_idx);
|
|
|
+ kfree(mr->sig);
|
|
|
+ }
|
|
|
+
|
|
|
+ err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
|
|
|
+ if (err) {
|
|
|
+ mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
|
|
|
+ mr->mmr.key, err);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ kfree(mr);
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
|
|
|
int max_page_list_len)
|
|
|
{
|