patch-2.3.30 linux/arch/alpha/kernel/smp.c
Next file: linux/arch/alpha/kernel/sys_alcor.c
Previous file: linux/arch/alpha/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 126
- Date:
Mon Dec 6 17:15:53 1999
- Orig file:
v2.3.29/linux/arch/alpha/kernel/smp.c
- Orig date:
Tue Nov 23 22:42:20 1999
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/hwrpb.h>
#include <asm/ptrace.h>
@@ -32,7 +33,6 @@
#include <asm/unistd.h>
#include "proto.h"
-#include "irq_impl.h"
#define DEBUG_SMP 0
@@ -47,8 +47,8 @@
/* A collection of single bit ipi messages. */
static struct {
- unsigned long bits __cacheline_aligned;
-} ipi_data[NR_CPUS];
+ unsigned long bits ____cacheline_aligned;
+} ipi_data[NR_CPUS] __cacheline_aligned;
enum ipi_message_type {
IPI_RESCHEDULE,
@@ -56,7 +56,7 @@
IPI_CPU_STOP,
};
-spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
/* Set to a secondary's cpuid when it comes online. */
static unsigned long smp_secondary_alive;
@@ -396,6 +396,16 @@
return 0;
}
+static int __init fork_by_hand(void)
+{
+ struct pt_regs regs;
+ /*
+ * don't care about the regs settings since
+ * we'll never reschedule the forked task.
+ */
+ return do_fork(CLONE_VM|CLONE_PID, 0, ®s);
+}
+
/*
* Bring one cpu online.
*/
@@ -409,18 +419,25 @@
to kernel_thread is irrelevant -- it's going to start where
HWRPB.CPU_restart says to start. But this gets all the other
task-y sort of data structures set up like we wish. */
- kernel_thread((void *)__smp_callin, NULL, CLONE_PID|CLONE_VM);
+ /*
+ * We can't use kernel_thread since we must avoid to
+ * reschedule the child.
+ */
+ if (fork_by_hand() < 0)
+ panic("failed fork for CPU %d", cpuid);
idle = init_task.prev_task;
if (!idle)
- panic("No idle process for CPU %d", cpunum);
- del_from_runqueue(idle);
- init_tasks[cpunum] = idle;
- idle->processor = cpuid;
-
- /* Schedule the first task manually. */
- /* ??? Ingo, what is this? */
- idle->has_cpu = 1;
+ panic("No idle process for CPU %d", cpuid);
+
+ idle->processor = cpuid;
+ __cpu_logical_map[cpunum] = cpuid;
+ cpu_number_map[cpuid] = cpunum;
+ idle->has_cpu = 1; /* we schedule the first task manually */
+
+ del_from_runqueue(idle);
+ unhash_process(idle);
+ init_tasks[cpunum] = idle;
DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
cpuid, idle->state, idle->flags));
@@ -442,13 +459,18 @@
barrier();
}
+ /* we must invalidate our stuff as we failed to boot the CPU */
+ __cpu_logical_map[cpunum] = -1;
+ cpu_number_map[cpuid] = -1;
+
+ /* the idle task is local to us so free it as we don't use it */
+ free_task_struct(idle);
+
printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
return -1;
alive:
/* Another "Red Snapper". */
- cpu_number_map[cpuid] = cpunum;
- __cpu_logical_map[cpunum] = cpuid;
return 0;
}
@@ -579,16 +601,6 @@
{
/* smp_init sets smp_threads_ready -- that's enough. */
mb();
-}
-
-/*
- * Only broken Intel needs this, thus it should not even be
- * referenced globally.
- */
-
-void __init
-initialize_secondary(void)
-{
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)