[IA64] support for cpu0 removal
here is the BSP removal support for IA64. Its pretty much the same thing that was released a while back, but has your feedback incorporated. - Removed CONFIG_BSP_REMOVE_WORKAROUND and associated cmdline param - Fixed compile issue with sn2/zx1 due to a undefined fix_b0_for_bsp - some formatting nits (whitespace etc) This has been tested on tiger and long back by alex on hp systems as well. Signed-off-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
db9edfd7e3
commit
ff741906ad
@ -272,6 +272,25 @@ config SCHED_SMT
|
|||||||
Intel IA64 chips with MultiThreading at a cost of slightly increased
|
Intel IA64 chips with MultiThreading at a cost of slightly increased
|
||||||
overhead in some places. If unsure say N here.
|
overhead in some places. If unsure say N here.
|
||||||
|
|
||||||
|
config PERMIT_BSP_REMOVE
|
||||||
|
bool "Support removal of Bootstrap Processor"
|
||||||
|
depends on HOTPLUG_CPU
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Say Y here if your platform SAL will support removal of BSP with HOTPLUG_CPU
|
||||||
|
support.
|
||||||
|
|
||||||
|
config FORCE_CPEI_RETARGET
|
||||||
|
bool "Force assumption that CPEI can be re-targetted"
|
||||||
|
depends on PERMIT_BSP_REMOVE
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Say Y if you need to force the assumption that CPEI can be re-targetted to
|
||||||
|
any cpu in the system. This hint is available via ACPI 3.0 specifications.
|
||||||
|
Tiger4 systems are capable of re-directing CPEI to any CPU other than BSP.
|
||||||
|
This option it useful to enable this feature on older BIOS's as well.
|
||||||
|
You can also enable this by using boot command line option force_cpei=1.
|
||||||
|
|
||||||
config PREEMPT
|
config PREEMPT
|
||||||
bool "Preemptible Kernel"
|
bool "Preemptible Kernel"
|
||||||
help
|
help
|
||||||
|
@ -114,6 +114,8 @@ CONFIG_FORCE_MAX_ZONEORDER=17
|
|||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_NR_CPUS=4
|
CONFIG_NR_CPUS=4
|
||||||
CONFIG_HOTPLUG_CPU=y
|
CONFIG_HOTPLUG_CPU=y
|
||||||
|
CONFIG_PERMIT_BSP_REMOVE=y
|
||||||
|
CONFIG_FORCE_CPEI_RETARGET=y
|
||||||
# CONFIG_SCHED_SMT is not set
|
# CONFIG_SCHED_SMT is not set
|
||||||
# CONFIG_PREEMPT is not set
|
# CONFIG_PREEMPT is not set
|
||||||
CONFIG_SELECT_MEMORY_MODEL=y
|
CONFIG_SELECT_MEMORY_MODEL=y
|
||||||
|
@ -287,15 +287,19 @@ acpi_parse_plat_int_src(acpi_table_entry_header * header,
|
|||||||
unsigned int can_cpei_retarget(void)
|
unsigned int can_cpei_retarget(void)
|
||||||
{
|
{
|
||||||
extern int cpe_vector;
|
extern int cpe_vector;
|
||||||
|
extern unsigned int force_cpei_retarget;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only if CPEI is supported and the override flag
|
* Only if CPEI is supported and the override flag
|
||||||
* is present, otherwise return that its re-targettable
|
* is present, otherwise return that its re-targettable
|
||||||
* if we are in polling mode.
|
* if we are in polling mode.
|
||||||
*/
|
*/
|
||||||
if (cpe_vector > 0 && !acpi_cpei_override)
|
if (cpe_vector > 0) {
|
||||||
return 0;
|
if (acpi_cpei_override || force_cpei_retarget)
|
||||||
|
return 1;
|
||||||
else
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,6 +631,7 @@ get_target_cpu (unsigned int gsi, int vector)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
static int cpu = -1;
|
static int cpu = -1;
|
||||||
|
extern int cpe_vector;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In case of vector shared by multiple RTEs, all RTEs that
|
* In case of vector shared by multiple RTEs, all RTEs that
|
||||||
@ -653,6 +654,11 @@ get_target_cpu (unsigned int gsi, int vector)
|
|||||||
if (!cpu_online(smp_processor_id()))
|
if (!cpu_online(smp_processor_id()))
|
||||||
return cpu_physical_id(smp_processor_id());
|
return cpu_physical_id(smp_processor_id());
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI
|
||||||
|
if (cpe_vector > 0 && vector == IA64_CPEP_VECTOR)
|
||||||
|
return get_cpei_target_cpu();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
{
|
{
|
||||||
int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
|
int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
|
||||||
|
@ -163,8 +163,19 @@ void fixup_irqs(void)
|
|||||||
{
|
{
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
extern void ia64_process_pending_intr(void);
|
extern void ia64_process_pending_intr(void);
|
||||||
|
extern void ia64_disable_timer(void);
|
||||||
|
extern volatile int time_keeper_id;
|
||||||
|
|
||||||
|
ia64_disable_timer();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a new timesync master
|
||||||
|
*/
|
||||||
|
if (smp_processor_id() == time_keeper_id) {
|
||||||
|
time_keeper_id = first_cpu(cpu_online_map);
|
||||||
|
printk ("CPU %d is now promoted to time-keeper master\n", time_keeper_id);
|
||||||
|
}
|
||||||
|
|
||||||
ia64_set_itv(1<<16);
|
|
||||||
/*
|
/*
|
||||||
* Phase 1: Locate irq's bound to this cpu and
|
* Phase 1: Locate irq's bound to this cpu and
|
||||||
* relocate them for cpu removal.
|
* relocate them for cpu removal.
|
||||||
|
@ -289,6 +289,7 @@ ia64_mca_log_sal_error_record(int sal_info_type)
|
|||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
int cpe_vector = -1;
|
int cpe_vector = -1;
|
||||||
|
int ia64_cpe_irq = -1;
|
||||||
|
|
||||||
static irqreturn_t
|
static irqreturn_t
|
||||||
ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
|
ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
|
||||||
@ -1444,11 +1445,13 @@ void __devinit
|
|||||||
ia64_mca_cpu_init(void *cpu_data)
|
ia64_mca_cpu_init(void *cpu_data)
|
||||||
{
|
{
|
||||||
void *pal_vaddr;
|
void *pal_vaddr;
|
||||||
|
static int first_time = 1;
|
||||||
|
|
||||||
if (smp_processor_id() == 0) {
|
if (first_time) {
|
||||||
void *mca_data;
|
void *mca_data;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
|
first_time = 0;
|
||||||
mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
|
mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu)
|
||||||
* NR_CPUS + KERNEL_STACK_SIZE);
|
* NR_CPUS + KERNEL_STACK_SIZE);
|
||||||
mca_data = (void *)(((unsigned long)mca_data +
|
mca_data = (void *)(((unsigned long)mca_data +
|
||||||
@ -1704,6 +1707,7 @@ ia64_mca_late_init(void)
|
|||||||
desc = irq_descp(irq);
|
desc = irq_descp(irq);
|
||||||
desc->status |= IRQ_PER_CPU;
|
desc->status |= IRQ_PER_CPU;
|
||||||
setup_irq(irq, &mca_cpe_irqaction);
|
setup_irq(irq, &mca_cpe_irqaction);
|
||||||
|
ia64_cpe_irq = irq;
|
||||||
}
|
}
|
||||||
ia64_mca_register_cpev(cpe_vector);
|
ia64_mca_register_cpev(cpe_vector);
|
||||||
IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
|
IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
|
||||||
|
@ -6718,6 +6718,7 @@ __initcall(pfm_init);
|
|||||||
void
|
void
|
||||||
pfm_init_percpu (void)
|
pfm_init_percpu (void)
|
||||||
{
|
{
|
||||||
|
static int first_time=1;
|
||||||
/*
|
/*
|
||||||
* make sure no measurement is active
|
* make sure no measurement is active
|
||||||
* (may inherit programmed PMCs from EFI).
|
* (may inherit programmed PMCs from EFI).
|
||||||
@ -6730,8 +6731,10 @@ pfm_init_percpu (void)
|
|||||||
*/
|
*/
|
||||||
pfm_unfreeze_pmu();
|
pfm_unfreeze_pmu();
|
||||||
|
|
||||||
if (smp_processor_id() == 0)
|
if (first_time) {
|
||||||
register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
|
register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
|
||||||
|
first_time=0;
|
||||||
|
}
|
||||||
|
|
||||||
ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR);
|
ia64_setreg(_IA64_REG_CR_PMV, IA64_PERFMON_VECTOR);
|
||||||
ia64_srlz_d();
|
ia64_srlz_d();
|
||||||
|
@ -70,6 +70,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
#ifdef CONFIG_PERMIT_BSP_REMOVE
|
||||||
|
#define bsp_remove_ok 1
|
||||||
|
#else
|
||||||
|
#define bsp_remove_ok 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store all idle threads, this can be reused instead of creating
|
* Store all idle threads, this can be reused instead of creating
|
||||||
* a new thread. Also avoids complicated thread destroy functionality
|
* a new thread. Also avoids complicated thread destroy functionality
|
||||||
@ -104,7 +110,7 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
|
|||||||
/*
|
/*
|
||||||
* ITC synchronization related stuff:
|
* ITC synchronization related stuff:
|
||||||
*/
|
*/
|
||||||
#define MASTER 0
|
#define MASTER (0)
|
||||||
#define SLAVE (SMP_CACHE_BYTES/8)
|
#define SLAVE (SMP_CACHE_BYTES/8)
|
||||||
|
|
||||||
#define NUM_ROUNDS 64 /* magic value */
|
#define NUM_ROUNDS 64 /* magic value */
|
||||||
@ -151,6 +157,27 @@ char __initdata no_int_routing;
|
|||||||
|
|
||||||
unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
|
unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
|
||||||
|
|
||||||
|
#ifdef CONFIG_FORCE_CPEI_RETARGET
|
||||||
|
#define CPEI_OVERRIDE_DEFAULT (1)
|
||||||
|
#else
|
||||||
|
#define CPEI_OVERRIDE_DEFAULT (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
|
||||||
|
|
||||||
|
static int __init
|
||||||
|
cmdl_force_cpei(char *str)
|
||||||
|
{
|
||||||
|
int value=0;
|
||||||
|
|
||||||
|
get_option (&str, &value);
|
||||||
|
force_cpei_retarget = value;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__setup("force_cpei=", cmdl_force_cpei);
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
nointroute (char *str)
|
nointroute (char *str)
|
||||||
{
|
{
|
||||||
@ -161,6 +188,27 @@ nointroute (char *str)
|
|||||||
|
|
||||||
__setup("nointroute", nointroute);
|
__setup("nointroute", nointroute);
|
||||||
|
|
||||||
|
static void fix_b0_for_bsp(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
|
int cpuid;
|
||||||
|
static int fix_bsp_b0 = 1;
|
||||||
|
|
||||||
|
cpuid = smp_processor_id();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache the b0 value on the first AP that comes up
|
||||||
|
*/
|
||||||
|
if (!(fix_bsp_b0 && cpuid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
|
||||||
|
printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
|
||||||
|
|
||||||
|
fix_bsp_b0 = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sync_master (void *arg)
|
sync_master (void *arg)
|
||||||
{
|
{
|
||||||
@ -327,8 +375,9 @@ smp_setup_percpu_timer (void)
|
|||||||
static void __devinit
|
static void __devinit
|
||||||
smp_callin (void)
|
smp_callin (void)
|
||||||
{
|
{
|
||||||
int cpuid, phys_id;
|
int cpuid, phys_id, itc_master;
|
||||||
extern void ia64_init_itm(void);
|
extern void ia64_init_itm(void);
|
||||||
|
extern volatile int time_keeper_id;
|
||||||
|
|
||||||
#ifdef CONFIG_PERFMON
|
#ifdef CONFIG_PERFMON
|
||||||
extern void pfm_init_percpu(void);
|
extern void pfm_init_percpu(void);
|
||||||
@ -336,6 +385,7 @@ smp_callin (void)
|
|||||||
|
|
||||||
cpuid = smp_processor_id();
|
cpuid = smp_processor_id();
|
||||||
phys_id = hard_smp_processor_id();
|
phys_id = hard_smp_processor_id();
|
||||||
|
itc_master = time_keeper_id;
|
||||||
|
|
||||||
if (cpu_online(cpuid)) {
|
if (cpu_online(cpuid)) {
|
||||||
printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
|
printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
|
||||||
@ -343,6 +393,8 @@ smp_callin (void)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fix_b0_for_bsp();
|
||||||
|
|
||||||
lock_ipi_calllock();
|
lock_ipi_calllock();
|
||||||
cpu_set(cpuid, cpu_online_map);
|
cpu_set(cpuid, cpu_online_map);
|
||||||
unlock_ipi_calllock();
|
unlock_ipi_calllock();
|
||||||
@ -365,8 +417,8 @@ smp_callin (void)
|
|||||||
* calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
|
* calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
|
||||||
* local_bh_enable(), which bugs out if irqs are not enabled...
|
* local_bh_enable(), which bugs out if irqs are not enabled...
|
||||||
*/
|
*/
|
||||||
Dprintk("Going to syncup ITC with BP.\n");
|
Dprintk("Going to syncup ITC with ITC Master.\n");
|
||||||
ia64_sync_itc(0);
|
ia64_sync_itc(itc_master);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -638,6 +690,47 @@ remove_siblinginfo(int cpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern void fixup_irqs(void);
|
extern void fixup_irqs(void);
|
||||||
|
|
||||||
|
int migrate_platform_irqs(unsigned int cpu)
|
||||||
|
{
|
||||||
|
int new_cpei_cpu;
|
||||||
|
irq_desc_t *desc = NULL;
|
||||||
|
cpumask_t mask;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dont permit CPEI target to removed.
|
||||||
|
*/
|
||||||
|
if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
|
||||||
|
printk ("CPU (%d) is CPEI Target\n", cpu);
|
||||||
|
if (can_cpei_retarget()) {
|
||||||
|
/*
|
||||||
|
* Now re-target the CPEI to a different processor
|
||||||
|
*/
|
||||||
|
new_cpei_cpu = any_online_cpu(cpu_online_map);
|
||||||
|
mask = cpumask_of_cpu(new_cpei_cpu);
|
||||||
|
set_cpei_target_cpu(new_cpei_cpu);
|
||||||
|
desc = irq_descp(ia64_cpe_irq);
|
||||||
|
/*
|
||||||
|
* Switch for now, immediatly, we need to do fake intr
|
||||||
|
* as other interrupts, but need to study CPEI behaviour with
|
||||||
|
* polling before making changes.
|
||||||
|
*/
|
||||||
|
if (desc) {
|
||||||
|
desc->handler->disable(ia64_cpe_irq);
|
||||||
|
desc->handler->set_affinity(ia64_cpe_irq, mask);
|
||||||
|
desc->handler->enable(ia64_cpe_irq);
|
||||||
|
printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!desc) {
|
||||||
|
printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
|
||||||
|
retval = -EBUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* must be called with cpucontrol mutex held */
|
/* must be called with cpucontrol mutex held */
|
||||||
int __cpu_disable(void)
|
int __cpu_disable(void)
|
||||||
{
|
{
|
||||||
@ -646,8 +739,17 @@ int __cpu_disable(void)
|
|||||||
/*
|
/*
|
||||||
* dont permit boot processor for now
|
* dont permit boot processor for now
|
||||||
*/
|
*/
|
||||||
if (cpu == 0)
|
if (cpu == 0 && !bsp_remove_ok) {
|
||||||
return -EBUSY;
|
printk ("Your platform does not support removal of BSP\n");
|
||||||
|
return (-EBUSY);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_clear(cpu, cpu_online_map);
|
||||||
|
|
||||||
|
if (migrate_platform_irqs(cpu)) {
|
||||||
|
cpu_set(cpu, cpu_online_map);
|
||||||
|
return (-EBUSY);
|
||||||
|
}
|
||||||
|
|
||||||
remove_siblinginfo(cpu);
|
remove_siblinginfo(cpu);
|
||||||
cpu_clear(cpu, cpu_online_map);
|
cpu_clear(cpu, cpu_online_map);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
extern unsigned long wall_jiffies;
|
extern unsigned long wall_jiffies;
|
||||||
|
|
||||||
#define TIME_KEEPER_ID 0 /* smp_processor_id() of time-keeper */
|
volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */
|
||||||
|
|
||||||
#ifdef CONFIG_IA64_DEBUG_IRQ
|
#ifdef CONFIG_IA64_DEBUG_IRQ
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
|
|||||||
|
|
||||||
new_itm += local_cpu_data->itm_delta;
|
new_itm += local_cpu_data->itm_delta;
|
||||||
|
|
||||||
if (smp_processor_id() == TIME_KEEPER_ID) {
|
if (smp_processor_id() == time_keeper_id) {
|
||||||
/*
|
/*
|
||||||
* Here we are in the timer irq handler. We have irqs locally
|
* Here we are in the timer irq handler. We have irqs locally
|
||||||
* disabled, but we don't know if the timer_bh is running on
|
* disabled, but we don't know if the timer_bh is running on
|
||||||
@ -236,6 +236,11 @@ static struct irqaction timer_irqaction = {
|
|||||||
.name = "timer"
|
.name = "timer"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void __devinit ia64_disable_timer(void)
|
||||||
|
{
|
||||||
|
ia64_set_itv(1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
void __init
|
void __init
|
||||||
time_init (void)
|
time_init (void)
|
||||||
{
|
{
|
||||||
|
@ -181,13 +181,15 @@ per_cpu_init (void)
|
|||||||
{
|
{
|
||||||
void *cpu_data;
|
void *cpu_data;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
static int first_time=1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_free_pages() cannot be used before cpu_init() done. BSP
|
* get_free_pages() cannot be used before cpu_init() done. BSP
|
||||||
* allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
|
* allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
|
||||||
* get_zeroed_page().
|
* get_zeroed_page().
|
||||||
*/
|
*/
|
||||||
if (smp_processor_id() == 0) {
|
if (first_time) {
|
||||||
|
first_time=0;
|
||||||
cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
|
cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
|
||||||
PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
|
PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
|
||||||
for (cpu = 0; cpu < NR_CPUS; cpu++) {
|
for (cpu = 0; cpu < NR_CPUS; cpu++) {
|
||||||
|
@ -528,12 +528,17 @@ void __init find_memory(void)
|
|||||||
void *per_cpu_init(void)
|
void *per_cpu_init(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
static int first_time = 1;
|
||||||
|
|
||||||
|
|
||||||
if (smp_processor_id() != 0)
|
if (smp_processor_id() != 0)
|
||||||
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
|
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
|
||||||
|
|
||||||
|
if (first_time) {
|
||||||
|
first_time = 0;
|
||||||
for (cpu = 0; cpu < NR_CPUS; cpu++)
|
for (cpu = 0; cpu < NR_CPUS; cpu++)
|
||||||
per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
|
per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
|
||||||
|
}
|
||||||
|
|
||||||
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
|
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,8 @@ struct ia64_mca_cpu {
|
|||||||
/* Array of physical addresses of each CPU's MCA area. */
|
/* Array of physical addresses of each CPU's MCA area. */
|
||||||
extern unsigned long __per_cpu_mca[NR_CPUS];
|
extern unsigned long __per_cpu_mca[NR_CPUS];
|
||||||
|
|
||||||
|
extern int cpe_vector;
|
||||||
|
extern int ia64_cpe_irq;
|
||||||
extern void ia64_mca_init(void);
|
extern void ia64_mca_init(void);
|
||||||
extern void ia64_mca_cpu_init(void *);
|
extern void ia64_mca_cpu_init(void *);
|
||||||
extern void ia64_os_mca_dispatch(void);
|
extern void ia64_os_mca_dispatch(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user