arch/x86/events/intel/uncore_discovery.c
Source file repositories/reference/linux-study-clean/arch/x86/events/intel/uncore_discovery.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/events/intel/uncore_discovery.c- Extension
.c- Size
- 19992 bytes
- Lines
- 811
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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
asm/msr.huncore.huncore_discovery.h
Detected Declarations
function get_device_die_idfunction __type_cmpfunction search_uncore_discovery_typefunction __type_lessfunction add_uncore_discovery_typefunction get_uncore_discovery_typefunction pmu_idx_cmpfunction intel_uncore_find_discovery_unitfunction intel_uncore_find_discovery_unit_idfunction unit_lessfunction uncore_find_unitfunction uncore_find_add_unitfunction uncore_insert_box_infofunction uncore_ignore_unitfunction __parse_discovery_tablefunction parse_discovery_tablefunction uncore_discovery_pcifunction uncore_discovery_msrfunction for_each_online_cpufunction uncore_discoveryfunction intel_uncore_clear_discovery_tablesfunction rbtree_postorder_for_each_entry_safefunction intel_generic_uncore_box_ctlfunction intel_generic_uncore_msr_init_boxfunction intel_generic_uncore_msr_disable_boxfunction intel_generic_uncore_msr_enable_boxfunction intel_generic_uncore_msr_enable_eventfunction intel_generic_uncore_msr_disable_eventfunction intel_generic_uncore_assign_hw_eventfunction intel_pci_uncore_box_ctlfunction intel_generic_uncore_pci_init_boxfunction intel_generic_uncore_pci_disable_boxfunction intel_generic_uncore_pci_enable_boxfunction intel_generic_uncore_pci_enable_eventfunction intel_generic_uncore_pci_disable_eventfunction intel_generic_uncore_pci_read_counterfunction intel_generic_uncore_mmio_init_boxfunction intel_generic_uncore_mmio_disable_boxfunction intel_generic_uncore_mmio_enable_boxfunction intel_generic_uncore_mmio_enable_eventfunction intel_generic_uncore_mmio_disable_eventfunction uncore_update_uncore_typefunction intel_uncore_generic_init_uncoresfunction intel_uncore_generic_uncore_cpu_initfunction intel_uncore_generic_uncore_pci_initfunction intel_uncore_generic_uncore_mmio_init
Annotated Snippet
while ((dvsec = pci_find_next_ext_capability(dev, dvsec, UNCORE_EXT_CAP_ID_DISCOVERY))) {
pci_read_config_dword(dev, dvsec + UNCORE_DISCOVERY_DVSEC_OFFSET, &val);
entry_id = val & UNCORE_DISCOVERY_DVSEC_ID_MASK;
if (entry_id != UNCORE_DISCOVERY_DVSEC_ID_PMON)
continue;
pci_read_config_dword(dev, dvsec + UNCORE_DISCOVERY_DVSEC2_OFFSET, &val);
if (val & ~UNCORE_DISCOVERY_DVSEC2_BIR_MASK) {
ret = false;
goto err;
}
bar_offset = UNCORE_DISCOVERY_BIR_BASE +
(val & UNCORE_DISCOVERY_DVSEC2_BIR_MASK) * UNCORE_DISCOVERY_BIR_STEP;
die = get_device_die_id(dev);
if ((die < 0) || (die >= uncore_max_dies()))
continue;
parse_discovery_table(domain, dev, die, bar_offset, &parsed);
}
}
/* None of the discovery tables are available */
if (!parsed)
ret = false;
err:
pci_dev_put(dev);
return ret;
}
static bool uncore_discovery_msr(struct uncore_discovery_domain *domain)
{
unsigned long *die_mask;
bool parsed = false;
int cpu, die;
u64 base;
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
sizeof(unsigned long), GFP_KERNEL);
if (!die_mask)
return false;
for_each_online_cpu(cpu) {
die = topology_logical_die_id(cpu);
if (__test_and_set_bit(die, die_mask))
continue;
if (rdmsrq_safe_on_cpu(cpu, domain->discovery_base, &base))
continue;
if (!base)
continue;
__parse_discovery_table(domain, base, die, &parsed);
}
kfree(die_mask);
return parsed;
}
bool uncore_discovery(struct uncore_plat_init *init)
{
struct uncore_discovery_domain *domain;
bool ret = false;
int i;
for (i = 0; i < UNCORE_DISCOVERY_DOMAINS; i++) {
domain = &init->domain[i];
if (domain->discovery_base) {
cpus_read_lock();
if (!domain->base_is_pci)
ret |= uncore_discovery_msr(domain);
else
ret |= uncore_discovery_pci(domain);
cpus_read_unlock();
}
}
return ret;
}
void intel_uncore_clear_discovery_tables(void)
{
struct intel_uncore_discovery_type *type, *next;
struct intel_uncore_discovery_unit *pos;
struct rb_node *node;
Annotation
- Immediate include surface: `asm/msr.h`, `uncore.h`, `uncore_discovery.h`.
- Detected declarations: `function get_device_die_id`, `function __type_cmp`, `function search_uncore_discovery_type`, `function __type_less`, `function add_uncore_discovery_type`, `function get_uncore_discovery_type`, `function pmu_idx_cmp`, `function intel_uncore_find_discovery_unit`, `function intel_uncore_find_discovery_unit_id`, `function unit_less`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
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.