drivers/md/dm-vdo/priority-table.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/priority-table.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/priority-table.c
Extension
.c
Size
6565 bytes
Lines
224
Domain
Driver Families
Bucket
drivers/md
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 bucket {
	/*
	 * The head of a queue of table entries, all having the same priority
	 */
	struct list_head queue;
	/* The priority of all the entries in this bucket */
	unsigned int priority;
};

/*
 * A priority table is an array of buckets, indexed by priority. New entries are added to the end
 * of the queue in the appropriate bucket. The dequeue operation finds the highest-priority
 * non-empty bucket by searching a bit vector represented as a single 8-byte word, which is very
 * fast with compiler and CPU support.
 */
struct priority_table {
	/* The maximum priority of entries that may be stored in this table */
	unsigned int max_priority;
	/* A bit vector flagging all buckets that are currently non-empty */
	u64 search_vector;
	/* The array of all buckets, indexed by priority */
	struct bucket buckets[];
};

/**
 * vdo_make_priority_table() - Allocate and initialize a new priority_table.
 * @max_priority: The maximum priority value for table entries.
 * @table_ptr: A pointer to hold the new table.
 *
 * Return: VDO_SUCCESS or an error code.
 */
int vdo_make_priority_table(unsigned int max_priority, struct priority_table **table_ptr)
{
	struct priority_table *table;
	int result;
	unsigned int priority;

	if (max_priority > MAX_PRIORITY)
		return UDS_INVALID_ARGUMENT;

	result = vdo_allocate_extended(max_priority + 1, buckets, __func__, &table);
	if (result != VDO_SUCCESS)
		return result;

	for (priority = 0; priority <= max_priority; priority++) {
		struct bucket *bucket = &table->buckets[priority];

		bucket->priority = priority;
		INIT_LIST_HEAD(&bucket->queue);
	}

	table->max_priority = max_priority;
	table->search_vector = 0;

	*table_ptr = table;
	return VDO_SUCCESS;
}

/**
 * vdo_free_priority_table() - Free a priority_table.
 * @table: The table to free.
 *
 * The table does not own the entries stored in it and they are not freed by this call.
 */
void vdo_free_priority_table(struct priority_table *table)
{
	if (table == NULL)
		return;

	/*
	 * Unlink the buckets from any entries still in the table so the entries won't be left with
	 * dangling pointers to freed memory.
	 */
	vdo_reset_priority_table(table);

	vdo_free(table);
}

/**
 * vdo_reset_priority_table() - Reset a priority table, leaving it in the same empty state as when
 *                          newly constructed.
 * @table: The table to reset.
 *
 * The table does not own the entries stored in it and they are not freed (or even unlinked from
 * each other) by this call.
 */
void vdo_reset_priority_table(struct priority_table *table)
{
	unsigned int priority;

Annotation

Implementation Notes