smpboot.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * SMP boot-related support
  3.  *
  4.  * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  5.  *
  6.  * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here.
  7.  * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code.
  8.  */
  9. #define __KERNEL_SYSCALLS__
  10. #include <linux/config.h>
  11. #include <linux/bootmem.h>
  12. #include <linux/delay.h>
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/irq.h>
  16. #include <linux/kernel.h>
  17. #include <linux/kernel_stat.h>
  18. #include <linux/mm.h>
  19. #include <linux/smp.h>
  20. #include <linux/smp_lock.h>
  21. #include <linux/spinlock.h>
  22. #include <linux/efi.h>
  23. #include <asm/atomic.h>
  24. #include <asm/bitops.h>
  25. #include <asm/cache.h>
  26. #include <asm/current.h>
  27. #include <asm/delay.h>
  28. #include <asm/io.h>
  29. #include <asm/irq.h>
  30. #include <asm/machvec.h>
  31. #include <asm/mca.h>
  32. #include <asm/page.h>
  33. #include <asm/pgalloc.h>
  34. #include <asm/pgtable.h>
  35. #include <asm/processor.h>
  36. #include <asm/ptrace.h>
  37. #include <asm/sal.h>
  38. #include <asm/system.h>
  39. #include <asm/unistd.h>
  40. #define SMP_DEBUG 0
  41. #if SMP_DEBUG
  42. #define Dprintk(x...)  printk(x)
  43. #else
  44. #define Dprintk(x...)
  45. #endif
  46. /*
  47.  * ITC synchronization related stuff:
  48.  */
  49. #define MASTER 0
  50. #define SLAVE (SMP_CACHE_BYTES/8)
  51. #define NUM_ROUNDS 64 /* magic value */
  52. #define NUM_ITERS 5 /* likewise */
  53. static spinlock_t itc_sync_lock = SPIN_LOCK_UNLOCKED;
  54. static volatile unsigned long go[SLAVE + 1];
  55. #define DEBUG_ITC_SYNC 0
  56. extern void __init calibrate_delay(void);
  57. extern void start_ap(void);
  58. extern unsigned long ia64_iobase;
  59. int cpucount;
  60. /* Setup configured maximum number of CPUs to activate */
  61. static int max_cpus = -1;
  62. /* Total count of live CPUs */
  63. int smp_num_cpus = 1;
  64. /* Bitmask of currently online CPUs */
  65. volatile unsigned long cpu_online_map;
  66. /* which logical CPU number maps to which CPU (physical APIC ID) */
  67. volatile int ia64_cpu_to_sapicid[NR_CPUS];
  68. static volatile unsigned long cpu_callin_map;
  69. struct smp_boot_data smp_boot_data __initdata;
  70. /* Set when the idlers are all forked */
  71. volatile int smp_threads_ready;
  72. unsigned long ap_wakeup_vector = -1; /* External Int use to wakeup APs */
  73. char __initdata no_int_routing;
  74. unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
  75. /*
  76.  * Setup routine for controlling SMP activation
  77.  *
  78.  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  79.  * activation entirely (the MPS table probe still happens, though).
  80.  *
  81.  * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
  82.  * greater than 0, limits the maximum number of CPUs activated in
  83.  * SMP mode to <NUM>.
  84.  */
  85. static int __init
  86. nosmp (char *str)
  87. {
  88. max_cpus = 0;
  89. return 1;
  90. }
  91. __setup("nosmp", nosmp);
  92. static int __init
  93. maxcpus (char *str)
  94. {
  95. get_option(&str, &max_cpus);
  96. return 1;
  97. }
  98. __setup("maxcpus=", maxcpus);
  99. static int __init
  100. nointroute (char *str)
  101. {
  102. no_int_routing = 1;
  103. return 1;
  104. }
  105. __setup("nointroute", nointroute);
  106. void
  107. sync_master (void *arg)
  108. {
  109. unsigned long flags, i;
  110. go[MASTER] = 0;
  111. local_irq_save(flags);
  112. {
  113. for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) {
  114. while (!go[MASTER]);
  115. go[MASTER] = 0;
  116. go[SLAVE] = ia64_get_itc();
  117. }
  118. }
  119. local_irq_restore(flags);
  120. }
  121. /*
  122.  * Return the number of cycles by which our itc differs from the itc on the master
  123.  * (time-keeper) CPU.  A positive number indicates our itc is ahead of the master,
  124.  * negative that it is behind.
  125.  */
  126. static inline long
  127. get_delta (long *rt, long *master)
  128. {
  129. unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
  130. unsigned long tcenter, t0, t1, tm;
  131. long i;
  132. for (i = 0; i < NUM_ITERS; ++i) {
  133. t0 = ia64_get_itc();
  134. go[MASTER] = 1;
  135. while (!(tm = go[SLAVE]));
  136. go[SLAVE] = 0;
  137. t1 = ia64_get_itc();
  138. if (t1 - t0 < best_t1 - best_t0)
  139. best_t0 = t0, best_t1 = t1, best_tm = tm;
  140. }
  141. *rt = best_t1 - best_t0;
  142. *master = best_tm - best_t0;
  143. /* average best_t0 and best_t1 without overflow: */
  144. tcenter = (best_t0/2 + best_t1/2);
  145. if (best_t0 % 2 + best_t1 % 2 == 2)
  146. ++tcenter;
  147. return tcenter - best_tm;
  148. }
  149. /*
  150.  * Synchronize ar.itc of the current (slave) CPU with the ar.itc of the MASTER CPU
  151.  * (normally the time-keeper CPU).  We use a closed loop to eliminate the possibility of
  152.  * unaccounted-for errors (such as getting a machine check in the middle of a calibration
  153.  * step).  The basic idea is for the slave to ask the master what itc value it has and to
  154.  * read its own itc before and after the master responds.  Each iteration gives us three
  155.  * timestamps:
  156.  *
  157.  * slave master
  158.  *
  159.  * t0 ---
  160.  *             ---
  161.  *    --->
  162.  * tm
  163.  *    /---
  164.  *        /---
  165.  * t1 <---
  166.  *
  167.  *
  168.  * The goal is to adjust the slave's ar.itc such that tm falls exactly half-way between t0
  169.  * and t1.  If we achieve this, the clocks are synchronized provided the interconnect
  170.  * between the slave and the master is symmetric.  Even if the interconnect were
  171.  * asymmetric, we would still know that the synchronization error is smaller than the
  172.  * roundtrip latency (t0 - t1).
  173.  *
  174.  * When the interconnect is quiet and symmetric, this lets us synchronize the itc to
  175.  * within one or two cycles.  However, we can only *guarantee* that the synchronization is
  176.  * accurate to within a round-trip time, which is typically in the range of several
  177.  * hundred cycles (e.g., ~500 cycles).  In practice, this means that the itc's are usually
  178.  * almost perfectly synchronized, but we shouldn't assume that the accuracy is much better
  179.  * than half a micro second or so.
  180.  */
  181. void
  182. ia64_sync_itc (unsigned int master)
  183. {
  184. long i, delta, adj, adjust_latency = 0, done = 0;
  185. unsigned long flags, rt, master_time_stamp, bound;
  186. #if DEBUG_ITC_SYNC
  187. struct {
  188. long rt; /* roundtrip time */
  189. long master; /* master's timestamp */
  190. long diff; /* difference between midpoint and master's timestamp */
  191. long lat; /* estimate of itc adjustment latency */
  192. } t[NUM_ROUNDS];
  193. #endif
  194. go[MASTER] = 1;
  195. if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) {
  196. printk("sync_itc: failed to get attention of CPU %u!n", master);
  197. return;
  198. }
  199. while (go[MASTER]); /* wait for master to be ready */
  200. spin_lock_irqsave(&itc_sync_lock, flags);
  201. {
  202. for (i = 0; i < NUM_ROUNDS; ++i) {
  203. delta = get_delta(&rt, &master_time_stamp);
  204. if (delta == 0) {
  205. done = 1; /* let's lock on to this... */
  206. bound = rt;
  207. }
  208. if (!done) {
  209. if (i > 0) {
  210. adjust_latency += -delta;
  211. adj = -delta + adjust_latency/4;
  212. } else
  213. adj = -delta;
  214. ia64_set_itc(ia64_get_itc() + adj);
  215. }
  216. #if DEBUG_ITC_SYNC
  217. t[i].rt = rt;
  218. t[i].master = master_time_stamp;
  219. t[i].diff = delta;
  220. t[i].lat = adjust_latency/4;
  221. #endif
  222. }
  223. }
  224. spin_unlock_irqrestore(&itc_sync_lock, flags);
  225. #if DEBUG_ITC_SYNC
  226. for (i = 0; i < NUM_ROUNDS; ++i)
  227. printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ldn",
  228.        t[i].rt, t[i].master, t[i].diff, t[i].lat);
  229. #endif
  230. printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)n",
  231.        smp_processor_id(), master, delta, rt);
  232. }
  233. /*
  234.  * Ideally sets up per-cpu profiling hooks.  Doesn't do much now...
  235.  */
  236. static inline void __init
  237. smp_setup_percpu_timer (void)
  238. {
  239. local_cpu_data->prof_counter = 1;
  240. local_cpu_data->prof_multiplier = 1;
  241. }
  242. /*
  243.  * Architecture specific routine called by the kernel just before init is
  244.  * fired off. This allows the BP to have everything in order [we hope].
  245.  * At the end of this all the APs will hit the system scheduling and off
  246.  * we go. Each AP will jump through the kernel
  247.  * init into idle(). At this point the scheduler will one day take over
  248.  * and give them jobs to do. smp_callin is a standard routine
  249.  * we use to track CPUs as they power up.
  250.  */
  251. static volatile atomic_t smp_commenced = ATOMIC_INIT(0);
  252. void __init
  253. smp_commence (void)
  254. {
  255. /*
  256.  * Lets the callins below out of their loop.
  257.  */
  258. Dprintk("Setting commenced=1, go go gon");
  259. wmb();
  260. atomic_set(&smp_commenced,1);
  261. }
  262. static void __init
  263. smp_callin (void)
  264. {
  265. int cpuid, phys_id;
  266. extern void ia64_init_itm(void);
  267. #ifdef CONFIG_PERFMON
  268. extern void perfmon_init_percpu(void);
  269. #endif
  270. cpuid = smp_processor_id();
  271. phys_id = hard_smp_processor_id();
  272. if (test_and_set_bit(cpuid, &cpu_online_map)) {
  273. printk("huh, phys CPU#0x%x, CPU#0x%x already present??n", phys_id, cpuid);
  274. BUG();
  275. }
  276. smp_setup_percpu_timer();
  277. /*
  278.  * Synchronize the ITC with the BP
  279.  */
  280. Dprintk("Going to syncup ITC with BP.n");
  281. ia64_sync_itc(0);
  282. /*
  283.  * Get our bogomips.
  284.  */
  285. ia64_init_itm();
  286. /*
  287.  * Set I/O port base per CPU
  288.  */
  289. ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
  290. #ifdef CONFIG_IA64_MCA
  291. ia64_mca_cmc_vector_setup(); /* Setup vector on AP & enable */
  292. ia64_mca_check_errors(); /* For post-failure MCA error logging */
  293. #endif
  294. #ifdef CONFIG_PERFMON
  295. perfmon_init_percpu();
  296. #endif
  297. local_irq_enable();
  298. calibrate_delay();
  299. local_cpu_data->loops_per_jiffy = loops_per_jiffy;
  300. /*
  301.  * Allow the master to continue.
  302.  */
  303. set_bit(cpuid, &cpu_callin_map);
  304. Dprintk("Stack on CPU %d at about %pn",cpuid, &cpuid);
  305. }
  306. /*
  307.  * Activate a secondary processor.  head.S calls this.
  308.  */
  309. int __init
  310. start_secondary (void *unused)
  311. {
  312. extern int cpu_idle (void);
  313. Dprintk("start_secondary: starting CPU 0x%xn", hard_smp_processor_id());
  314. efi_map_pal_code();
  315. cpu_init();
  316. smp_callin();
  317. Dprintk("CPU %d is set to go.n", smp_processor_id());
  318. while (!atomic_read(&smp_commenced))
  319. ;
  320. Dprintk("CPU %d is starting idle.n", smp_processor_id());
  321. return cpu_idle();
  322. }
  323. static int __init
  324. fork_by_hand (void)
  325. {
  326. /*
  327.  * don't care about the eip and regs settings since
  328.  * we'll never reschedule the forked task.
  329.  */
  330. return do_fork(CLONE_VM|CLONE_PID, 0, 0, 0);
  331. }
  332. static void __init
  333. do_boot_cpu (int sapicid)
  334. {
  335. struct task_struct *idle;
  336. int timeout, cpu;
  337. cpu = ++cpucount;
  338. /*
  339.  * We can't use kernel_thread since we must avoid to
  340.  * reschedule the child.
  341.  */
  342. if (fork_by_hand() < 0)
  343. panic("failed fork for CPU %d", cpu);
  344. /*
  345.  * We remove it from the pidhash and the runqueue
  346.  * once we got the process:
  347.  */
  348. idle = init_task.prev_task;
  349. if (!idle)
  350. panic("No idle process for CPU %d", cpu);
  351. task_set_cpu(idle, cpu); /* we schedule the first task manually */
  352. ia64_cpu_to_sapicid[cpu] = sapicid;
  353. del_from_runqueue(idle);
  354. unhash_process(idle);
  355. init_tasks[cpu] = idle;
  356. Dprintk("Sending wakeup vector %u to AP 0x%x/0x%x.n", ap_wakeup_vector, cpu, sapicid);
  357. platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
  358. /*
  359.  * Wait 10s total for the AP to start
  360.  */
  361. Dprintk("Waiting on callin_map ...");
  362. for (timeout = 0; timeout < 100000; timeout++) {
  363. if (test_bit(cpu, &cpu_callin_map))
  364. break;  /* It has booted */
  365. udelay(100);
  366. }
  367. Dprintk("n");
  368. if (test_bit(cpu, &cpu_callin_map)) {
  369. /* number CPUs logically, starting from 1 (BSP is 0) */
  370. printk("CPU%d: ", cpu);
  371. /*print_cpu_info(&cpu_data[cpu]); */
  372. printk("CPU has booted.n");
  373. } else {
  374. printk(KERN_ERR "Processor 0x%x/0x%x is stuck.n", cpu, sapicid);
  375. ia64_cpu_to_sapicid[cpu] = -1;
  376. cpucount--;
  377. }
  378. }
  379. /*
  380.  * Cycle through the APs sending Wakeup IPIs to boot each.
  381.  */
  382. void __init
  383. smp_boot_cpus (void)
  384. {
  385. int sapicid, cpu;
  386. int boot_cpu_id = hard_smp_processor_id();
  387. /*
  388.  * Initialize the logical to physical CPU number mapping
  389.  * and the per-CPU profiling counter/multiplier
  390.  */
  391. for (cpu = 0; cpu < NR_CPUS; cpu++)
  392. ia64_cpu_to_sapicid[cpu] = -1;
  393. smp_setup_percpu_timer();
  394. /*
  395. * We have the boot CPU online for sure.
  396. */
  397. set_bit(0, &cpu_online_map);
  398. set_bit(0, &cpu_callin_map);
  399. local_cpu_data->loops_per_jiffy = loops_per_jiffy;
  400. ia64_cpu_to_sapicid[0] = boot_cpu_id;
  401. printk("Boot processor id 0x%x/0x%xn", 0, boot_cpu_id);
  402. global_irq_holder = 0;
  403. current->processor = 0;
  404. init_idle();
  405. /*
  406.  * If SMP should be disabled, then really disable it!
  407.  */
  408. if (!max_cpus || (max_cpus < -1)) {
  409. printk(KERN_INFO "SMP mode deactivated.n");
  410. cpu_online_map =  1;
  411. smp_num_cpus = 1;
  412. goto smp_done;
  413. }
  414. if  (max_cpus != -1)
  415. printk (KERN_INFO "Limiting CPUs to %dn", max_cpus);
  416. if (smp_boot_data.cpu_count > 1) {
  417. printk(KERN_INFO "SMP: starting up secondaries.n");
  418. for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) {
  419. /*
  420.  * Don't even attempt to start the boot CPU!
  421.  */
  422. sapicid = smp_boot_data.cpu_phys_id[cpu];
  423. if ((sapicid == -1) || (sapicid == hard_smp_processor_id()))
  424. continue;
  425. if ((max_cpus > 0) && (cpucount + 1 >= max_cpus))
  426. break;
  427. do_boot_cpu(sapicid);
  428. /*
  429.  * Make sure we unmap all failed CPUs
  430.  */
  431. if (ia64_cpu_to_sapicid[cpu] == -1)
  432. printk("phys CPU#%d not responding - cannot use it.n", cpu);
  433. }
  434. smp_num_cpus = cpucount + 1;
  435. /*
  436.  * Allow the user to impress friends.
  437.  */
  438. printk("Before bogomips.n");
  439. if (!cpucount) {
  440. printk(KERN_WARNING "Warning: only one processor found.n");
  441. } else {
  442. unsigned long bogosum = 0;
  443.    for (cpu = 0; cpu < NR_CPUS; cpu++)
  444. if (cpu_online_map & (1UL << cpu))
  445. bogosum += cpu_data(cpu)->loops_per_jiffy;
  446. printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).n",
  447.        cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
  448. }
  449. }
  450.   smp_done:
  451. ;
  452. }
  453. /*
  454.  * Assume that CPU's have been discovered by some platform-dependant interface.  For
  455.  * SoftSDV/Lion, that would be ACPI.
  456.  *
  457.  * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
  458.  */
  459. void __init
  460. init_smp_config(void)
  461. {
  462. struct fptr {
  463. unsigned long fp;
  464. unsigned long gp;
  465. } *ap_startup;
  466. long sal_ret;
  467. /* Tell SAL where to drop the AP's.  */
  468. ap_startup = (struct fptr *) start_ap;
  469. sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
  470.        __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
  471. if (sal_ret < 0) {
  472. printk("SMP: Can't set SAL AP Boot Rendezvous: %sn     Forcing UP moden",
  473.        ia64_sal_strerror(sal_ret));
  474. max_cpus = 0;
  475. smp_num_cpus = 1;
  476. }
  477. }