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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2. ** SMP Support
  3. **
  4. ** Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  5. ** Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
  6. ** Copyright (C) 2001 Grant Grundler <grundler@parisc-linux.org>
  7. ** 
  8. ** Lots of stuff stolen from arch/alpha/kernel/smp.c
  9. ** ...and then parisc stole from arch/ia64/kernel/smp.c. Thanks David! :^)
  10. **
  11. ** Thanks to John Curry and Ullas Ponnadi. I learned alot from their work.
  12. ** -grant (1/12/2001)
  13. **
  14. ** This program is free software; you can redistribute it and/or modify
  15. ** it under the terms of the GNU General Public License as published by
  16. **      the Free Software Foundation; either version 2 of the License, or
  17. **      (at your option) any later version.
  18. */
  19. #define __KERNEL_SYSCALLS__
  20. #undef ENTRY_SYS_CPUS /* syscall support for iCOD-like functionality */
  21. #include <linux/autoconf.h>
  22. #include <linux/types.h>
  23. #include <linux/spinlock.h>
  24. #include <linux/slab.h>
  25. #include <linux/kernel.h>
  26. #include <linux/sched.h>
  27. #include <linux/init.h>
  28. #include <linux/interrupt.h>
  29. #include <linux/smp.h>
  30. #include <linux/kernel_stat.h>
  31. #include <linux/mm.h>
  32. #include <linux/delay.h>
  33. #include <asm/system.h>
  34. #include <asm/atomic.h>
  35. #include <asm/bitops.h>
  36. #include <asm/current.h>
  37. #include <asm/delay.h>
  38. #include <asm/pgalloc.h> /* for flush_tlb_all() proto/macro */
  39. #include <asm/io.h>
  40. #include <asm/irq.h> /* for CPU_IRQ_REGION and friends */
  41. #include <asm/mmu_context.h>
  42. #include <asm/page.h>
  43. #include <asm/pgtable.h>
  44. #include <asm/pgalloc.h>
  45. #include <asm/processor.h>
  46. #include <asm/ptrace.h>
  47. #include <asm/unistd.h>
  48. #define kDEBUG 0
  49. spinlock_t pa_dbit_lock = SPIN_LOCK_UNLOCKED;
  50. spinlock_t smp_lock = SPIN_LOCK_UNLOCKED;
  51. volatile struct task_struct *smp_init_current_idle_task;
  52. spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
  53. static volatile int smp_commenced = 0;   /* Set when the idlers are all forked */
  54. static volatile int cpu_now_booting = 0;      /* track which CPU is booting */
  55. volatile unsigned long cpu_online_map = 0;   /* Bitmap of online CPUs */
  56. #define IS_LOGGED_IN(cpunum) (test_bit(cpunum, (atomic_t *)&cpu_online_map))
  57. int smp_num_cpus = 1;
  58. int smp_threads_ready = 0;
  59. static int max_cpus = -1;      /* Command line */
  60. struct smp_call_struct {
  61. void (*func) (void *info);
  62. void *info;
  63. long wait;
  64. atomic_t unstarted_count;
  65. atomic_t unfinished_count;
  66. };
  67. static volatile struct smp_call_struct *smp_call_function_data;
  68. enum ipi_message_type {
  69. IPI_NOP=0,
  70. IPI_RESCHEDULE=1,
  71. IPI_CALL_FUNC,
  72. IPI_CPU_START,
  73. IPI_CPU_STOP,
  74. IPI_CPU_TEST
  75. };
  76. /********** SMP inter processor interrupt and communication routines */
  77. #undef PER_CPU_IRQ_REGION
  78. #ifdef PER_CPU_IRQ_REGION
  79. /* XXX REVISIT Ignore for now.
  80. **    *May* need this "hook" to register IPI handler
  81. **    once we have perCPU ExtIntr switch tables.
  82. */
  83. static void
  84. ipi_init(int cpuid)
  85. {
  86. /* If CPU is present ... */
  87. #ifdef ENTRY_SYS_CPUS
  88. /* *and* running (not stopped) ... */
  89. #error iCOD support wants state checked here.
  90. #endif
  91. #error verify IRQ_OFFSET(IPI_IRQ) is ipi_interrupt() in new IRQ region
  92. if(IS_LOGGED_IN(cpuid) )
  93. {
  94. switch_to_idle_task(current);
  95. }
  96. return;
  97. }
  98. #endif
  99. /*
  100. ** Yoink this CPU from the runnable list... 
  101. **
  102. */
  103. static void
  104. halt_processor(void) 
  105. {
  106. #ifdef ENTRY_SYS_CPUS
  107. #error halt_processor() needs rework
  108. /*
  109. ** o migrate I/O interrupts off this CPU.
  110. ** o leave IPI enabled - __cli() will disable IPI.
  111. ** o leave CPU in online map - just change the state
  112. */
  113. cpu_data[this_cpu].state = STATE_STOPPED;
  114. mark_bh(IPI_BH);
  115. #else
  116. /* REVISIT : redirect I/O Interrupts to another CPU? */
  117. /* REVISIT : does PM *know* this CPU isn't available? */
  118. clear_bit(smp_processor_id(), (void *)&cpu_online_map);
  119. __cli();
  120. for (;;)
  121. ;
  122. #endif
  123. }
  124. void
  125. ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
  126. {
  127. int this_cpu = smp_processor_id();
  128. struct cpuinfo_parisc *p = &cpu_data[this_cpu];
  129. unsigned long ops;
  130. unsigned long flags;
  131. /* Count this now; we may make a call that never returns. */
  132. p->ipi_count++;
  133. mb(); /* Order interrupt and bit testing. */
  134. for (;;) {
  135. spin_lock_irqsave(&(p->lock),flags);
  136. ops = p->pending_ipi;
  137. p->pending_ipi = 0;
  138. spin_unlock_irqrestore(&(p->lock),flags);
  139. mb(); /* Order bit clearing and data access. */
  140. if (!ops)
  141.     break;
  142. while (ops) {
  143. unsigned long which = ffz(~ops);
  144. switch (which) {
  145. case IPI_RESCHEDULE:
  146. #if (kDEBUG>=100)
  147. printk(KERN_DEBUG "CPU%d IPI_RESCHEDULEn",this_cpu);
  148. #endif /* kDEBUG */
  149. ops &= ~(1 << IPI_RESCHEDULE);
  150. /*
  151.  * Reschedule callback.  Everything to be
  152.  * done is done by the interrupt return path.
  153.  */
  154. break;
  155. case IPI_CALL_FUNC:
  156. #if (kDEBUG>=100)
  157. printk(KERN_DEBUG "CPU%d IPI_CALL_FUNCn",this_cpu);
  158. #endif /* kDEBUG */
  159. ops &= ~(1 << IPI_CALL_FUNC);
  160. {
  161. volatile struct smp_call_struct *data;
  162. void (*func)(void *info);
  163. void *info;
  164. int wait;
  165. data = smp_call_function_data;
  166. func = data->func;
  167. info = data->info;
  168. wait = data->wait;
  169. mb();
  170. atomic_dec ((atomic_t *)&data->unstarted_count);
  171. /* At this point, *data can't
  172.  * be relied upon.
  173.  */
  174. (*func)(info);
  175. /* Notify the sending CPU that the
  176.  * task is done.
  177.  */
  178. mb();
  179. if (wait)
  180. atomic_dec ((atomic_t *)&data->unfinished_count);
  181. }
  182. break;
  183. case IPI_CPU_START:
  184. #if (kDEBUG>=100)
  185. printk(KERN_DEBUG "CPU%d IPI_CPU_STARTn",this_cpu);
  186. #endif /* kDEBUG */
  187. ops &= ~(1 << IPI_CPU_START);
  188. #ifdef ENTRY_SYS_CPUS
  189. p->state = STATE_RUNNING;
  190. #endif
  191. break;
  192. case IPI_CPU_STOP:
  193. #if (kDEBUG>=100)
  194. printk(KERN_DEBUG "CPU%d IPI_CPU_STOPn",this_cpu);
  195. #endif /* kDEBUG */
  196. ops &= ~(1 << IPI_CPU_STOP);
  197. #ifdef ENTRY_SYS_CPUS
  198. #else
  199. halt_processor();
  200. #endif
  201. break;
  202. case IPI_CPU_TEST:
  203. #if (kDEBUG>=100)
  204. printk(KERN_DEBUG "CPU%d is alive!n",this_cpu);
  205. #endif /* kDEBUG */
  206. ops &= ~(1 << IPI_CPU_TEST);
  207. break;
  208. default:
  209. printk(KERN_CRIT "Unknown IPI num on CPU%d: %lun",
  210. this_cpu, which);
  211. ops &= ~(1 << which);
  212. return;
  213. } /* Switch */
  214. } /* while (ops) */
  215. }
  216. return;
  217. }
  218. static inline void
  219. ipi_send(int cpu, enum ipi_message_type op)
  220. {
  221. struct cpuinfo_parisc *p = &cpu_data[cpu];
  222. unsigned long flags;
  223. spin_lock_irqsave(&(p->lock),flags);
  224. p->pending_ipi |= 1 << op;
  225. __raw_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa);
  226. spin_unlock_irqrestore(&(p->lock),flags);
  227. }
  228. static inline void
  229. send_IPI_single(int dest_cpu, enum ipi_message_type op)
  230. {
  231. if (dest_cpu == NO_PROC_ID) {
  232. BUG();
  233. return;
  234. }
  235. ipi_send(dest_cpu, op);
  236. }
  237. static inline void
  238. send_IPI_allbutself(enum ipi_message_type op)
  239. {
  240. int i;
  241. for (i = 0; i < smp_num_cpus; i++) {
  242. if (i != smp_processor_id())
  243. send_IPI_single(i, op);
  244. }
  245. }
  246. inline void 
  247. smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); }
  248. static inline void
  249. smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
  250. void 
  251. smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
  252. /**
  253.  * Run a function on all other CPUs.
  254.  *  <func> The function to run. This must be fast and non-blocking.
  255.  *  <info> An arbitrary pointer to pass to the function.
  256.  *  <retry> If true, keep retrying until ready.
  257.  *  <wait> If true, wait until function has completed on other CPUs.
  258.  *  [RETURNS]   0 on success, else a negative status code.
  259.  *
  260.  * Does not return until remote CPUs are nearly ready to execute <func>
  261.  * or have executed.
  262.  */
  263. int
  264. smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
  265. {
  266. struct smp_call_struct data;
  267. long timeout;
  268. static spinlock_t lock = SPIN_LOCK_UNLOCKED;
  269. data.func = func;
  270. data.info = info;
  271. data.wait = wait;
  272. atomic_set(&data.unstarted_count, smp_num_cpus - 1);
  273. atomic_set(&data.unfinished_count, smp_num_cpus - 1);
  274. if (retry) {
  275. spin_lock (&lock);
  276. while (smp_call_function_data != 0)
  277. barrier();
  278. }
  279. else {
  280. spin_lock (&lock);
  281. if (smp_call_function_data) {
  282. spin_unlock (&lock);
  283. return -EBUSY;
  284. }
  285. }
  286. smp_call_function_data = &data;
  287. spin_unlock (&lock);
  288. /*  Send a message to all other CPUs and wait for them to respond  */
  289. send_IPI_allbutself(IPI_CALL_FUNC);
  290. /*  Wait for response  */
  291. timeout = jiffies + HZ;
  292. while ( (atomic_read (&data.unstarted_count) > 0) &&
  293. time_before (jiffies, timeout) )
  294. barrier ();
  295. /* We either got one or timed out. Release the lock */
  296. mb();
  297. smp_call_function_data = NULL;
  298. if (atomic_read (&data.unstarted_count) > 0) {
  299. printk(KERN_CRIT "SMP CALL FUNCTION TIMED OUT! (cpu=%d)n",
  300.       smp_processor_id());
  301. return -ETIMEDOUT;
  302. }
  303. while (wait && atomic_read (&data.unfinished_count) > 0)
  304. barrier ();
  305. return 0;
  306. }
  307. /*
  308.  * Setup routine for controlling SMP activation
  309.  *
  310.  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  311.  * activation entirely (the MPS table probe still happens, though).
  312.  *
  313.  * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
  314.  * greater than 0, limits the maximum number of CPUs activated in
  315.  * SMP mode to <NUM>.
  316.  */
  317. static int __init nosmp(char *str)
  318. {
  319. max_cpus = 0;
  320. return 1;
  321. }
  322. __setup("nosmp", nosmp);
  323. static int __init maxcpus(char *str)
  324. {
  325. get_option(&str, &max_cpus);
  326. return 1;
  327. }
  328. __setup("maxcpus=", maxcpus);
  329. /*
  330.  * Flush all other CPU's tlb and then mine.  Do this with smp_call_function()
  331.  * as we want to ensure all TLB's flushed before proceeding.
  332.  */
  333. extern void flush_tlb_all_local(void);
  334. void
  335. smp_flush_tlb_all(void)
  336. {
  337. smp_call_function((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
  338. flush_tlb_all_local();
  339. }
  340. void 
  341. smp_do_timer(struct pt_regs *regs)
  342. {
  343. int cpu = smp_processor_id();
  344. struct cpuinfo_parisc *data = &cpu_data[cpu];
  345.         if (!--data->prof_counter) {
  346. data->prof_counter = data->prof_multiplier;
  347. update_process_times(user_mode(regs));
  348. }
  349. }
  350. /*
  351.  * Called by secondaries to update state and initialize CPU registers.
  352.  */
  353. static void __init
  354. smp_cpu_init(int cpunum)
  355. {
  356. extern int init_per_cpu(int);  /* arch/parisc/kernel/setup.c */
  357. extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
  358. /* Set modes and Enable floating point coprocessor */
  359. (void) init_per_cpu(cpunum);
  360. disable_sr_hashing();
  361. mb();
  362. /* Well, support 2.4 linux scheme as well. */
  363. if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map)))
  364. {
  365. extern void machine_halt(void); /* arch/parisc.../process.c */
  366. printk(KERN_CRIT "CPU#%d already initialized!n", cpunum);
  367. machine_halt();
  368. }  
  369. /* Initialise the idle task for this CPU */
  370. atomic_inc(&init_mm.mm_count);
  371. current->active_mm = &init_mm;
  372. if(current->mm)
  373. BUG();
  374. enter_lazy_tlb(&init_mm, current, cpunum);
  375. init_IRQ();   /* make sure no IRQ's are enabled or pending */
  376. }
  377. /*
  378.  * Slaves start using C here. Indirectly called from smp_slave_stext.
  379.  * Do what start_kernel() and main() do for boot strap processor (aka monarch)
  380.  */
  381. void __init smp_callin(void)
  382. {
  383. extern void cpu_idle(void); /* arch/parisc/kernel/process.c */
  384. int slave_id = cpu_now_booting;
  385. #if 0
  386. void *istack;
  387. #endif
  388. smp_cpu_init(slave_id);
  389. #if 0 /* NOT WORKING YET - see entry.S */
  390. istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
  391. if (istack == NULL) {
  392.     printk(KERN_CRIT "Failed to allocate interrupt stack for cpu %dn",slave_id);
  393.     BUG();
  394. }
  395. mtctl(istack,31);
  396. #endif
  397. flush_cache_all_local(); /* start with known state */
  398. flush_tlb_all_local();
  399. local_irq_enable();  /* Interrupts have been off until now */
  400. /* Slaves wait here until Big Poppa daddy say "jump" */
  401. mb(); /* PARANOID */
  402. while (!smp_commenced) ;
  403. mb(); /* PARANOID */
  404. cpu_idle();      /* Wait for timer to schedule some work */
  405. /* NOTREACHED */
  406. panic("smp_callin() AAAAaaaaahhhh....n");
  407. }
  408. /*
  409.  * Create the idle task for a new Slave CPU.  DO NOT use kernel_thread()
  410.  * because that could end up calling schedule(). If it did, the new idle
  411.  * task could get scheduled before we had a chance to remove it from the
  412.  * run-queue...
  413.  */
  414. static int fork_by_hand(void)
  415. {
  416. struct pt_regs regs;  
  417. /*
  418.  * don't care about the regs settings since
  419.  * we'll never reschedule the forked task.
  420.  */
  421. return do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
  422. }
  423. /*
  424.  * Bring one cpu online.
  425.  */
  426. static int smp_boot_one_cpu(int cpuid, int cpunum)
  427. {
  428. struct task_struct *idle;
  429. long timeout;
  430. /* 
  431.  * Create an idle task for this CPU.  Note the address wed* give 
  432.  * to kernel_thread is irrelevant -- it's going to start
  433.  * where OS_BOOT_RENDEVZ vector in SAL says to start.  But
  434.  * this gets all the other task-y sort of data structures set
  435.  * up like we wish.   We need to pull the just created idle task 
  436.  * off the run queue and stuff it into the init_tasks[] array.  
  437.  * Sheesh . . .
  438.  */
  439. if (fork_by_hand() < 0) 
  440. panic("SMP: fork failed for CPU:%d", cpuid);
  441. idle = init_task.prev_task;
  442. if (!idle)
  443. panic("SMP: No idle process for CPU:%d", cpuid);
  444. task_set_cpu(idle, cpunum); /* manually schedule idle task */
  445. del_from_runqueue(idle);
  446. unhash_process(idle);
  447. init_tasks[cpunum] = idle;
  448. /* Let _start know what logical CPU we're booting
  449. ** (offset into init_tasks[],cpu_data[])
  450. */
  451. cpu_now_booting = cpunum;
  452. /* 
  453. ** boot strap code needs to know the task address since
  454. ** it also contains the process stack.
  455. */
  456. smp_init_current_idle_task = idle ;
  457. mb();
  458. /*
  459. ** This gets PDC to release the CPU from a very tight loop.
  460. ** See MEM_RENDEZ comments in head.S.
  461. */
  462. __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa);
  463. mb();
  464. /* 
  465.  * OK, wait a bit for that CPU to finish staggering about. 
  466.  * Slave will set a bit when it reaches smp_cpu_init() and then
  467.  * wait for smp_commenced to be 1.
  468.  * Once we see the bit change, we can move on.
  469.  */
  470. for (timeout = 0; timeout < 10000; timeout++) {
  471. if(IS_LOGGED_IN(cpunum)) {
  472. /* Which implies Slave has started up */
  473. cpu_now_booting = 0;
  474. smp_init_current_idle_task = NULL;
  475. goto alive ;
  476. }
  477. udelay(100);
  478. barrier();
  479. }
  480. init_tasks[cpunum] = NULL;
  481. free_task_struct(idle);
  482. printk(KERN_CRIT "SMP: CPU:%d is stuck.n", cpuid);
  483. return -1;
  484. alive:
  485. /* Remember the Slave data */
  486. #if (kDEBUG>=100)
  487. printk(KERN_DEBUG "SMP: CPU:%d (num %d) came alive after %ld _usn",
  488. cpuid,  cpunum, timeout * 100);
  489. #endif /* kDEBUG */
  490. #ifdef ENTRY_SYS_CPUS
  491. cpu_data[cpunum].state = STATE_RUNNING;
  492. #endif
  493. return 0;
  494. }
  495. /*
  496. ** inventory.c:do_inventory() has already 'discovered' the additional CPU's.
  497. ** We are ready to wrest them from PDC's control now.
  498. ** Called by smp_init bring all the secondaries online and hold them.  
  499. **
  500. ** o Setup of the IPI irq handler is done in irq.c.
  501. ** o MEM_RENDEZ is initialzed in head.S:stext()
  502. **
  503. */
  504. void __init smp_boot_cpus(void)
  505. {
  506. int i, cpu_count = 1;
  507. unsigned long bogosum = loops_per_jiffy; /* Count Monarch */
  508. /* REVISIT - assumes first CPU reported by PAT PDC is BSP */
  509. int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */
  510. /* Setup BSP mappings */
  511. printk(KERN_DEBUG "SMP: bootstrap CPU ID is %dn",bootstrap_processor);
  512. init_task.processor = bootstrap_processor; 
  513. current->processor = bootstrap_processor;
  514. cpu_online_map = 1 << bootstrap_processor; /* Mark Boostrap processor as present */
  515. current->active_mm = &init_mm;
  516. #ifdef ENTRY_SYS_CPUS
  517. cpu_data[0].state = STATE_RUNNING;
  518. #endif
  519. /* Nothing to do when told not to.  */
  520. if (max_cpus == 0) {
  521. printk(KERN_INFO "SMP mode deactivated.n");
  522. return;
  523. }
  524. if (max_cpus != -1) 
  525. printk(KERN_INFO "Limiting CPUs to %dn", max_cpus);
  526. /* We found more than one CPU.... */
  527. if (boot_cpu_data.cpu_count > 1) {
  528. for (i = 0; i < NR_CPUS; i++) {
  529. if (cpu_data[i].cpuid == NO_PROC_ID || 
  530.     cpu_data[i].cpuid == bootstrap_processor)
  531. continue;
  532. if (smp_boot_one_cpu(cpu_data[i].cpuid, cpu_count) < 0)
  533. continue;
  534. bogosum += loops_per_jiffy;
  535. cpu_count++; /* Count good CPUs only... */
  536. /* Bail when we've started as many CPUS as told to */
  537. if (cpu_count == max_cpus)
  538. break;
  539. }
  540. }
  541. if (cpu_count == 1) {
  542. printk(KERN_INFO "SMP: Bootstrap processor only.n");
  543. }
  544. printk(KERN_INFO "SMP: Total %d of %d processors activated "
  545.        "(%lu.%02lu BogoMIPS noticed).n",
  546.        cpu_count, boot_cpu_data.cpu_count, (bogosum + 25) / 5000,
  547.        ((bogosum + 25) / 50) % 100);
  548. smp_num_cpus = cpu_count;
  549. #ifdef PER_CPU_IRQ_REGION
  550. ipi_init();
  551. #endif
  552. return;
  553. }
  554. /* 
  555.  * Called from main.c by Monarch Processor.
  556.  * After this, any CPU can schedule any task.
  557.  */
  558. void smp_commence(void)
  559. {
  560. smp_commenced = 1;
  561. mb();
  562. return;
  563. }
  564. #ifdef ENTRY_SYS_CPUS
  565. /* Code goes along with:
  566. **    entry.s:        ENTRY_NAME(sys_cpus)   / * 215, for cpu stat * /
  567. */
  568. int sys_cpus(int argc, char **argv)
  569. {
  570. int i,j=0;
  571. extern int current_pid(int cpu);
  572. if( argc > 2 ) {
  573. printk("sys_cpus:Only one argument supportedn");
  574. return (-1);
  575. }
  576. if ( argc == 1 ){
  577. #ifdef DUMP_MORE_STATE
  578. for(i=0; i<NR_CPUS; i++) {
  579. int cpus_per_line = 4;
  580. if(IS_LOGGED_IN(i)) {
  581. if (j++ % cpus_per_line)
  582. printk(" %3d",i);
  583. else
  584. printk("n %3d",i);
  585. }
  586. }
  587. printk("n"); 
  588. #else
  589.      printk("n 0n"); 
  590. #endif
  591. } else if((argc==2) && !(strcmp(argv[1],"-l"))) {
  592. printk("nCPUSTATE  TASK CPUNUM CPUID HARDCPU(HPA)n");
  593. #ifdef DUMP_MORE_STATE
  594. for(i=0;i<NR_CPUS;i++) {
  595. if (!IS_LOGGED_IN(i))
  596. continue;
  597. if (cpu_data[i].cpuid != NO_PROC_ID) {
  598. switch(cpu_data[i].state) {
  599. case STATE_RENDEZVOUS:
  600. printk("RENDEZVS ");
  601. break;
  602. case STATE_RUNNING:
  603. printk((current_pid(i)!=0) ? "RUNNING  " : "IDLING   ");
  604. break;
  605. case STATE_STOPPED:
  606. printk("STOPPED  ");
  607. break;
  608. case STATE_HALTED:
  609. printk("HALTED   ");
  610. break;
  611. default:
  612. printk("%08x?", cpu_data[i].state);
  613. break;
  614. }
  615. if(IS_LOGGED_IN(i)) {
  616. printk(" %4d",current_pid(i));
  617. }
  618. printk(" %6d",cpu_number_map(i));
  619. printk(" %5d",i);
  620. printk(" 0x%lxn",cpu_data[i].hpa);
  621. }
  622. }
  623. #else
  624. printk("n%s  %4d      0     0 --------",
  625. (current->pid)?"RUNNING ": "IDLING  ",current->pid); 
  626. #endif
  627. } else if ((argc==2) && !(strcmp(argv[1],"-s"))) { 
  628. #ifdef DUMP_MORE_STATE
  629.       printk("nCPUSTATE   CPUIDn");
  630. for (i=0;i<NR_CPUS;i++) {
  631. if (!IS_LOGGED_IN(i))
  632. continue;
  633. if (cpu_data[i].cpuid != NO_PROC_ID) {
  634. switch(cpu_data[i].state) {
  635. case STATE_RENDEZVOUS:
  636. printk("RENDEZVS");break;
  637. case STATE_RUNNING:
  638. printk((current_pid(i)!=0) ? "RUNNING " : "IDLING");
  639. break;
  640. case STATE_STOPPED:
  641. printk("STOPPED ");break;
  642. case STATE_HALTED:
  643. printk("HALTED  ");break;
  644. default:
  645. }
  646. printk("  %5dn",i);
  647. }
  648. }
  649. #else
  650. printk("n%s    CPU0",(current->pid==0)?"RUNNING ":"IDLING  "); 
  651. #endif
  652. } else {
  653. printk("sys_cpus:Unknown requestn");
  654. return (-1);
  655. }
  656. return 0;
  657. }
  658. #endif /* ENTRY_SYS_CPUS */
  659. #ifdef CONFIG_PROC_FS
  660. int __init
  661. setup_profiling_timer(unsigned int multiplier)
  662. {
  663. return -EINVAL;
  664. }
  665. #endif