drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c
Extension
.c
Size
9363 bytes
Lines
315
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 (data) {
				mempool_free(data, log_ring->ras_log_mempool);
				log_ring->logged_ecc_count--;
				i++;
			}
		}
		batch_id = ++log_ring->last_del_batch_id;
		if (i >= count) {
			ret = 0;
			break;
		}
	}
	spin_unlock_irqrestore(&log_ring->spin_lock, flags);

	return ret;
}

static void ras_log_ring_clear_log_tree(struct ras_core_context *ras_core)
{
	struct ras_log_ring *log_ring = &ras_core->ras_log_ring;
	uint64_t batch_id, idx;
	unsigned long flags = 0;
	void *data;
	int j;

	if ((log_ring->mono_upward_batch_id <= log_ring->last_del_batch_id) &&
		!log_ring->logged_ecc_count)
		return;

	spin_lock_irqsave(&log_ring->spin_lock, flags);
	batch_id = log_ring->last_del_batch_id;
	while (batch_id < log_ring->mono_upward_batch_id) {
		for (j = 0; j < MAX_RECORD_PER_BATCH; j++) {
			idx = BATCH_IDX_TO_TREE_IDX(batch_id, j);
			data = radix_tree_delete(&log_ring->ras_log_root, idx);
			if (data) {
				mempool_free(data, log_ring->ras_log_mempool);
				log_ring->logged_ecc_count--;
			}
		}
		batch_id++;
	}
	spin_unlock_irqrestore(&log_ring->spin_lock, flags);

}

int ras_log_ring_sw_init(struct ras_core_context *ras_core)
{
	struct ras_log_ring *log_ring = &ras_core->ras_log_ring;

	memset(log_ring, 0, sizeof(*log_ring));

	log_ring->ras_log_mempool = mempool_create_kmalloc_pool(
			RAS_LOG_MEMPOOL_SIZE, sizeof(struct ras_log_info));
	if (!log_ring->ras_log_mempool)
		return -ENOMEM;

	INIT_RADIX_TREE(&log_ring->ras_log_root, GFP_KERNEL);

	spin_lock_init(&log_ring->spin_lock);

	return 0;
}

int ras_log_ring_sw_fini(struct ras_core_context *ras_core)
{
	struct ras_log_ring *log_ring = &ras_core->ras_log_ring;

	ras_log_ring_clear_log_tree(ras_core);
	log_ring->logged_ecc_count = 0;
	log_ring->last_del_batch_id = 0;
	log_ring->mono_upward_batch_id = 0;

	mempool_destroy(log_ring->ras_log_mempool);

	return 0;
}

struct ras_log_batch_tag *ras_log_ring_create_batch_tag(struct ras_core_context *ras_core)
{
	struct ras_log_ring *log_ring = &ras_core->ras_log_ring;
	struct ras_log_batch_tag *batch_tag;
	unsigned long flags = 0;

	batch_tag = kzalloc_obj(*batch_tag);
	if (!batch_tag)
		return NULL;

	spin_lock_irqsave(&log_ring->spin_lock, flags);
	batch_tag->batch_id = log_ring->mono_upward_batch_id;

Annotation

Implementation Notes