drivers/gpu/drm/amd/ras/rascore/ras_umc.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/amd/ras/rascore/ras_umc.c- Extension
.c- Size
- 21403 bytes
- Lines
- 783
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
ras.hras_umc.hras_umc_v12_0.h
Detected Declarations
function filesfunction ras_umc_psp_convert_ma_to_pafunction ras_umc_log_eccfunction ras_umc_clear_logged_eccfunction ras_umc_convert_record_to_nps_pagesfunction ras_umc_reserve_eeprom_recordfunction listfunction ras_umc_log_pending_bad_bankfunction ras_umc_log_bad_bankfunction ras_umc_get_new_recordsfunction ras_umc_check_retired_recordfunction ras_umc_realloc_err_data_spacefunction ras_umc_update_eeprom_rom_datafunction ras_umc_update_eeprom_ram_datafunction ras_umc_add_bad_pagesfunction ras_umc_load_bad_pagesfunction ras_umc_save_bad_pagesfunction ras_umc_handle_bad_pagesfunction ras_umc_sw_initfunction ras_umc_sw_finifunction ras_umc_hw_initfunction ras_umc_hw_finifunction ras_umc_clean_badpage_datafunction ras_umc_fill_eeprom_recordfunction ras_umc_get_saved_eeprom_countfunction ras_umc_get_badpage_countfunction ras_umc_get_badpage_recordfunction ras_umc_check_retired_addrfunction ras_umc_translate_soc_pa_and_bank
Annotated Snippet
if (!ras_umc_log_bad_bank(ras_core, &ecc_node->ecc)) {
list_del(&ecc_node->node);
kfree(ecc_node);
if (ras_umc->pending_ecc_count)
ras_umc->pending_ecc_count--;
}
}
if (ras_umc->pending_ecc_dropped) {
RAS_DEV_WARN(ras_core->dev,
"%u pending ECC bad-bank events were dropped during GPU reset\n",
ras_umc->pending_ecc_dropped);
ras_umc->pending_ecc_dropped = 0;
}
mutex_unlock(&ras_umc->pending_ecc_lock);
return 0;
}
int ras_umc_log_bad_bank(struct ras_core_context *ras_core, struct ras_bank_ecc *bank)
{
struct ras_umc *ras_umc = &ras_core->ras_umc;
struct eeprom_umc_record umc_rec;
struct eeprom_umc_record *err_rec;
int ret;
memset(&umc_rec, 0, sizeof(umc_rec));
mutex_lock(&ras_umc->bank_log_lock);
ret = ras_umc->ip_func->bank_to_eeprom_record(ras_core, bank, &umc_rec);
if (ret)
goto out;
err_rec = kzalloc_obj(*err_rec);
if (!err_rec) {
ret = -ENOMEM;
goto out;
}
memcpy(err_rec, &umc_rec, sizeof(umc_rec));
ret = ras_umc_log_ecc(ras_core, err_rec->cur_nps_retired_row_pfn, err_rec);
if (ret) {
if (ret == -EEXIST) {
RAS_DEV_INFO(ras_core->dev, "The bad pages have been logged before.\n");
ret = 0;
}
kfree(err_rec);
goto out;
}
ras_umc_reserve_eeprom_record(ras_core, err_rec);
ret = ras_core_event_notify(ras_core,
RAS_EVENT_ID__BAD_PAGE_DETECTED, NULL);
out:
mutex_unlock(&ras_umc->bank_log_lock);
return ret;
}
static int ras_umc_get_new_records(struct ras_core_context *ras_core,
struct eeprom_umc_record *records, u32 num)
{
struct ras_umc *ras_umc = &ras_core->ras_umc;
struct eeprom_umc_record *entries[MAX_ECC_NUM_PER_RETIREMENT];
u32 entry_num = num < MAX_ECC_NUM_PER_RETIREMENT ? num : MAX_ECC_NUM_PER_RETIREMENT;
int count = 0;
int new_detected, i;
mutex_lock(&ras_umc->tree_lock);
new_detected = radix_tree_gang_lookup_tag(&ras_umc->root, (void **)entries,
0, entry_num, UMC_ECC_NEW_DETECTED_TAG);
for (i = 0; i < new_detected; i++) {
if (!entries[i])
continue;
memcpy(&records[i], entries[i], sizeof(struct eeprom_umc_record));
count++;
radix_tree_tag_clear(&ras_umc->root,
entries[i]->cur_nps_retired_row_pfn, UMC_ECC_NEW_DETECTED_TAG);
}
mutex_unlock(&ras_umc->tree_lock);
return count;
}
static bool ras_umc_check_retired_record(struct ras_core_context *ras_core,
struct eeprom_umc_record *record, bool from_eeprom)
{
struct ras_umc *ras_umc = &ras_core->ras_umc;
Annotation
- Immediate include surface: `ras.h`, `ras_umc.h`, `ras_umc_v12_0.h`.
- Detected declarations: `function files`, `function ras_umc_psp_convert_ma_to_pa`, `function ras_umc_log_ecc`, `function ras_umc_clear_logged_ecc`, `function ras_umc_convert_record_to_nps_pages`, `function ras_umc_reserve_eeprom_record`, `function list`, `function ras_umc_log_pending_bad_bank`, `function ras_umc_log_bad_bank`, `function ras_umc_get_new_records`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.