Commit f30c04cf authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Richard Henderson

[PATCH] alpha smp fixes

From Jeff.Wiedemeier@hp.com:

Misc alpha smp updates for 2.5 tree.
parent 9326a730
...@@ -72,14 +72,13 @@ static int smp_secondary_alive __initdata = 0; ...@@ -72,14 +72,13 @@ static int smp_secondary_alive __initdata = 0;
/* Which cpus ids came online. */ /* Which cpus ids came online. */
unsigned long cpu_present_mask; unsigned long cpu_present_mask;
volatile unsigned long cpu_online_map;
/* cpus reported in the hwrpb */ /* cpus reported in the hwrpb */
static unsigned long hwrpb_cpu_present_mask __initdata = 0; static unsigned long hwrpb_cpu_present_mask __initdata = 0;
static int max_cpus = -1; /* Command-line limitation. */
int smp_num_probed; /* Internal processor count */ int smp_num_probed; /* Internal processor count */
int smp_num_cpus = 1; /* Number that came online. */ int smp_num_cpus = 1; /* Number that came online. */
int smp_threads_ready; /* True once the per process idle is forked. */
cycles_t cacheflush_time; cycles_t cacheflush_time;
unsigned long cache_decay_ticks; unsigned long cache_decay_ticks;
...@@ -87,22 +86,6 @@ extern void calibrate_delay(void); ...@@ -87,22 +86,6 @@ extern void calibrate_delay(void);
extern asmlinkage void entInt(void); extern asmlinkage void entInt(void);
static int __init nosmp(char *str)
{
max_cpus = 0;
return 1;
}
__setup("nosmp", nosmp);
static int __init maxcpus(char *str)
{
get_option(&str, &max_cpus);
return 1;
}
__setup("maxcpus", maxcpus);
/* /*
* Called by both boot and secondaries to move global data into * Called by both boot and secondaries to move global data into
...@@ -151,6 +134,11 @@ smp_callin(void) ...@@ -151,6 +134,11 @@ smp_callin(void)
{ {
int cpuid = hard_smp_processor_id(); int cpuid = hard_smp_processor_id();
if (test_and_set_bit(cpuid, &cpu_online_map)) {
printk("??, cpu 0x%x already present??\n", cpuid);
BUG();
}
/* Turn on machine checks. */ /* Turn on machine checks. */
wrmces(7); wrmces(7);
...@@ -181,10 +169,6 @@ smp_callin(void) ...@@ -181,10 +169,6 @@ smp_callin(void)
wmb(); wmb();
smp_secondary_alive = 1; smp_secondary_alive = 1;
/* Wait for the go code. */
while (!smp_threads_ready)
barrier();
DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
cpuid, current, current->active_mm)); cpuid, current, current->active_mm));
...@@ -432,7 +416,7 @@ fork_by_hand(void) ...@@ -432,7 +416,7 @@ fork_by_hand(void)
/* Don't care about the contents of regs since we'll never /* Don't care about the contents of regs since we'll never
reschedule the forked task. */ reschedule the forked task. */
struct pt_regs regs; struct pt_regs regs;
return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL); return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
} }
/* /*
...@@ -542,13 +526,12 @@ setup_smp(void) ...@@ -542,13 +526,12 @@ setup_smp(void)
} }
/* /*
* Called by smp_init bring all the secondaries online and hold them. * Called by smp_init prepare the secondaries
*/ */
void __init void __init
smp_boot_cpus(void) smp_prepare_cpus(unsigned int max_cpus)
{ {
int cpu_count, i; int cpu_count, i;
unsigned long bogosum;
/* Take care of some initial bookkeeping. */ /* Take care of some initial bookkeeping. */
memset(ipi_data, 0, sizeof(ipi_data)); memset(ipi_data, 0, sizeof(ipi_data));
...@@ -559,6 +542,9 @@ smp_boot_cpus(void) ...@@ -559,6 +542,9 @@ smp_boot_cpus(void)
smp_tune_scheduling(boot_cpuid); smp_tune_scheduling(boot_cpuid);
smp_setup_percpu_timer(boot_cpuid); smp_setup_percpu_timer(boot_cpuid);
/* We have already have the boot CPU online.. */
set_bit(boot_cpuid, &cpu_online_map);
/* Nothing to do on a UP box, or when told not to. */ /* Nothing to do on a UP box, or when told not to. */
if (smp_num_probed == 1 || max_cpus == 0) { if (smp_num_probed == 1 || max_cpus == 0) {
cpu_present_mask = 1UL << boot_cpuid; cpu_present_mask = 1UL << boot_cpuid;
...@@ -569,44 +555,20 @@ smp_boot_cpus(void) ...@@ -569,44 +555,20 @@ smp_boot_cpus(void)
printk(KERN_INFO "SMP starting up secondaries.\n"); printk(KERN_INFO "SMP starting up secondaries.\n");
cpu_count = 1; cpu_count = 1;
for (i = 0; i < NR_CPUS; i++) { for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) {
if (i == boot_cpuid) if (i == boot_cpuid)
continue; continue;
if (((hwrpb_cpu_present_mask >> i) & 1) == 0) if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
continue; continue;
if (smp_boot_one_cpu(i))
continue;
cpu_present_mask |= 1UL << i; cpu_present_mask |= 1UL << i;
cpu_count++; cpu_count++;
} }
if (cpu_count == 1) {
printk(KERN_ERR "SMP: Only one lonely processor alive.\n");
return;
}
bogosum = 0;
for (i = 0; i < NR_CPUS; i++) {
if (cpu_present_mask & (1UL << i))
bogosum += cpu_data[i].loops_per_jiffy;
}
printk(KERN_INFO "SMP: Total of %d processors activated "
"(%lu.%02lu BogoMIPS).\n",
cpu_count, (bogosum + 2500) / (500000/HZ),
((bogosum + 2500) / (5000/HZ)) % 100);
smp_num_cpus = cpu_count; smp_num_cpus = cpu_count;
} }
void __init
smp_prepare_cpus(unsigned int max_cpus)
{
smp_boot_cpus();
}
void __devinit void __devinit
smp_prepare_boot_cpu(void) smp_prepare_boot_cpu(void)
{ {
...@@ -616,14 +578,26 @@ smp_prepare_boot_cpu(void) ...@@ -616,14 +578,26 @@ smp_prepare_boot_cpu(void)
int __devinit int __devinit
__cpu_up(unsigned int cpu) __cpu_up(unsigned int cpu)
{ {
smp_boot_one_cpu(cpu);
return cpu_online(cpu) ? 0 : -ENOSYS; return cpu_online(cpu) ? 0 : -ENOSYS;
} }
void __init void __init
smp_cpus_done(unsigned int max_cpus) smp_cpus_done(unsigned int max_cpus)
{ {
smp_threads_ready = 1; int cpu;
mb(); unsigned long bogosum = 0;
for(cpu = 0; cpu < NR_CPUS; cpu++)
if (cpu_online(cpu))
bogosum += cpu_data[cpu].loops_per_jiffy;
printk(KERN_INFO "SMP: Total of %d processors activated "
"(%lu.%02lu BogoMIPS).\n",
num_online_cpus(),
(bogosum + 2500) / (500000/HZ),
((bogosum + 2500) / (5000/HZ)) % 100);
} }
...@@ -909,7 +883,7 @@ int ...@@ -909,7 +883,7 @@ int
smp_call_function (void (*func) (void *info), void *info, int retry, int wait) smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
{ {
return smp_call_function_on_cpu (func, info, retry, wait, return smp_call_function_on_cpu (func, info, retry, wait,
cpu_present_mask); cpu_online_map);
} }
static void static void
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/bitops.h>
#include <asm/pal.h> #include <asm/pal.h>
/* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */ /* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */
...@@ -21,7 +22,6 @@ __hard_smp_processor_id(void) ...@@ -21,7 +22,6 @@ __hard_smp_processor_id(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#include <linux/threads.h>
#include <asm/irq.h> #include <asm/irq.h>
struct cpuinfo_alpha { struct cpuinfo_alpha {
...@@ -45,12 +45,17 @@ extern struct cpuinfo_alpha cpu_data[NR_CPUS]; ...@@ -45,12 +45,17 @@ extern struct cpuinfo_alpha cpu_data[NR_CPUS];
#define smp_processor_id() (current_thread_info()->cpu) #define smp_processor_id() (current_thread_info()->cpu)
extern unsigned long cpu_present_mask; extern unsigned long cpu_present_mask;
extern volatile unsigned long cpu_online_map;
extern int smp_num_cpus; extern int smp_num_cpus;
#define cpu_online_map cpu_present_mask #define cpu_possible(cpu) (cpu_present_mask & (1UL << (cpu)))
#define num_online_cpus() (smp_num_cpus) #define cpu_online(cpu) (cpu_online_map & (1UL << (cpu)))
#define cpu_online(cpu) (cpu_present_mask & (1<<(cpu)))
#define cpu_possible(cpu) cpu_online(cpu) static inline int
num_online_cpus(void)
{
return hweight64(cpu_online_map);
}
extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu); extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment