drivers/infiniband/hw/mlx5/mr.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mlx5/mr.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mlx5/mr.c
Extension
.c
Size
60145 bytes
Lines
2230
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (WARN_ON(access_flags & IB_ACCESS_ON_DEMAND || ksm_mode)) {
			err = -EINVAL;
			goto err_2;
		}
		mlx5_ib_populate_pas(umem, 1UL << mr->page_shift, pas,
				     pg_cap ? MLX5_IB_MTT_PRESENT : 0);
	}

	/* The pg_access bit allows setting the access flags
	 * in the page list submitted with the command.
	 */
	MLX5_SET(create_mkey_in, in, pg_access, !!(pg_cap));

	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
	set_mkc_access_pd_addr_fields(mkc, access_flags, iova,
				      populate ? pd : dev->umrc.pd);
	/* In case a data direct flow, overwrite the pdn field by its internal kernel PD */
	if (umem->is_dmabuf && ksm_mode)
		MLX5_SET(mkc, mkc, pd, dev->ddr.pdn);

	MLX5_SET(mkc, mkc, free, !populate);
	MLX5_SET(mkc, mkc, access_mode_1_0, access_mode);
	MLX5_SET(mkc, mkc, umr_en, 1);

	MLX5_SET64(mkc, mkc, len, umem->length);
	MLX5_SET(mkc, mkc, bsf_octword_size, 0);
	if (ksm_mode)
		MLX5_SET(mkc, mkc, translations_octword_size,
			 get_octo_len(iova, umem->length, mr->page_shift) * 2);
	else
		MLX5_SET(mkc, mkc, translations_octword_size,
			 get_octo_len(iova, umem->length, mr->page_shift));
	MLX5_SET(mkc, mkc, log_page_size, mr->page_shift);
	if (mlx5_umem_needs_ats(dev, umem, access_flags))
		MLX5_SET(mkc, mkc, ma_translation_mode, 1);
	if (populate) {
		MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
			 get_octo_len(iova, umem->length, mr->page_shift));
	}

	if (ph != MLX5_IB_NO_PH) {
		MLX5_SET(mkc, mkc, pcie_tph_en, 1);
		MLX5_SET(mkc, mkc, pcie_tph_ph, ph);
		if (st_index != MLX5_MKC_PCIE_TPH_NO_STEERING_TAG_INDEX)
			MLX5_SET(mkc, mkc, pcie_tph_steering_tag_index, st_index);
	}

	err = mlx5_ib_create_mkey(dev, &mr->mmkey, in, inlen);
	if (err) {
		mlx5_ib_warn(dev, "create mkey failed\n");
		goto err_2;
	}
	mr->mmkey.type = MLX5_MKEY_MR;
	mr->mmkey.ndescs = get_octo_len(iova, umem->length, mr->page_shift);
	mr->umem = umem;
	set_mr_fields(dev, mr, umem->length, access_flags, iova);
	kvfree(in);

	mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmkey.key);

	return mr;

err_2:
	kvfree(in);
err_1:
	kfree(mr);
	return ERR_PTR(err);
}

static struct ib_mr *mlx5_ib_get_dm_mr(struct ib_pd *pd, u64 start_addr,
				       u64 length, int acc, int mode)
{
	struct mlx5_ib_dev *dev = to_mdev(pd->device);
	int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
	struct mlx5_ib_mr *mr;
	void *mkc;
	u32 *in;
	int err;

	mr = kzalloc_obj(*mr);
	if (!mr)
		return ERR_PTR(-ENOMEM);

	in = kzalloc(inlen, GFP_KERNEL);
	if (!in) {
		err = -ENOMEM;
		goto err_free;
	}

	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);

Annotation

Implementation Notes