drivers/infiniband/hw/mlx5/odp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mlx5/odp.c
Extension
.c
Size
57632 bytes
Lines
2109
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

struct mlx5_pagefault {
	u32			bytes_committed;
	u64			token;
	u8			event_subtype;
	u8			type;
	union {
		/* Initiator or send message responder pagefault details. */
		struct {
			/* Received packet size, only valid for responders. */
			u32	packet_size;
			/*
			 * Number of resource holding WQE, depends on type.
			 */
			u32	wq_num;
			/*
			 * WQE index. Refers to either the send queue or
			 * receive queue, according to event_subtype.
			 */
			u16	wqe_index;
		} wqe;
		/* RDMA responder pagefault details */
		struct {
			u32	r_key;
			/*
			 * Received packet size, minimal size page fault
			 * resolution required for forward progress.
			 */
			u32	packet_size;
			u32	rdma_op_len;
			u64	rdma_va;
		} rdma;
		struct {
			u64	va;
			u32	mkey;
			u32	fault_byte_count;
			u32     prefetch_before_byte_count;
			u32     prefetch_after_byte_count;
			u8	flags;
		} memory;
	};

	struct mlx5_ib_pf_eq	*eq;
	struct work_struct	work;
};

#define MAX_PREFETCH_LEN (4*1024*1024U)

/* Timeout in ms to wait for an active mmu notifier to complete when handling
 * a pagefault. */
#define MMU_NOTIFIER_TIMEOUT 1000

static u64 mlx5_imr_ksm_entries;
static u64 mlx5_imr_mtt_entries;
static u64 mlx5_imr_mtt_size;
static u8 mlx5_imr_mtt_shift;
static u8 mlx5_imr_ksm_page_shift;

static void populate_ksm(struct mlx5_ksm *pksm, size_t idx, size_t nentries,
			struct mlx5_ib_mr *imr, int flags)
{
	struct mlx5_core_dev *dev = mr_to_mdev(imr)->mdev;
	struct mlx5_ksm *end = pksm + nentries;
	u64 step = MLX5_CAP_ODP(dev, mem_page_fault) ? mlx5_imr_mtt_size : 0;
	__be32 key = MLX5_CAP_ODP(dev, mem_page_fault) ?
			     cpu_to_be32(imr->null_mmkey.key) :
			     mr_to_mdev(imr)->mkeys.null_mkey;
	u64 va =
		MLX5_CAP_ODP(dev, mem_page_fault) ? idx * mlx5_imr_mtt_size : 0;

	if (flags & MLX5_IB_UPD_XLT_ZAP) {
		for (; pksm != end; pksm++, idx++, va += step) {
			pksm->key = key;
			pksm->va = cpu_to_be64(va);
		}
		return;
	}

	/*
	 * The locking here is pretty subtle. Ideally the implicit_children
	 * xarray would be protected by the umem_mutex, however that is not
	 * possible. Instead this uses a weaker update-then-lock pattern:
	 *
	 *    xa_store()
	 *    mutex_lock(umem_mutex)
	 *     mlx5r_umr_update_xlt()
	 *    mutex_unlock(umem_mutex)
	 *    destroy lkey
	 *
	 * ie any change the xarray must be followed by the locked update_xlt
	 * before destroying.

Annotation

Implementation Notes