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.

Dependency Surface

Detected Declarations

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

Implementation Notes