Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: mm: Improve Duplicate PD Fault handler

- Move the verbosity knob from .data to .bss by using inverted logic
- No need to readout PD1 descriptor
- clip the non pfn bits of PD0 to avoid clipping inside the loop

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

+22 -22
+22 -22
arch/arc/mm/tlb.c
··· 856 856 * the duplicate one. 857 857 * -Knob to be verbose abt it.(TODO: hook them up to debugfs) 858 858 */ 859 - volatile int dup_pd_verbose = 1;/* Be slient abt it or complain (default) */ 859 + volatile int dup_pd_silent; /* Be slient abt it or complain (default) */ 860 860 861 861 void do_tlb_overlap_fault(unsigned long cause, unsigned long address, 862 862 struct pt_regs *regs) 863 863 { 864 - int set, way, n; 865 - unsigned long flags, is_valid; 866 864 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 867 - unsigned int pd0[mmu->ways], pd1[mmu->ways]; 865 + unsigned int pd0[mmu->ways]; 866 + unsigned long flags; 867 + int set; 868 868 869 869 local_irq_save(flags); 870 870 ··· 874 874 /* loop thru all sets of TLB */ 875 875 for (set = 0; set < mmu->sets; set++) { 876 876 877 + int is_valid, way; 878 + 877 879 /* read out all the ways of current set */ 878 880 for (way = 0, is_valid = 0; way < mmu->ways; way++) { 879 881 write_aux_reg(ARC_REG_TLBINDEX, 880 882 SET_WAY_TO_IDX(mmu, set, way)); 881 883 write_aux_reg(ARC_REG_TLBCOMMAND, TLBRead); 882 884 pd0[way] = read_aux_reg(ARC_REG_TLBPD0); 883 - pd1[way] = read_aux_reg(ARC_REG_TLBPD1); 884 885 is_valid |= pd0[way] & _PAGE_PRESENT; 886 + pd0[way] &= PAGE_MASK; 885 887 } 886 888 887 889 /* If all the WAYS in SET are empty, skip to next SET */ ··· 892 890 893 891 /* Scan the set for duplicate ways: needs a nested loop */ 894 892 for (way = 0; way < mmu->ways - 1; way++) { 893 + 894 + int n; 895 + 895 896 if (!pd0[way]) 896 897 continue; 897 898 898 899 for (n = way + 1; n < mmu->ways; n++) { 899 - if ((pd0[way] & PAGE_MASK) == 900 - (pd0[n] & PAGE_MASK)) { 900 + if (pd0[way] != pd0[n]) 901 + continue; 901 902 902 - if (dup_pd_verbose) { 903 - pr_info("Duplicate PD's @" 904 - "[%d:%d]/[%d:%d]\n", 905 - set, way, set, n); 906 - pr_info("TLBPD0[%u]: %08x\n", 907 - way, pd0[way]); 908 - } 903 + if (!dup_pd_silent) 904 + pr_info("Dup TLB PD0 %08x @ set %d ways %d,%d\n", 905 + pd0[way], set, way, n); 909 906 910 - /* 911 - * clear entry @way and not @n. This is 912 - * critical to our optimised loop 913 - */ 914 - pd0[way] = pd1[way] = 0; 915 - write_aux_reg(ARC_REG_TLBINDEX, 907 + /* 908 + * clear entry @way and not @n. 909 + * This is critical to our optimised loop 910 + */ 911 + pd0[way] = 0; 912 + write_aux_reg(ARC_REG_TLBINDEX, 916 913 SET_WAY_TO_IDX(mmu, set, way)); 917 - __tlb_entry_erase(); 918 - } 914 + __tlb_entry_erase(); 919 915 } 920 916 } 921 917 }