arch/powerpc/platforms/powernv/subcore.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/subcore.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powernv/subcore.c- Extension
.c- Size
- 11282 bytes
- Lines
- 452
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/cpu.hlinux/cpumask.hlinux/device.hlinux/gfp.hlinux/smp.hlinux/stop_machine.hlinux/sysfs.hasm/cputhreads.hasm/cpuidle.hasm/kvm_ppc.hasm/machdep.hasm/opal.hasm/smp.htrace/events/ipi.hsubcore.hpowernv.h
Detected Declarations
struct split_statefunction wait_for_sync_stepfunction update_hid_in_slwfunction update_power8_hid0function unsplit_corefunction split_corefunction cpu_do_splitfunction cpu_core_split_requiredfunction update_subcore_sibling_maskfunction for_each_possible_cpufunction cpu_update_split_modefunction set_subcores_per_corefunction for_each_present_cpufunction store_subcores_per_corefunction show_subcores_per_corefunction subcore_init
Annotated Snippet
struct split_state {
u8 step;
u8 master;
};
static DEFINE_PER_CPU(struct split_state, split_state);
static void wait_for_sync_step(int step)
{
int i, cpu = smp_processor_id();
for (i = cpu + 1; i < cpu + threads_per_core; i++)
while(per_cpu(split_state, i).step < step)
barrier();
/* Order the wait loop vs any subsequent loads/stores. */
mb();
}
static void update_hid_in_slw(u64 hid0)
{
u64 idle_states = pnv_get_supported_cpuidle_states();
if (idle_states & OPAL_PM_WINKLE_ENABLED) {
/* OPAL call to patch slw with the new HID0 value */
u64 cpu_pir = hard_smp_processor_id();
opal_slw_set_reg(cpu_pir, SPRN_HID0, hid0);
}
}
static inline void update_power8_hid0(unsigned long hid0)
{
/*
* The HID0 update on Power8 should at the very least be
* preceded by a SYNC instruction followed by an ISYNC
* instruction
*/
asm volatile("sync; mtspr %0,%1; isync":: "i"(SPRN_HID0), "r"(hid0));
}
static void unsplit_core(void)
{
u64 hid0, mask;
int i, cpu;
mask = HID0_POWER8_2LPARMODE | HID0_POWER8_4LPARMODE;
cpu = smp_processor_id();
if (cpu_thread_in_core(cpu) != 0) {
while (mfspr(SPRN_HID0) & mask)
power7_idle_type(PNV_THREAD_NAP);
per_cpu(split_state, cpu).step = SYNC_STEP_UNSPLIT;
return;
}
hid0 = mfspr(SPRN_HID0);
hid0 &= ~HID0_POWER8_DYNLPARDIS;
update_power8_hid0(hid0);
update_hid_in_slw(hid0);
while (mfspr(SPRN_HID0) & mask)
cpu_relax();
/* Wake secondaries out of NAP */
for (i = cpu + 1; i < cpu + threads_per_core; i++)
smp_send_reschedule(i);
wait_for_sync_step(SYNC_STEP_UNSPLIT);
}
static void split_core(int new_mode)
{
struct { u64 value; u64 mask; } split_parms[2] = {
{ HID0_POWER8_1TO2LPAR, HID0_POWER8_2LPARMODE },
{ HID0_POWER8_1TO4LPAR, HID0_POWER8_4LPARMODE }
};
int i, cpu;
u64 hid0;
/* Convert new_mode (2 or 4) into an index into our parms array */
i = (new_mode >> 1) - 1;
BUG_ON(i < 0 || i > 1);
cpu = smp_processor_id();
if (cpu_thread_in_core(cpu) != 0) {
split_core_secondary_loop(&per_cpu(split_state, cpu).step);
return;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/cpu.h`, `linux/cpumask.h`, `linux/device.h`, `linux/gfp.h`, `linux/smp.h`, `linux/stop_machine.h`, `linux/sysfs.h`.
- Detected declarations: `struct split_state`, `function wait_for_sync_step`, `function update_hid_in_slw`, `function update_power8_hid0`, `function unsplit_core`, `function split_core`, `function cpu_do_split`, `function cpu_core_split_required`, `function update_subcore_sibling_mask`, `function for_each_possible_cpu`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration 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.