drivers/infiniband/core/umem.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/umem.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/umem.c
Extension
.c
Size
20441 bytes
Lines
685
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (pinned < 0) {
			ret = pinned;
			goto umem_release;
		}

		cur_base += pinned * PAGE_SIZE;
		npages -= pinned;
		ret = sg_alloc_append_table_from_pages(
			&umem->sgt_append, page_list, pinned, 0,
			pinned << PAGE_SHIFT, ib_dma_max_seg_size(device),
			npages, GFP_KERNEL);
		if (ret) {
			unpin_user_pages_dirty_lock(page_list, pinned, 0);
			goto umem_release;
		}
	}

	ret = ib_dma_map_sgtable_attrs(device, &umem->sgt_append.sgt,
				       DMA_BIDIRECTIONAL, umem->dma_attrs);
	if (ret)
		goto umem_release;
	goto out;

umem_release:
	__ib_umem_release(device, umem, 0);
	atomic64_sub(ib_umem_num_pages(umem), &mm->pinned_vm);
out:
	free_page((unsigned long) page_list);
umem_kfree:
	if (ret) {
		mmdrop(umem->owning_mm);
		kfree(umem);
	}
	return ret ? ERR_PTR(ret) : umem;
}

/**
 * ib_umem_get_desc - Pin a umem from a buffer descriptor.
 * @device: IB device.
 * @desc:   buffer descriptor (VA or DMABUF).
 * @access: IB access flags.
 *
 * Return: caller-owned umem on success, ERR_PTR(...) on error.
 */
struct ib_umem *ib_umem_get_desc(struct ib_device *device,
				 const struct ib_uverbs_buffer_desc *desc,
				 int access)
{
	struct ib_umem_dmabuf *umem_dmabuf;

	if (desc->flags & ~IB_UVERBS_BUFFER_DESC_FLAGS_KNOWN_MASK)
		return ERR_PTR(-EINVAL);

	if (overflows_type(desc->addr, unsigned long) ||
	    overflows_type(desc->length, size_t))
		return ERR_PTR(-EOVERFLOW);

	switch (desc->type) {
	case IB_UVERBS_BUFFER_TYPE_DMABUF:
		umem_dmabuf = ib_umem_dmabuf_get_pinned(device, desc->addr,
							desc->length, desc->fd,
							access);
		if (IS_ERR(umem_dmabuf))
			return ERR_CAST(umem_dmabuf);
		return &umem_dmabuf->umem;
	case IB_UVERBS_BUFFER_TYPE_VA:
		return __ib_umem_get_va(device, desc->addr, desc->length,
					access);
	default:
		return ERR_PTR(-EINVAL);
	}
}
EXPORT_SYMBOL(ib_umem_get_desc);

/*
 * Per-command legacy buffer-desc filler.
 * Returns 0 on success (desc filled), -ENODATA if no legacy attrs apply,
 * negative errno on validation failure.
 */
typedef int (*ib_umem_buf_desc_filler_t)(const struct uverbs_attr_bundle *attrs,
					 struct ib_uverbs_buffer_desc *desc);

/*
 * ib_umem_resolve_desc - Resolve a buffer descriptor from a per-command UMEM
 *                        attribute and/or a legacy attr filler.
 *
 * Return:
 *    0       @desc filled.
 *   -ENOENT  no source produced a buffer.
 *   -EINVAL  both the UMEM attribute and the legacy filler produced a buffer.

Annotation

Implementation Notes