arch/x86/events/intel/uncore.c
Source file repositories/reference/linux-study-clean/arch/x86/events/intel/uncore.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/events/intel/uncore.c- Extension
.c- Size
- 52266 bytes
- Lines
- 2057
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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
linux/module.hasm/cpu_device_id.hasm/intel-family.hasm/msr.huncore.huncore_discovery.h
Detected Declarations
function uncore_pcibus_to_dieidfunction uncore_die_to_segmentfunction uncore_device_to_diefunction for_each_cpufunction cpus_read_lockfunction for_each_online_cpufunction uncore_free_pcibus_mapfunction list_for_each_entry_safefunction uncore_event_showfunction uncore_msr_read_counterfunction uncore_mmio_exit_boxfunction uncore_mmio_read_counterfunction uncore_get_constraintfunction uncore_put_constraintfunction uncore_shared_reg_configfunction uncore_assign_hw_eventfunction uncore_perf_event_updatefunction uncore_pmu_hrtimerfunction uncore_pmu_start_hrtimerfunction uncore_pmu_cancel_hrtimerfunction uncore_pmu_init_hrtimerfunction is_box_eventfunction uncore_collect_eventsfunction for_each_sibling_eventfunction uncore_get_event_constraintfunction uncore_put_event_constraintfunction uncore_assign_eventsfunction uncore_pmu_event_startfunction uncore_pmu_event_stopfunction uncore_pmu_event_addfunction event_initfunction uncore_pmu_event_delfunction uncore_pmu_event_readfunction uncore_validate_groupfunction uncore_pmu_event_initfunction uncore_pmu_enablefunction uncore_pmu_disablefunction uncore_get_attr_cpumaskfunction uncore_get_box_idfunction uncore_get_alias_namefunction uncore_get_pmu_namefunction uncore_pmu_registerfunction uncore_pmu_unregisterfunction uncore_free_boxesfunction uncore_type_exitfunction uncore_types_exitfunction uncore_type_initfunction uncore_types_init
Annotated Snippet
struct pci_driver *uncore_pci_driver;
/* The PCI driver for the device which the uncore doesn't own. */
struct pci_driver *uncore_pci_sub_driver;
/* pci bus to socket mapping */
DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
struct pci_extra_dev *uncore_extra_pci_dev;
int __uncore_max_dies;
/* mask of cpus that collect uncore events */
static cpumask_t uncore_cpu_mask;
/* constraint for the fixed counter */
static struct event_constraint uncore_constraint_fixed =
EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
struct event_constraint uncore_constraint_empty =
EVENT_CONSTRAINT(0, 0, 0);
MODULE_DESCRIPTION("Support for Intel uncore performance events");
MODULE_LICENSE("GPL");
int uncore_pcibus_to_dieid(struct pci_bus *bus)
{
struct pci2phy_map *map;
int die_id = -1;
raw_spin_lock(&pci2phy_map_lock);
list_for_each_entry(map, &pci2phy_map_head, list) {
if (map->segment == pci_domain_nr(bus)) {
die_id = map->pbus_to_dieid[bus->number];
break;
}
}
raw_spin_unlock(&pci2phy_map_lock);
return die_id;
}
int uncore_die_to_segment(int die)
{
struct pci_bus *bus = NULL;
/* Find first pci bus which attributes to specified die. */
while ((bus = pci_find_next_bus(bus)) &&
(die != uncore_pcibus_to_dieid(bus)))
;
return bus ? pci_domain_nr(bus) : -EINVAL;
}
/* Note: This API can only be used when NUMA information is available. */
int uncore_device_to_die(struct pci_dev *dev)
{
int node = pcibus_to_node(dev->bus);
int cpu;
for_each_cpu(cpu, cpumask_of_pcibus(dev->bus)) {
struct cpuinfo_x86 *c = &cpu_data(cpu);
if (c->initialized && cpu_to_node(cpu) == node)
return c->topo.logical_die_id;
}
return -1;
}
/*
* Using cpus_read_lock() to ensure cpu is not going down between
* looking at cpu_online_mask.
*
* The lock must be held by the caller.
*/
int uncore_die_to_cpu(int die)
{
int res = -1, cpu;
for_each_online_cpu(cpu) {
if (topology_logical_die_id(cpu) == die) {
res = cpu;
break;
}
}
return res;
}
static void uncore_free_pcibus_map(void)
{
struct pci2phy_map *map, *tmp;
list_for_each_entry_safe(map, tmp, &pci2phy_map_head, list) {
Annotation
- Immediate include surface: `linux/module.h`, `asm/cpu_device_id.h`, `asm/intel-family.h`, `asm/msr.h`, `uncore.h`, `uncore_discovery.h`.
- Detected declarations: `function uncore_pcibus_to_dieid`, `function uncore_die_to_segment`, `function uncore_device_to_die`, `function for_each_cpu`, `function cpus_read_lock`, `function for_each_online_cpu`, `function uncore_free_pcibus_map`, `function list_for_each_entry_safe`, `function uncore_event_show`, `function uncore_msr_read_counter`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: pattern 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.