aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@bell.net>2018-10-16 20:49:56 -0400
committerHelge Deller <deller@gmx.de>2018-10-17 02:18:00 -0400
commita886c9791aed64d73f8c0038cc1506741ba216fa (patch)
treefce68683084a6861c96f13e030f2eaec9cb0e853
parent7c4ba3d38a3b013b79c3c07a639504cdc68fefdf (diff)
parisc: Reorder TLB flush timing calculation
On boot (mostly reboot), my c8000 sometimes crashes after it prints the TLB flush threshold. The lockup is hard. The front LED flashes red and the box must be unplugged to reset the error. I noticed that when the crash occurs the TLB flush threshold is about one quarter what it is on a successful boot. If I disabled the calculation, the crash didn't occur. There also seemed to be a timing dependency affecting the crash. I finally realized that the flush_tlb_all() timing test runs just after the secondary CPUs are started. There seems to be a problem with running flush_tlb_all() too soon after the CPUs are started. The timing for the range test always seemed okay. So, I reversed the order of the two timing tests and I haven't had a crash at this point so far. I added a couple of information messages which I have left to help with diagnosis if the problem should appear on another machine. This version reduces the minimum TLB flush threshold to 16 KiB. Signed-off-by: John David Anglin <dave.anglin@bell.net> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/kernel/cache.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index bddd2acebdcc..9f1c29d06574 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -364,7 +364,7 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm);
364#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */ 364#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
365static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD; 365static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
366 366
367#define FLUSH_TLB_THRESHOLD (2*1024*1024) /* 2MB initial TLB threshold */ 367#define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */
368static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD; 368static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD;
369 369
370void __init parisc_setup_cache_timing(void) 370void __init parisc_setup_cache_timing(void)
@@ -404,10 +404,6 @@ void __init parisc_setup_cache_timing(void)
404 goto set_tlb_threshold; 404 goto set_tlb_threshold;
405 } 405 }
406 406
407 alltime = mfctl(16);
408 flush_tlb_all();
409 alltime = mfctl(16) - alltime;
410
411 size = 0; 407 size = 0;
412 start = (unsigned long) _text; 408 start = (unsigned long) _text;
413 rangetime = mfctl(16); 409 rangetime = mfctl(16);
@@ -418,13 +414,19 @@ void __init parisc_setup_cache_timing(void)
418 } 414 }
419 rangetime = mfctl(16) - rangetime; 415 rangetime = mfctl(16) - rangetime;
420 416
421 printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n", 417 alltime = mfctl(16);
418 flush_tlb_all();
419 alltime = mfctl(16) - alltime;
420
421 printk(KERN_INFO "Whole TLB flush %lu cycles, Range flush %lu bytes %lu cycles\n",
422 alltime, size, rangetime); 422 alltime, size, rangetime);
423 423
424 threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime); 424 threshold = PAGE_ALIGN((num_online_cpus() * size * alltime) / rangetime);
425 printk(KERN_INFO "Calculated TLB flush threshold %lu KiB\n",
426 threshold/1024);
425 427
426set_tlb_threshold: 428set_tlb_threshold:
427 if (threshold) 429 if (threshold > parisc_tlb_flush_threshold)
428 parisc_tlb_flush_threshold = threshold; 430 parisc_tlb_flush_threshold = threshold;
429 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", 431 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
430 parisc_tlb_flush_threshold/1024); 432 parisc_tlb_flush_threshold/1024);