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