drivers/base/cpu.c

Source file repositories/reference/linux-study-clean/drivers/base/cpu.c

File Facts

System
Linux kernel
Corpus path
drivers/base/cpu.c
Extension
.c
Size
18180 bytes
Lines
697
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static int cpu_subsys_match(struct device *dev, const struct device_driver *drv)
{
	/* ACPI style match is the only one that may succeed. */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
static void change_cpu_under_node(struct cpu *cpu,
			unsigned int from_nid, unsigned int to_nid)
{
	int cpuid = cpu->dev.id;
	unregister_cpu_under_node(cpuid, from_nid);
	register_cpu_under_node(cpuid, to_nid);
	cpu->node_id = to_nid;
}

static int cpu_subsys_online(struct device *dev)
{
	struct cpu *cpu = container_of(dev, struct cpu, dev);
	int cpuid = dev->id;
	int from_nid, to_nid;
	int ret;
	int retries = 0;

	from_nid = cpu_to_node(cpuid);
	if (from_nid == NUMA_NO_NODE)
		return -ENODEV;

retry:
	ret = cpu_device_up(dev);

	/*
	 * If -EBUSY is returned, it is likely that hotplug is temporarily
	 * disabled when cpu_hotplug_disable() was called. This condition is
	 * transient. So we retry after waiting for an exponentially
	 * increasing delay up to a total of at least 620ms as some PCI
	 * device initialization can take quite a while.
	 */
	if (ret == -EBUSY) {
		retries++;
		if (retries > 5)
			return ret;
		msleep(10 * (1 << retries));
		goto retry;
	}

	/*
	 * When hot adding memory to memoryless node and enabling a cpu
	 * on the node, node number of the cpu may internally change.
	 */
	to_nid = cpu_to_node(cpuid);
	if (from_nid != to_nid)
		change_cpu_under_node(cpu, from_nid, to_nid);

	return ret;
}

static int cpu_subsys_offline(struct device *dev)
{
	return cpu_device_down(dev);
}

void unregister_cpu(struct cpu *cpu)
{
	int logical_cpu = cpu->dev.id;

	set_cpu_enabled(logical_cpu, false);
	unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));

	device_unregister(&cpu->dev);
	per_cpu(cpu_sys_devices, logical_cpu) = NULL;
	return;
}

#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t cpu_probe_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf,
			       size_t count)
{
	ssize_t cnt;
	int ret;

	ret = lock_device_hotplug_sysfs();
	if (ret)
		return ret;

Annotation

Implementation Notes