drivers/gpu/drm/xe/xe_guc_id_mgr.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_guc_id_mgr.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_guc_id_mgr.c
Extension
.c
Size
7328 bytes
Lines
281
Domain
Driver Families
Bucket
drivers/gpu
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 (weight) {
			struct drm_printer p = xe_gt_info_printer(idm_to_gt(idm));

			xe_gt_err(idm_to_gt(idm), "GUC ID manager unclean (%u/%u)\n",
				  weight, idm->total);
			idm_print_locked(idm, &p, 1);
		}
	}

	bitmap_free(idm->bitmap);
	idm->bitmap = NULL;
	idm->total = 0;
	idm->used = 0;

	mutex_unlock(idm_mutex(idm));
}

/**
 * xe_guc_id_mgr_init() - Initialize GuC context ID Manager.
 * @idm: the &xe_guc_id_mgr to initialize
 * @limit: number of IDs to manage
 *
 * The bare-metal or PF driver can pass ~0 as &limit to indicate that all
 * context IDs supported by the GuC firmware are available for use.
 *
 * Only VF drivers will have to provide explicit number of context IDs
 * that they can use.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_guc_id_mgr_init(struct xe_guc_id_mgr *idm, unsigned int limit)
{
	int ret;

	idm_assert(idm, !idm->bitmap);
	idm_assert(idm, !idm->total);
	idm_assert(idm, !idm->used);

	if (limit == ~0)
		limit = GUC_ID_MAX;
	else if (limit > GUC_ID_MAX)
		return -ERANGE;
	else if (!limit)
		return -EINVAL;

	idm->bitmap = bitmap_zalloc(limit, GFP_KERNEL);
	if (!idm->bitmap)
		return -ENOMEM;
	idm->total = limit;

	ret = drmm_add_action_or_reset(&idm_to_xe(idm)->drm, __fini_idm, idm);
	if (ret)
		return ret;

	xe_gt_dbg(idm_to_gt(idm), "using %u GuC ID%s\n",
		  idm->total, str_plural(idm->total));
	return 0;
}

static unsigned int find_last_zero_area(unsigned long *bitmap,
					unsigned int total,
					unsigned int count)
{
	unsigned int found = total;
	unsigned int rs, re, range;

	for_each_clear_bitrange(rs, re, bitmap, total) {
		range = re - rs;
		if (range < count)
			continue;
		found = rs + (range - count);
	}
	return found;
}

static int idm_reserve_chunk_locked(struct xe_guc_id_mgr *idm,
				    unsigned int count, unsigned int retain)
{
	int id;

	idm_assert(idm, count);
	lockdep_assert_held(idm_mutex(idm));

	if (!idm->total)
		return -ENODATA;

	if (retain) {
		/*
		 * For IDs reservations (used on PF for VFs) we want to make
		 * sure there will be at least 'retain' available for the PF

Annotation

Implementation Notes