arch/powerpc/platforms/pseries/hotplug-cpu.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/pseries/hotplug-cpu.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/pseries/hotplug-cpu.c- Extension
.c- Size
- 20202 bytes
- Lines
- 905
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/interrupt.hlinux/delay.hlinux/sched.hlinux/sched/hotplug.hlinux/cpu.hlinux/of.hlinux/slab.hasm/prom.hasm/rtas.hasm/firmware.hasm/machdep.hasm/vdso_datapage.hasm/xics.hasm/xive.hasm/plpar_wrappers.hasm/topology.hasm/systemcfg.hpseries.h
Detected Declarations
function rtas_stop_selffunction pseries_cpu_offline_selffunction pseries_cpu_disablefunction pseries_cpu_diefunction find_cpu_id_rangefunction pacafunction for_each_cpufunction for_each_online_nodefunction pacafunction for_each_present_cpufunction dlpar_offline_cpufunction for_each_present_cpufunction device_offlinefunction dlpar_online_cpufunction for_each_present_cpufunction dlpar_cpu_existsfunction for_each_child_of_nodefunction drc_info_valid_indexfunction valid_cpu_drc_indexfunction pseries_cpuhp_attach_nodesfunction dlpar_cpu_addfunction pseries_cpuhp_cache_use_countfunction for_each_of_cpu_nodefunction for_each_node_by_typefunction pseries_cpuhp_detach_nodesfunction dlpar_cpu_removefunction for_each_node_by_typefunction dlpar_cpu_remove_by_indexfunction dlpar_cpufunction dlpar_cpu_probefunction dlpar_cpu_releasefunction pseries_smp_notifierfunction pseries_cpu_hotplug_initfunction pseries_dlpar_initfunction for_each_node
Annotated Snippet
if (time_after(jiffies, timeout)) {
pr_warn("CPU %i (hwid %i) didn't die after 120 seconds\n",
cpu, pcpu);
timeout = jiffies + msecs_to_jiffies(120000);
}
cond_resched();
}
if (cpu_status == QCSS_HARDWARE_ERROR) {
pr_warn("CPU %i (hwid %i) reported error while dying\n",
cpu, pcpu);
}
paca_ptrs[cpu]->cpu_start = 0;
}
/**
* find_cpu_id_range - found a linear ranger of @nthreads free CPU ids.
* @nthreads : the number of threads (cpu ids)
* @assigned_node : the node it belongs to or NUMA_NO_NODE if free ids from any
* node can be peek.
* @cpu_mask: the returned CPU mask.
*
* Returns 0 on success.
*/
static int find_cpu_id_range(unsigned int nthreads, int assigned_node,
cpumask_var_t *cpu_mask)
{
cpumask_var_t candidate_mask;
unsigned int cpu, node;
int rc = -ENOSPC;
if (!zalloc_cpumask_var(&candidate_mask, GFP_KERNEL))
return -ENOMEM;
cpumask_clear(*cpu_mask);
for (cpu = 0; cpu < nthreads; cpu++)
cpumask_set_cpu(cpu, *cpu_mask);
BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask));
/* Get a bitmap of unoccupied slots. */
cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask);
if (assigned_node != NUMA_NO_NODE) {
/*
* Remove free ids previously assigned on the other nodes. We
* can walk only online nodes because once a node became online
* it is not turned offlined back.
*/
for_each_online_node(node) {
if (node == assigned_node)
continue;
cpumask_andnot(candidate_mask, candidate_mask,
node_recorded_ids_map[node]);
}
}
if (cpumask_empty(candidate_mask))
goto out;
while (!cpumask_empty(*cpu_mask)) {
if (cpumask_subset(*cpu_mask, candidate_mask))
/* Found a range where we can insert the new cpu(s) */
break;
cpumask_shift_left(*cpu_mask, *cpu_mask, nthreads);
}
if (!cpumask_empty(*cpu_mask))
rc = 0;
out:
free_cpumask_var(candidate_mask);
return rc;
}
/*
* Update cpu_present_mask and paca(s) for a new cpu node. The wrinkle
* here is that a cpu device node may represent multiple logical cpus
* in the SMT case. We must honor the assumption in other code that
* the logical ids for sibling SMT threads x and y are adjacent, such
* that x^1 == y and y^1 == x.
*/
static int pseries_add_processor(struct device_node *np)
{
int len, nthreads, node, cpu, assigned_node;
int rc = 0;
cpumask_var_t cpu_mask;
const __be32 *intserv;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/interrupt.h`, `linux/delay.h`, `linux/sched.h`, `linux/sched/hotplug.h`, `linux/cpu.h`, `linux/of.h`, `linux/slab.h`.
- Detected declarations: `function rtas_stop_self`, `function pseries_cpu_offline_self`, `function pseries_cpu_disable`, `function pseries_cpu_die`, `function find_cpu_id_range`, `function paca`, `function for_each_cpu`, `function for_each_online_node`, `function paca`, `function for_each_present_cpu`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.