1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/kernel_stat.h>
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/threads.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/interrupt.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/spinlock.h>
25#include <linux/irq.h>
26#include <linux/cache.h>
27
28#include <asm/hwrpb.h>
29#include <asm/ptrace.h>
30#include <asm/atomic.h>
31
32#include <asm/io.h>
33#include <asm/irq.h>
34#include <asm/bitops.h>
35#include <asm/pgtable.h>
36#include <asm/pgalloc.h>
37#include <asm/hardirq.h>
38#include <asm/softirq.h>
39#include <asm/mmu_context.h>
40
41#define __KERNEL_SYSCALLS__
42#include <asm/unistd.h>
43
44#include "proto.h"
45#include "irq_impl.h"
46
47
48#define DEBUG_SMP 0
49#if DEBUG_SMP
50#define DBGS(args) printk args
51#else
52#define DBGS(args)
53#endif
54
55
56struct cpuinfo_alpha cpu_data[NR_CPUS];
57
58
59static struct {
60 unsigned long bits ____cacheline_aligned;
61} ipi_data[NR_CPUS] __cacheline_aligned;
62
63enum ipi_message_type {
64 IPI_RESCHEDULE,
65 IPI_CALL_FUNC,
66 IPI_CPU_STOP,
67};
68
69spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
70
71
72static unsigned long smp_secondary_alive;
73
74
75unsigned long cpu_present_mask;
76
77
78static unsigned long hwrpb_cpu_present_mask __initdata = 0;
79
80static int max_cpus = -1;
81int smp_num_probed;
82int smp_num_cpus = 1;
83int smp_threads_ready;
84cycles_t cacheflush_time;
85
86int __cpu_number_map[NR_CPUS];
87int __cpu_logical_map[NR_CPUS];
88
89extern void calibrate_delay(void);
90extern asmlinkage void entInt(void);
91
92
93static int __init nosmp(char *str)
94{
95 max_cpus = 0;
96 return 1;
97}
98
99__setup("nosmp", nosmp);
100
101static int __init maxcpus(char *str)
102{
103 get_option(&str, &max_cpus);
104 return 1;
105}
106
107__setup("maxcpus", maxcpus);
108
109
110
111
112
113
114static inline void __init
115smp_store_cpu_info(int cpuid)
116{
117 cpu_data[cpuid].loops_per_jiffy = loops_per_jiffy;
118 cpu_data[cpuid].last_asn = ASN_FIRST_VERSION;
119 cpu_data[cpuid].need_new_asn = 0;
120 cpu_data[cpuid].asn_lock = 0;
121 local_irq_count(cpuid) = 0;
122 local_bh_count(cpuid) = 0;
123}
124
125
126
127
128static inline void __init
129smp_setup_percpu_timer(int cpuid)
130{
131 cpu_data[cpuid].prof_counter = 1;
132 cpu_data[cpuid].prof_multiplier = 1;
133}
134
135static void __init
136wait_boot_cpu_to_stop(int cpuid)
137{
138 long stop = jiffies + 10*HZ;
139
140 while (time_before(jiffies, stop)) {
141 if (!smp_secondary_alive)
142 return;
143 barrier();
144 }
145
146 printk("wait_boot_cpu_to_stop: FAILED on CPU %d, hanging now\n", cpuid);
147 for (;;)
148 barrier();
149}
150
151
152
153
154void __init
155smp_callin(void)
156{
157 int cpuid = hard_smp_processor_id();
158
159 if (current != init_tasks[cpu_number_map(cpuid)]) {
160 printk("BUG: smp_calling: cpu %d current %p init_tasks[cpu_number_map(cpuid)] %p\n",
161 cpuid, current, init_tasks[cpu_number_map(cpuid)]);
162 }
163
164 DBGS(("CALLIN %d state 0x%lx\n", cpuid, current->state));
165
166
167 wrmces(7);
168
169
170 trap_init();
171
172
173 wrent(entInt, 0);
174
175
176 smp_setup_percpu_timer(cpuid);
177
178
179 __sti();
180
181
182
183
184
185 wait_boot_cpu_to_stop(cpuid);
186 mb();
187 calibrate_delay();
188
189 smp_store_cpu_info(cpuid);
190
191
192
193
194 wmb();
195 smp_secondary_alive = 1;
196
197
198 while (!smp_threads_ready)
199 barrier();
200
201 DBGS(("smp_callin: commencing CPU %d current %p\n",
202 cpuid, current));
203
204
205 init_idle();
206
207
208 atomic_inc(&init_mm.mm_count);
209 current->active_mm = &init_mm;
210
211 cpu_idle();
212}
213
214
215
216
217
218
219
220
221static void __init
222smp_tune_scheduling (int cpuid)
223{
224 struct percpu_struct *cpu;
225 unsigned long on_chip_cache;
226 unsigned long freq;
227
228 cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset
229 + cpuid * hwrpb->processor_size);
230 switch (cpu->type)
231 {
232 case EV45_CPU:
233 on_chip_cache = 16 + 16;
234 break;
235
236 case EV5_CPU:
237 case EV56_CPU:
238 on_chip_cache = 8 + 8 + 96;
239 break;
240
241 case PCA56_CPU:
242 on_chip_cache = 16 + 8;
243 break;
244
245 case EV6_CPU:
246 case EV67_CPU:
247 on_chip_cache = 64 + 64;
248 break;
249
250 default:
251 on_chip_cache = 8 + 8;
252 break;
253 }
254
255 freq = hwrpb->cycle_freq ? : est_cycle_freq;
256
257#if 0
258
259 cacheflush_time = freq / 1024L * on_chip_cache / 5000L;
260
261 printk("Using heuristic of %d cycles.\n",
262 cacheflush_time);
263#else
264
265 cacheflush_time = INT_MAX;
266
267 printk("Using heuristic of %d cycles.\n",
268 cacheflush_time);
269#endif
270}
271
272
273
274
275
276static void
277send_secondary_console_msg(char *str, int cpuid)
278{
279 struct percpu_struct *cpu;
280 register char *cp1, *cp2;
281 unsigned long cpumask;
282 size_t len;
283 long timeout;
284
285 cpu = (struct percpu_struct *)
286 ((char*)hwrpb
287 + hwrpb->processor_offset
288 + cpuid * hwrpb->processor_size);
289
290 cpumask = (1UL << cpuid);
291 if (hwrpb->txrdy & cpumask)
292 goto delay1;
293 ready1:
294
295 cp2 = str;
296 len = strlen(cp2);
297 *(unsigned int *)&cpu->ipc_buffer[0] = len;
298 cp1 = (char *) &cpu->ipc_buffer[1];
299 memcpy(cp1, cp2, len);
300
301
302 wmb();
303 set_bit(cpuid, &hwrpb->rxrdy);
304
305 if (hwrpb->txrdy & cpumask)
306 goto delay2;
307 ready2:
308 return;
309
310delay1:
311
312 for (timeout = 1000000; timeout > 0; --timeout) {
313 if (!(hwrpb->txrdy & cpumask))
314 goto ready1;
315 udelay(10);
316 barrier();
317 }
318 goto timeout;
319
320delay2:
321
322 for (timeout = 1000000; timeout > 0; --timeout) {
323 if (!(hwrpb->txrdy & cpumask))
324 goto ready2;
325 udelay(10);
326 barrier();
327 }
328 goto timeout;
329
330timeout:
331 printk("Processor %x not ready\n", cpuid);
332 return;
333}
334
335
336
337
338static void
339recv_secondary_console_msg(void)
340{
341 int mycpu, i, cnt;
342 unsigned long txrdy = hwrpb->txrdy;
343 char *cp1, *cp2, buf[80];
344 struct percpu_struct *cpu;
345
346 DBGS(("recv_secondary_console_msg: TXRDY 0x%lx.\n", txrdy));
347
348 mycpu = hard_smp_processor_id();
349
350 for (i = 0; i < NR_CPUS; i++) {
351 if (!(txrdy & (1UL << i)))
352 continue;
353
354 DBGS(("recv_secondary_console_msg: "
355 "TXRDY contains CPU %d.\n", i));
356
357 cpu = (struct percpu_struct *)
358 ((char*)hwrpb
359 + hwrpb->processor_offset
360 + i * hwrpb->processor_size);
361
362 DBGS(("recv_secondary_console_msg: on %d from %d"
363 " HALT_REASON 0x%lx FLAGS 0x%lx\n",
364 mycpu, i, cpu->halt_reason, cpu->flags));
365
366 cnt = cpu->ipc_buffer[0] >> 32;
367 if (cnt <= 0 || cnt >= 80)
368 strcpy(buf, "<<< BOGUS MSG >>>");
369 else {
370 cp1 = (char *) &cpu->ipc_buffer[11];
371 cp2 = buf;
372 strcpy(cp2, cp1);
373
374 while ((cp2 = strchr(cp2, '\r')) != 0) {
375 *cp2 = ' ';
376 if (cp2[1] == '\n')
377 cp2[1] = ' ';
378 }
379 }
380
381 DBGS((KERN_INFO "recv_secondary_console_msg: on %d "
382 "message is '%s'\n", mycpu, buf));
383 }
384
385 hwrpb->txrdy = 0;
386}
387
388
389
390
391static int __init
392secondary_cpu_start(int cpuid, struct task_struct *idle)
393{
394 struct percpu_struct *cpu;
395 struct pcb_struct *hwpcb;
396 long timeout;
397
398 cpu = (struct percpu_struct *)
399 ((char*)hwrpb
400 + hwrpb->processor_offset
401 + cpuid * hwrpb->processor_size);
402 hwpcb = (struct pcb_struct *) cpu->hwpcb;
403
404
405
406
407
408 hwpcb->ksp = (unsigned long) idle + sizeof(union task_union) - 16;
409 hwpcb->usp = 0;
410 hwpcb->ptbr = idle->thread.ptbr;
411 hwpcb->pcc = 0;
412 hwpcb->asn = 0;
413 hwpcb->unique = virt_to_phys(&idle->thread);
414 hwpcb->flags = idle->thread.pal_flags;
415 hwpcb->res1 = hwpcb->res2 = 0;
416
417#if 0
418 DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx UNIQUE 0x%lx\n",
419 hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwpcb->unique));
420#endif
421 DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
422 cpuid, idle->state, idle->thread.pal_flags));
423
424
425 hwrpb->CPU_restart = __smp_callin;
426 hwrpb->CPU_restart_data = (unsigned long) __smp_callin;
427
428
429 hwrpb_update_checksum(hwrpb);
430
431
432
433
434
435
436 cpu->flags |= 0x22;
437 cpu->flags &= ~1;
438 wmb();
439
440 send_secondary_console_msg("START\r\n", cpuid);
441
442
443
444 for (timeout = 1000000; timeout > 0; timeout--) {
445 if (cpu->flags & 1)
446 goto started;
447 udelay(10);
448 barrier();
449 }
450 printk(KERN_ERR "SMP: Processor %d failed to start.\n", cpuid);
451 return -1;
452
453started:
454 DBGS(("secondary_cpu_start: SUCCESS for CPU %d!!!\n", cpuid));
455 return 0;
456}
457
458static int __init fork_by_hand(void)
459{
460 struct pt_regs regs;
461
462
463
464
465 return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0);
466}
467
468
469
470
471static int __init
472smp_boot_one_cpu(int cpuid, int cpunum)
473{
474 struct task_struct *idle;
475 long timeout;
476
477
478
479
480
481
482
483
484
485 if (fork_by_hand() < 0)
486 panic("failed fork for CPU %d", cpuid);
487
488 idle = init_task.prev_task;
489 if (!idle)
490 panic("No idle process for CPU %d", cpuid);
491 if (idle == &init_task)
492 panic("idle process is init_task for CPU %d", cpuid);
493
494 idle->processor = cpuid;
495 idle->cpus_runnable = 1 << cpuid;
496 __cpu_logical_map[cpunum] = cpuid;
497 __cpu_number_map[cpuid] = cpunum;
498
499 del_from_runqueue(idle);
500 unhash_process(idle);
501 init_tasks[cpunum] = idle;
502
503 DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
504 cpuid, idle->state, idle->flags));
505
506
507
508 smp_secondary_alive = -1;
509
510
511 if (secondary_cpu_start(cpuid, idle))
512 return -1;
513
514 mb();
515
516 smp_secondary_alive = 0;
517
518
519
520 for (timeout = 0; timeout < 1000000; timeout++) {
521 if (smp_secondary_alive == 1)
522 goto alive;
523 udelay(10);
524 barrier();
525 }
526
527
528 __cpu_logical_map[cpunum] = -1;
529 __cpu_number_map[cpuid] = -1;
530
531
532 free_task_struct(idle);
533
534 printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
535 return -1;
536
537alive:
538
539 return 0;
540}
541
542
543
544
545
546void __init
547setup_smp(void)
548{
549 struct percpu_struct *cpubase, *cpu;
550 int i;
551
552 if (boot_cpuid != 0) {
553 printk(KERN_WARNING "SMP: Booting off cpu %d instead of 0?\n",
554 boot_cpuid);
555 }
556
557 if (hwrpb->nr_processors > 1) {
558 int boot_cpu_palrev;
559
560 DBGS(("setup_smp: nr_processors %ld\n",
561 hwrpb->nr_processors));
562
563 cpubase = (struct percpu_struct *)
564 ((char*)hwrpb + hwrpb->processor_offset);
565 boot_cpu_palrev = cpubase->pal_revision;
566
567 for (i = 0; i < hwrpb->nr_processors; i++ ) {
568 cpu = (struct percpu_struct *)
569 ((char *)cpubase + i*hwrpb->processor_size);
570 if ((cpu->flags & 0x1cc) == 0x1cc) {
571 smp_num_probed++;
572
573 hwrpb_cpu_present_mask |= (1UL << i);
574 cpu->pal_revision = boot_cpu_palrev;
575 }
576
577 DBGS(("setup_smp: CPU %d: flags 0x%lx type 0x%lx\n",
578 i, cpu->flags, cpu->type));
579 DBGS(("setup_smp: CPU %d: PAL rev 0x%lx\n",
580 i, cpu->pal_revision));
581 }
582 } else {
583 smp_num_probed = 1;
584 hwrpb_cpu_present_mask = (1UL << boot_cpuid);
585 }
586 cpu_present_mask = 1UL << boot_cpuid;
587
588 printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
589 smp_num_probed, hwrpb_cpu_present_mask);
590}
591
592
593
594
595void __init
596smp_boot_cpus(void)
597{
598 int cpu_count, i;
599 unsigned long bogosum;
600
601
602 memset(__cpu_number_map, -1, sizeof(__cpu_number_map));
603 memset(__cpu_logical_map, -1, sizeof(__cpu_logical_map));
604 memset(ipi_data, 0, sizeof(ipi_data));
605
606 __cpu_number_map[boot_cpuid] = 0;
607 __cpu_logical_map[0] = boot_cpuid;
608 current->processor = boot_cpuid;
609
610 smp_store_cpu_info(boot_cpuid);
611 smp_tune_scheduling(boot_cpuid);
612 smp_setup_percpu_timer(boot_cpuid);
613
614 init_idle();
615
616
617 atomic_inc(&init_mm.mm_count);
618 current->active_mm = &init_mm;
619
620
621 if (smp_num_probed == 1 || max_cpus == 0) {
622 printk(KERN_INFO "SMP mode deactivated.\n");
623 return;
624 }
625
626 printk(KERN_INFO "SMP starting up secondaries.\n");
627
628 cpu_count = 1;
629 for (i = 0; i < NR_CPUS; i++) {
630 if (i == boot_cpuid)
631 continue;
632
633 if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
634 continue;
635
636 if (smp_boot_one_cpu(i, cpu_count))
637 continue;
638
639 cpu_present_mask |= 1UL << i;
640 cpu_count++;
641 }
642
643 if (cpu_count == 1) {
644 printk(KERN_ERR "SMP: Only one lonely processor alive.\n");
645 return;
646 }
647
648 bogosum = 0;
649 for (i = 0; i < NR_CPUS; i++) {
650 if (cpu_present_mask & (1UL << i))
651 bogosum += cpu_data[i].loops_per_jiffy;
652 }
653 printk(KERN_INFO "SMP: Total of %d processors activated "
654 "(%lu.%02lu BogoMIPS).\n",
655 cpu_count, (bogosum + 2500) / (500000/HZ),
656 ((bogosum + 2500) / (5000/HZ)) % 100);
657
658 smp_num_cpus = cpu_count;
659}
660
661
662
663
664
665void __init
666smp_commence(void)
667{
668
669 mb();
670}
671
672
673void
674smp_percpu_timer_interrupt(struct pt_regs *regs)
675{
676 int cpu = smp_processor_id();
677 unsigned long user = user_mode(regs);
678 struct cpuinfo_alpha *data = &cpu_data[cpu];
679
680
681 if (!user)
682 alpha_do_profile(regs->pc);
683
684 if (!--data->prof_counter) {
685
686
687
688 irq_enter(cpu, RTC_IRQ);
689
690 update_process_times(user);
691
692 data->prof_counter = data->prof_multiplier;
693 irq_exit(cpu, RTC_IRQ);
694
695 if (softirq_pending(cpu))
696 do_softirq();
697 }
698}
699
700int __init
701setup_profiling_timer(unsigned int multiplier)
702{
703 return -EINVAL;
704}
705
706
707static void
708send_ipi_message(unsigned long to_whom, enum ipi_message_type operation)
709{
710 long i, j;
711
712
713
714
715 mb();
716
717 for (i = 0, j = 1; i < NR_CPUS; ++i, j <<= 1) {
718 if (to_whom & j)
719 set_bit(operation, &ipi_data[i].bits);
720 }
721
722 mb();
723
724 for (i = 0, j = 1; i < NR_CPUS; ++i, j <<= 1) {
725 if (to_whom & j)
726 wripir(i);
727 }
728}
729
730
731
732
733struct smp_call_struct {
734 void (*func) (void *info);
735 void *info;
736 long wait;
737 atomic_t unstarted_count;
738 atomic_t unfinished_count;
739};
740
741static struct smp_call_struct *smp_call_function_data;
742
743
744
745
746static inline int
747pointer_lock (void *lock, void *data, int retry)
748{
749 void *old, *tmp;
750
751 mb();
752again:
753
754 asm volatile (
755 "1: ldq_l %0,%1\n"
756 " mov %3,%2\n"
757 " bne %0,2f\n"
758 " stq_c %2,%1\n"
759 " beq %2,1b\n"
760 "2:"
761 : "=&r"(old), "=m"(*(void **)lock), "=&r"(tmp)
762 : "r"(data)
763 : "memory");
764
765 if (old == 0)
766 return 0;
767 if (! retry)
768 return -EBUSY;
769
770 while (*(void **)lock)
771 barrier();
772 goto again;
773}
774
775void
776handle_ipi(struct pt_regs *regs)
777{
778 int this_cpu = smp_processor_id();
779 unsigned long *pending_ipis = &ipi_data[this_cpu].bits;
780 unsigned long ops;
781
782#if 0
783 DBGS(("handle_ipi: on CPU %d ops 0x%lx PC 0x%lx\n",
784 this_cpu, *pending_ipis, regs->pc));
785#endif
786
787 mb();
788 while ((ops = xchg(pending_ipis, 0)) != 0) {
789 mb();
790 do {
791 unsigned long which;
792
793 which = ops & -ops;
794 ops &= ~which;
795 which = ffz(~which);
796
797 if (which == IPI_RESCHEDULE) {
798
799
800 }
801 else if (which == IPI_CALL_FUNC) {
802 struct smp_call_struct *data;
803 void (*func)(void *info);
804 void *info;
805 int wait;
806
807 data = smp_call_function_data;
808 func = data->func;
809 info = data->info;
810 wait = data->wait;
811
812
813
814 mb();
815 atomic_dec (&data->unstarted_count);
816
817
818
819 (*func)(info);
820
821
822 mb();
823 if (wait) atomic_dec (&data->unfinished_count);
824 }
825 else if (which == IPI_CPU_STOP) {
826 halt();
827 }
828 else {
829 printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n",
830 this_cpu, which);
831 }
832 } while (ops);
833
834 mb();
835 }
836
837 cpu_data[this_cpu].ipi_count++;
838
839 if (hwrpb->txrdy)
840 recv_secondary_console_msg();
841}
842
843void
844smp_send_reschedule(int cpu)
845{
846#if DEBUG_IPI_MSG
847 if (cpu == hard_smp_processor_id())
848 printk(KERN_WARNING
849 "smp_send_reschedule: Sending IPI to self.\n");
850#endif
851 send_ipi_message(1UL << cpu, IPI_RESCHEDULE);
852}
853
854void
855smp_send_stop(void)
856{
857 unsigned long to_whom = cpu_present_mask ^ (1UL << smp_processor_id());
858#if DEBUG_IPI_MSG
859 if (hard_smp_processor_id() != boot_cpu_id)
860 printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n");
861#endif
862 send_ipi_message(to_whom, IPI_CPU_STOP);
863}
864
865
866
867
868
869
870
871
872
873
874
875
876
877int
878smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry,
879 int wait, unsigned long to_whom)
880{
881 struct smp_call_struct data;
882 long timeout;
883 int num_cpus_to_call;
884 long i,j;
885
886 data.func = func;
887 data.info = info;
888 data.wait = wait;
889
890 to_whom &= ~(1L << smp_processor_id());
891 for (i = 0, j = 1, num_cpus_to_call = 0; i < NR_CPUS; ++i, j <<= 1)
892 if (to_whom & j)
893 num_cpus_to_call++;
894
895 atomic_set(&data.unstarted_count, num_cpus_to_call);
896 atomic_set(&data.unfinished_count, num_cpus_to_call);
897
898
899 if (pointer_lock(&smp_call_function_data, &data, retry))
900 return -EBUSY;
901
902
903 send_ipi_message(to_whom, IPI_CALL_FUNC);
904
905
906 timeout = jiffies + HZ;
907 while (atomic_read (&data.unstarted_count) > 0
908 && time_before (jiffies, timeout))
909 barrier();
910
911
912 mb();
913 smp_call_function_data = 0;
914 if (atomic_read (&data.unstarted_count) > 0)
915 return -ETIMEDOUT;
916
917
918 if (wait) {
919 while (atomic_read (&data.unfinished_count) > 0)
920 barrier();
921 }
922
923 return 0;
924}
925
926int
927smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
928{
929 return smp_call_function_on_cpu (func, info, retry, wait,
930 cpu_present_mask);
931}
932
933static void
934ipi_imb(void *ignored)
935{
936 imb();
937}
938
939void
940smp_imb(void)
941{
942
943 if (smp_call_function(ipi_imb, NULL, 1, 1))
944 printk(KERN_CRIT "smp_imb: timed out\n");
945
946 imb();
947}
948
949static void
950ipi_flush_tlb_all(void *ignored)
951{
952 tbia();
953}
954
955void
956flush_tlb_all(void)
957{
958
959
960 if (smp_call_function(ipi_flush_tlb_all, NULL, 1, 1)) {
961 printk(KERN_CRIT "flush_tlb_all: timed out\n");
962 }
963
964 tbia();
965}
966
967#define asn_locked() (cpu_data[smp_processor_id()].asn_lock)
968
969static void
970ipi_flush_tlb_mm(void *x)
971{
972 struct mm_struct *mm = (struct mm_struct *) x;
973 if (mm == current->active_mm && !asn_locked())
974 flush_tlb_current(mm);
975 else
976 flush_tlb_other(mm);
977}
978
979void
980flush_tlb_mm(struct mm_struct *mm)
981{
982 if (mm == current->active_mm) {
983 flush_tlb_current(mm);
984 if (atomic_read(&mm->mm_users) <= 1) {
985 int i, cpu, this_cpu = smp_processor_id();
986 for (i = 0; i < smp_num_cpus; i++) {
987 cpu = cpu_logical_map(i);
988 if (cpu == this_cpu)
989 continue;
990 if (mm->context[cpu])
991 mm->context[cpu] = 0;
992 }
993 return;
994 }
995 }
996
997 if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) {
998 printk(KERN_CRIT "flush_tlb_mm: timed out\n");
999 }
1000}
1001
1002struct flush_tlb_page_struct {
1003 struct vm_area_struct *vma;
1004 struct mm_struct *mm;
1005 unsigned long addr;
1006};
1007
1008static void
1009ipi_flush_tlb_page(void *x)
1010{
1011 struct flush_tlb_page_struct *data = (struct flush_tlb_page_struct *)x;
1012 struct mm_struct * mm = data->mm;
1013
1014 if (mm == current->active_mm && !asn_locked())
1015 flush_tlb_current_page(mm, data->vma, data->addr);
1016 else
1017 flush_tlb_other(mm);
1018}
1019
1020void
1021flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
1022{
1023 struct flush_tlb_page_struct data;
1024 struct mm_struct *mm = vma->vm_mm;
1025
1026 if (mm == current->active_mm) {
1027 flush_tlb_current_page(mm, vma, addr);
1028 if (atomic_read(&mm->mm_users) <= 1) {
1029 int i, cpu, this_cpu = smp_processor_id();
1030 for (i = 0; i < smp_num_cpus; i++) {
1031 cpu = cpu_logical_map(i);
1032 if (cpu == this_cpu)
1033 continue;
1034 if (mm->context[cpu])
1035 mm->context[cpu] = 0;
1036 }
1037 return;
1038 }
1039 }
1040
1041 data.vma = vma;
1042 data.mm = mm;
1043 data.addr = addr;
1044
1045 if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) {
1046 printk(KERN_CRIT "flush_tlb_page: timed out\n");
1047 }
1048}
1049
1050void
1051flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
1052{
1053
1054 flush_tlb_mm(mm);
1055}
1056
1057static void
1058ipi_flush_icache_page(void *x)
1059{
1060 struct mm_struct *mm = (struct mm_struct *) x;
1061 if (mm == current->active_mm && !asn_locked())
1062 __load_new_mm_context(mm);
1063 else
1064 flush_tlb_other(mm);
1065}
1066
1067void
1068flush_icache_page(struct vm_area_struct *vma, struct page *page)
1069{
1070 struct mm_struct *mm = vma->vm_mm;
1071
1072 if ((vma->vm_flags & VM_EXEC) == 0)
1073 return;
1074
1075 if (mm == current->active_mm) {
1076 __load_new_mm_context(mm);
1077 if (atomic_read(&mm->mm_users) <= 1) {
1078 int i, cpu, this_cpu = smp_processor_id();
1079 for (i = 0; i < smp_num_cpus; i++) {
1080 cpu = cpu_logical_map(i);
1081 if (cpu == this_cpu)
1082 continue;
1083 if (mm->context[cpu])
1084 mm->context[cpu] = 0;
1085 }
1086 return;
1087 }
1088 }
1089
1090 if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) {
1091 printk(KERN_CRIT "flush_icache_page: timed out\n");
1092 }
1093}
1094
1095#ifdef CONFIG_DEBUG_SPINLOCK
1096void
1097spin_unlock(spinlock_t * lock)
1098{
1099 mb();
1100 lock->lock = 0;
1101
1102 lock->on_cpu = -1;
1103 lock->previous = NULL;
1104 lock->task = NULL;
1105 lock->base_file = "none";
1106 lock->line_no = 0;
1107}
1108
1109void
1110debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
1111{
1112 long tmp;
1113 long stuck;
1114 void *inline_pc = __builtin_return_address(0);
1115 unsigned long started = jiffies;
1116 int printed = 0;
1117 int cpu = smp_processor_id();
1118
1119 stuck = 1L << 30;
1120 try_again:
1121
1122
1123
1124
1125 __asm__ __volatile__(
1126 "1: ldl_l %0,%1\n"
1127 " subq %2,1,%2\n"
1128 " blbs %0,2f\n"
1129 " or %0,1,%0\n"
1130 " stl_c %0,%1\n"
1131 " beq %0,3f\n"
1132 "4: mb\n"
1133 ".subsection 2\n"
1134 "2: ldl %0,%1\n"
1135 " subq %2,1,%2\n"
1136 "3: blt %2,4b\n"
1137 " blbs %0,2b\n"
1138 " br 1b\n"
1139 ".previous"
1140 : "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
1141 : "1" (lock->lock), "2" (stuck) : "memory");
1142
1143 if (stuck < 0) {
1144 printk(KERN_WARNING
1145 "%s:%d spinlock stuck in %s at %p(%d)"
1146 " owner %s at %p(%d) %s:%d\n",
1147 base_file, line_no,
1148 current->comm, inline_pc, cpu,
1149 lock->task->comm, lock->previous,
1150 lock->on_cpu, lock->base_file, lock->line_no);
1151 stuck = 1L << 36;
1152 printed = 1;
1153 goto try_again;
1154 }
1155
1156
1157 lock->on_cpu = cpu;
1158 lock->previous = inline_pc;
1159 lock->task = current;
1160 lock->base_file = base_file;
1161 lock->line_no = line_no;
1162
1163 if (printed) {
1164 printk(KERN_WARNING
1165 "%s:%d spinlock grabbed in %s at %p(%d) %ld ticks\n",
1166 base_file, line_no, current->comm, inline_pc,
1167 cpu, jiffies - started);
1168 }
1169}
1170
1171int
1172debug_spin_trylock(spinlock_t * lock, const char *base_file, int line_no)
1173{
1174 int ret;
1175 if ((ret = !test_and_set_bit(0, lock))) {
1176 lock->on_cpu = smp_processor_id();
1177 lock->previous = __builtin_return_address(0);
1178 lock->task = current;
1179 } else {
1180 lock->base_file = base_file;
1181 lock->line_no = line_no;
1182 }
1183 return ret;
1184}
1185#endif
1186
1187#ifdef CONFIG_DEBUG_RWLOCK
1188void write_lock(rwlock_t * lock)
1189{
1190 long regx, regy;
1191 int stuck_lock, stuck_reader;
1192 void *inline_pc = __builtin_return_address(0);
1193
1194 try_again:
1195
1196 stuck_lock = 1<<30;
1197 stuck_reader = 1<<30;
1198
1199 __asm__ __volatile__(
1200 "1: ldl_l %1,%0\n"
1201 " blbs %1,6f\n"
1202 " blt %1,8f\n"
1203 " mov 1,%1\n"
1204 " stl_c %1,%0\n"
1205 " beq %1,6f\n"
1206 "4: mb\n"
1207 ".subsection 2\n"
1208 "6: blt %3,4b # debug\n"
1209 " subl %3,1,%3 # debug\n"
1210 " ldl %1,%0\n"
1211 " blbs %1,6b\n"
1212 "8: blt %4,4b # debug\n"
1213 " subl %4,1,%4 # debug\n"
1214 " ldl %1,%0\n"
1215 " blt %1,8b\n"
1216 " br 1b\n"
1217 ".previous"
1218 : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
1219 "=&r" (stuck_lock), "=&r" (stuck_reader)
1220 : "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
1221
1222 if (stuck_lock < 0) {
1223 printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
1224 goto try_again;
1225 }
1226 if (stuck_reader < 0) {
1227 printk(KERN_WARNING "write_lock stuck on readers at %p\n",
1228 inline_pc);
1229 goto try_again;
1230 }
1231}
1232
1233void read_lock(rwlock_t * lock)
1234{
1235 long regx;
1236 int stuck_lock;
1237 void *inline_pc = __builtin_return_address(0);
1238
1239 try_again:
1240
1241 stuck_lock = 1<<30;
1242
1243 __asm__ __volatile__(
1244 "1: ldl_l %1,%0;"
1245 " blbs %1,6f;"
1246 " subl %1,2,%1;"
1247 " stl_c %1,%0;"
1248 " beq %1,6f;"
1249 "4: mb\n"
1250 ".subsection 2\n"
1251 "6: ldl %1,%0;"
1252 " blt %2,4b # debug\n"
1253 " subl %2,1,%2 # debug\n"
1254 " blbs %1,6b;"
1255 " br 1b\n"
1256 ".previous"
1257 : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
1258 : "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
1259
1260 if (stuck_lock < 0) {
1261 printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
1262 goto try_again;
1263 }
1264}
1265#endif
1266