Skip to content

Commit 4d73704

Browse files
Boris OstrovskyDavid Vrabel
authored andcommitted
xen/x86: Convert to hotplug state machine
Switch to new CPU hotplug infrastructure. Signed-off-by: Boris Ostrovsky <[email protected]> Suggested-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: David Vrabel <[email protected]>
1 parent 8129554 commit 4d73704

File tree

2 files changed

+66
-50
lines changed

2 files changed

+66
-50
lines changed

arch/x86/xen/enlighten.c

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
140140
__read_mostly int xen_have_vector_callback;
141141
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
142142

143-
static struct notifier_block xen_cpu_notifier;
143+
static int xen_cpu_up_prepare(unsigned int cpu);
144+
static int xen_cpu_up_online(unsigned int cpu);
145+
static int xen_cpu_dead(unsigned int cpu);
144146

145147
/*
146148
* Point at some empty memory to start with. We map the real shared_info
@@ -1541,6 +1543,24 @@ static void __init xen_dom0_set_legacy_features(void)
15411543
x86_platform.legacy.rtc = 1;
15421544
}
15431545

1546+
static int xen_cpuhp_setup(void)
1547+
{
1548+
int rc;
1549+
1550+
rc = cpuhp_setup_state_nocalls(CPUHP_XEN_PREPARE,
1551+
"XEN_HVM_GUEST_PREPARE",
1552+
xen_cpu_up_prepare, xen_cpu_dead);
1553+
if (rc >= 0) {
1554+
rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
1555+
"XEN_HVM_GUEST_ONLINE",
1556+
xen_cpu_up_online, NULL);
1557+
if (rc < 0)
1558+
cpuhp_remove_state_nocalls(CPUHP_XEN_PREPARE);
1559+
}
1560+
1561+
return rc >= 0 ? 0 : rc;
1562+
}
1563+
15441564
/* First C function to be called on Xen boot */
15451565
asmlinkage __visible void __init xen_start_kernel(void)
15461566
{
@@ -1629,7 +1649,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
16291649
xen_initial_gdt = &per_cpu(gdt_page, 0);
16301650

16311651
xen_smp_init();
1632-
register_cpu_notifier(&xen_cpu_notifier);
1652+
WARN_ON(xen_cpuhp_setup());
16331653

16341654
#ifdef CONFIG_ACPI_NUMA
16351655
/*
@@ -1823,63 +1843,58 @@ static void __init init_hvm_pv_info(void)
18231843
xen_domain_type = XEN_HVM_DOMAIN;
18241844
}
18251845

1826-
static int xen_cpu_notify(struct notifier_block *self, unsigned long action,
1827-
void *hcpu)
1846+
static int xen_cpu_up_prepare(unsigned int cpu)
18281847
{
1829-
int cpu = (long)hcpu;
18301848
int rc;
18311849

1832-
switch (action) {
1833-
case CPU_UP_PREPARE:
1834-
if (xen_hvm_domain()) {
1835-
/*
1836-
* This can happen if CPU was offlined earlier and
1837-
* offlining timed out in common_cpu_die().
1838-
*/
1839-
if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) {
1840-
xen_smp_intr_free(cpu);
1841-
xen_uninit_lock_cpu(cpu);
1842-
}
1843-
1844-
if (cpu_acpi_id(cpu) != U32_MAX)
1845-
per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
1846-
else
1847-
per_cpu(xen_vcpu_id, cpu) = cpu;
1848-
xen_vcpu_setup(cpu);
1850+
if (xen_hvm_domain()) {
1851+
/*
1852+
* This can happen if CPU was offlined earlier and
1853+
* offlining timed out in common_cpu_die().
1854+
*/
1855+
if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) {
1856+
xen_smp_intr_free(cpu);
1857+
xen_uninit_lock_cpu(cpu);
18491858
}
18501859

1851-
if (xen_pv_domain() ||
1852-
(xen_have_vector_callback &&
1853-
xen_feature(XENFEAT_hvm_safe_pvclock)))
1854-
xen_setup_timer(cpu);
1860+
if (cpu_acpi_id(cpu) != U32_MAX)
1861+
per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
1862+
else
1863+
per_cpu(xen_vcpu_id, cpu) = cpu;
1864+
xen_vcpu_setup(cpu);
1865+
}
18551866

1856-
rc = xen_smp_intr_init(cpu);
1857-
if (rc) {
1858-
WARN(1, "xen_smp_intr_init() for CPU %d failed: %d\n",
1859-
cpu, rc);
1860-
return NOTIFY_BAD;
1861-
}
1867+
if (xen_pv_domain() ||
1868+
(xen_have_vector_callback &&
1869+
xen_feature(XENFEAT_hvm_safe_pvclock)))
1870+
xen_setup_timer(cpu);
18621871

1863-
break;
1864-
case CPU_ONLINE:
1865-
xen_init_lock_cpu(cpu);
1866-
break;
1867-
case CPU_UP_CANCELED:
1868-
xen_smp_intr_free(cpu);
1869-
if (xen_pv_domain() ||
1870-
(xen_have_vector_callback &&
1871-
xen_feature(XENFEAT_hvm_safe_pvclock)))
1872-
xen_teardown_timer(cpu);
1873-
break;
1874-
default:
1875-
break;
1872+
rc = xen_smp_intr_init(cpu);
1873+
if (rc) {
1874+
WARN(1, "xen_smp_intr_init() for CPU %d failed: %d\n",
1875+
cpu, rc);
1876+
return rc;
18761877
}
1877-
return NOTIFY_OK;
1878+
return 0;
18781879
}
18791880

1880-
static struct notifier_block xen_cpu_notifier = {
1881-
.notifier_call = xen_cpu_notify,
1882-
};
1881+
static int xen_cpu_dead(unsigned int cpu)
1882+
{
1883+
xen_smp_intr_free(cpu);
1884+
1885+
if (xen_pv_domain() ||
1886+
(xen_have_vector_callback &&
1887+
xen_feature(XENFEAT_hvm_safe_pvclock)))
1888+
xen_teardown_timer(cpu);
1889+
1890+
return 0;
1891+
}
1892+
1893+
static int xen_cpu_up_online(unsigned int cpu)
1894+
{
1895+
xen_init_lock_cpu(cpu);
1896+
return 0;
1897+
}
18831898

18841899
#ifdef CONFIG_KEXEC_CORE
18851900
static void xen_hvm_shutdown(void)
@@ -1910,7 +1925,7 @@ static void __init xen_hvm_guest_init(void)
19101925
if (xen_feature(XENFEAT_hvm_callback_vector))
19111926
xen_have_vector_callback = 1;
19121927
xen_hvm_smp_init();
1913-
register_cpu_notifier(&xen_cpu_notifier);
1928+
WARN_ON(xen_cpuhp_setup());
19141929
xen_unplug_emulated_devices();
19151930
x86_init.irqs.intr_init = xen_init_IRQ;
19161931
xen_hvm_init_time_ops();

include/linux/cpuhotplug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum cpuhp_state {
2121
CPUHP_X2APIC_PREPARE,
2222
CPUHP_SMPCFD_PREPARE,
2323
CPUHP_RCUTREE_PREP,
24+
CPUHP_XEN_PREPARE,
2425
CPUHP_NOTIFY_PREPARE,
2526
CPUHP_TIMERS_DEAD,
2627
CPUHP_BRINGUP_CPU,

0 commit comments

Comments
 (0)