drivers/infiniband/hw/mthca/mthca_profile.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mthca/mthca_profile.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mthca/mthca_profile.c
Extension
.c
Size
9205 bytes
Lines
280
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 mthca_resource {
		u64 size;
		u64 start;
		int type;
		int num;
		int log_num;
	};

	u64 mem_base, mem_avail;
	s64 total_size = 0;
	struct mthca_resource *profile;
	int i, j;

	profile = kzalloc_objs(*profile, MTHCA_RES_NUM);
	if (!profile)
		return -ENOMEM;

	profile[MTHCA_RES_QP].size   = dev_lim->qpc_entry_sz;
	profile[MTHCA_RES_EEC].size  = dev_lim->eec_entry_sz;
	profile[MTHCA_RES_SRQ].size  = dev_lim->srq_entry_sz;
	profile[MTHCA_RES_CQ].size   = dev_lim->cqc_entry_sz;
	profile[MTHCA_RES_EQP].size  = dev_lim->eqpc_entry_sz;
	profile[MTHCA_RES_EEEC].size = dev_lim->eeec_entry_sz;
	profile[MTHCA_RES_EQ].size   = dev_lim->eqc_entry_sz;
	profile[MTHCA_RES_RDB].size  = MTHCA_RDB_ENTRY_SIZE;
	profile[MTHCA_RES_MCG].size  = MTHCA_MGM_ENTRY_SIZE;
	profile[MTHCA_RES_MPT].size  = dev_lim->mpt_entry_sz;
	profile[MTHCA_RES_MTT].size  = dev->limits.mtt_seg_size;
	profile[MTHCA_RES_UAR].size  = dev_lim->uar_scratch_entry_sz;
	profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
	profile[MTHCA_RES_UARC].size = request->uarc_size;

	profile[MTHCA_RES_QP].num    = request->num_qp;
	profile[MTHCA_RES_SRQ].num   = request->num_srq;
	profile[MTHCA_RES_EQP].num   = request->num_qp;
	profile[MTHCA_RES_RDB].num   = request->num_qp * request->rdb_per_qp;
	profile[MTHCA_RES_CQ].num    = request->num_cq;
	profile[MTHCA_RES_EQ].num    = MTHCA_NUM_EQS;
	profile[MTHCA_RES_MCG].num   = request->num_mcg;
	profile[MTHCA_RES_MPT].num   = request->num_mpt;
	profile[MTHCA_RES_MTT].num   = request->num_mtt;
	profile[MTHCA_RES_UAR].num   = request->num_uar;
	profile[MTHCA_RES_UARC].num  = request->num_uar;
	profile[MTHCA_RES_UDAV].num  = request->num_udav;

	for (i = 0; i < MTHCA_RES_NUM; ++i) {
		profile[i].type     = i;
		profile[i].log_num  = max(ffs(profile[i].num) - 1, 0);
		profile[i].size    *= profile[i].num;
		if (mthca_is_memfree(dev))
			profile[i].size = max(profile[i].size, (u64) PAGE_SIZE);
	}

	if (mthca_is_memfree(dev)) {
		mem_base  = 0;
		mem_avail = dev_lim->hca.arbel.max_icm_sz;
	} else {
		mem_base  = dev->ddr_start;
		mem_avail = dev->fw.tavor.fw_start - dev->ddr_start;
	}

	/*
	 * Sort the resources in decreasing order of size.  Since they
	 * all have sizes that are powers of 2, we'll be able to keep
	 * resources aligned to their size and pack them without gaps
	 * using the sorted order.
	 */
	for (i = MTHCA_RES_NUM; i > 0; --i)
		for (j = 1; j < i; ++j) {
			if (profile[j].size > profile[j - 1].size)
				swap(profile[j], profile[j - 1]);
		}

	for (i = 0; i < MTHCA_RES_NUM; ++i) {
		if (profile[i].size) {
			profile[i].start = mem_base + total_size;
			total_size      += profile[i].size;
		}
		if (total_size > mem_avail) {
			mthca_err(dev, "Profile requires 0x%llx bytes; "
				  "won't fit in 0x%llx bytes of context memory.\n",
				  (unsigned long long) total_size,
				  (unsigned long long) mem_avail);
			kfree(profile);
			return -ENOMEM;
		}

		if (profile[i].size)
			mthca_dbg(dev, "profile[%2d]--%2d/%2d @ 0x%16llx "
				  "(size 0x%8llx)\n",

Annotation

Implementation Notes