From 288ae9cb14aad037114222e4c6dc1e6ddb5b4d4c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 7 Feb 2013 17:14:08 -0800 Subject: [PATCH 1/8] timeconst.pl: Eliminate Perl warning defined(@array) is deprecated in Perl and gives off a warning. Restructure the code to remove that warning. [ hpa: it would be interesting to revert to the timeconst.bc script. It appears that the failures reported by akpm during testing of that script was due to a known broken version of make, not a problem with bc. The Makefile rules could probably be restructured to avoid the make bug, or it is probably old enough that it doesn't matter. ] Reported-by: Andi Kleen Signed-off-by: H. Peter Anvin Cc: Andrew Morton Cc: --- kernel/timeconst.pl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl index eb51d76e058a40..3f42652a6a3749 100644 --- a/kernel/timeconst.pl +++ b/kernel/timeconst.pl @@ -369,10 +369,8 @@ (@) die "Usage: $0 HZ\n"; } - @val = @{$canned_values{$hz}}; - if (!defined(@val)) { - @val = compute_values($hz); - } + $cv = $canned_values{$hz}; + @val = defined($cv) ? @$cv : compute_values($hz); output($hz, @val); } exit 0; From b51bc9f1d64ed96ed63bed1e22e7acf8c1e19a68 Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:04 -0700 Subject: [PATCH 2/8] commit chris.dearman@imgtec.com patch about cacheflush issue on SMP multi-core. The strategy is to flush both dcache and icache on the local CPU by address if the range < cachesize or by index if the range >= cachesize, and to flush the cache by index on all other CPU's. The other CPU maybe running in different process whit different address mapping, protected_blast_icache_range_ipi() maybe failed, so flush icache all with local_r4k_flush_icache_ipi(). But local_r4k_flush_icache_ipi() flush icache all by index, both flush L1 icache and L2 cache, it slowdown the machine performance. Ingenic should optimized the routine later. Change-Id: Ie95e1fcbb0edf12fd18bdfb592bcaacaf1580d05 --- arch/mips/mm/c-jz.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index 1da9a5970fd17c..a60edc87ae45cc 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -57,6 +57,15 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info) preempt_enable(); } +static inline void r4k_on_other_cpu(void (*func) (void *info), void *info) +{ +#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) + preempt_disable(); + smp_call_function(func, info, 1); + preempt_enable(); +#endif +} + #if defined(CONFIG_MIPS_CMP) #define cpu_has_safe_index_cacheops 0 #else @@ -638,15 +647,15 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo { if (!cpu_has_ic_fills_f_dc) { if (end - start >= dcache_size) { - r4k_blast_dcache_jz(); + r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; protected_blast_dcache_range(start, end); } } - if (end - start > icache_size) - r4k_blast_icache_jz(); + if (end - start >= icache_size) + r4k_blast_icache(); else protected_blast_icache_range(start, end); } @@ -660,18 +669,25 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) { if (!cpu_has_ic_fills_f_dc) { if (end - start >= dcache_size) { - //r4k_blast_dcache_jz(); - r4k_on_each_cpu(local_r4k_flush_dcache_jz_ipi,0); + /* Flush complete dcache on all CPUs */ + r4k_on_each_cpu(local_r4k_flush_dcache_ipi,0); } else { - R4600_HIT_CACHEOP_WAR_IMPL; + /* Flush dcache by address on this CPU */ protected_blast_dcache_range(start, end); + /* Flush complete dcache on other CPUs */ + r4k_on_other_cpu(local_r4k_flush_dcache_ipi,0); } } - if (end - start > icache_size) - r4k_on_each_cpu(local_r4k_flush_icache_jz_ipi,0); - else + if (end - start >= icache_size) + /* Flush complete icache on all CPUs */ + r4k_on_each_cpu(local_r4k_flush_icache_ipi,0); + else { + /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); + /* Flush complete icache on other CPUs */ + r4k_on_other_cpu(local_r4k_flush_icache_ipi,0); + } } #endif From 39b709abc882c3bb941bb9e872a52f99db54c5fd Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:13 -0700 Subject: [PATCH 3/8] Add protected_blast_other_cpu_icache_range_ipi() for cacheflush. rjzcache.h blast_dcache32() remove K0_TO_K1_CHECK(). rjzcache.h fix blast_icache_jz() bug. Change-Id: I3f23ca4204cb804ee2f986bf0301a4c3e794a845 --- arch/mips/include/asm/rjzcache.h | 28 ++++++++++++++-- arch/mips/mm/c-jz.c | 55 ++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/rjzcache.h b/arch/mips/include/asm/rjzcache.h index 7c3f0ead203d5b..0b2710260c59db 100644 --- a/arch/mips/include/asm/rjzcache.h +++ b/arch/mips/include/asm/rjzcache.h @@ -598,6 +598,7 @@ static inline void blast_icache_jz(void) unsigned long start = INDEX_BASE; unsigned long end = start + current_cpu_data.icache.waysize * current_cpu_data.icache.ways; unsigned long addr = start; + do { i_cache(JZ_FETCH_LOCK, addr, 0);i_cache(Hit_Invalidate_I,addr,0); addr += 32; @@ -608,6 +609,29 @@ static inline void blast_icache_jz(void) i_cache(JZ_FETCH_LOCK, addr, 0);i_cache(Hit_Invalidate_I,addr,0); addr += 32; } while (addr < end); + + do { + i_cache(Index_Load_Tag_I,start,0); + if(read_c0_dtaglo() & 1) { + i_cache(Index_Invalidate_I,start,0); + } + start += 32; + i_cache(Index_Load_Tag_I,start,0); + if(read_c0_dtaglo() & 1) { + i_cache(Index_Invalidate_I,start,0); + } + start += 32; + i_cache(Index_Load_Tag_I,start,0); + if(read_c0_dtaglo() & 1) { + i_cache(Index_Invalidate_I,start,0); + } + start += 32; + i_cache(Index_Load_Tag_I,start,0); + if(read_c0_dtaglo() & 1) { + i_cache(Index_Invalidate_I,start,0); + } + start += 32; + }while(start < end); } static inline void blast_dcache32(void) @@ -799,7 +823,7 @@ static inline void protected_blast_icache_range(unsigned long start, unsigned long aend = (end - 1) & ~(lsize - 1); // K0_TO_K1(); - K0_TO_K1_CHECK(start,end); + //K0_TO_K1_CHECK(start,end); while (1) { protected_cache_op(Hit_Invalidate_I, addr); @@ -809,7 +833,7 @@ static inline void protected_blast_icache_range(unsigned long start, } INVALIDATE_BTB(); - K1_TO_K0(); + //K1_TO_K0(); } static inline void blast_dcache_range(unsigned long start, diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index a60edc87ae45cc..069b31f3252124 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -665,6 +665,49 @@ static inline void local_r4k_flush_icache_jz_ipi(void *args){ static inline void local_r4k_flush_dcache_jz_ipi(void *args){ r4k_blast_dcache_jz(); } + +/* + The other CPU maybe running in different process(different ASID) whit different address mapping, + so flush icache all with local_r4k_flush_icache_ipi() is safe. + But local_r4k_flush_icache_ipi() flush icache all by index, + both flushed L1 icache and L2 cache, it slowdown the machine performance. + so optimized the routine as following. + */ +static inline void protected_blast_other_cpu_icache_range_ipi(void *args) +{ + unsigned long lsize; + unsigned long addr; + unsigned long aend; + struct flush_icache_range_args * addrp; + unsigned long start; + unsigned long end; + + addrp = (struct flush_icache_range_args *)args; + start = addrp->start; + end = addrp->end; + + lsize = cpu_icache_line_size(); + addr = (start & ~(lsize - 1)) | INDEX_BASE; /* INDEX_BASE = 0x80000000 */ + aend = ((end - 1) & ~(lsize - 1)) | INDEX_BASE; + + //printk("protected id=%d, start=%#x, size=%#x\n", smp_processor_id(), (unsigned int)start, (unsigned int)(end-start)); + + while (1) { + protected_cache_op(Index_Invalidate_I, (addr + 0x0)); + protected_cache_op(Index_Invalidate_I, (addr + 0x1000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x2000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x3000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x4000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x5000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x6000)); + protected_cache_op(Index_Invalidate_I, (addr + 0x7000)); + if (addr == aend) + break; + addr += lsize; + } + INVALIDATE_BTB(); +} + static void r4k_flush_icache_range(unsigned long start, unsigned long end) { if (!cpu_has_ic_fills_f_dc) { @@ -685,8 +728,16 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) else { /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); - /* Flush complete icache on other CPUs */ - r4k_on_other_cpu(local_r4k_flush_icache_ipi,0); + if ( (end-start < PAGE_SIZE)) { + struct flush_icache_range_args range_addr; + range_addr.start = start; + range_addr.end = end; + r4k_on_other_cpu(protected_blast_other_cpu_icache_range_ipi, &range_addr); + } + else { + /* Flush complete icache on other CPUs */ + r4k_on_other_cpu(local_r4k_flush_icache_ipi,0); + } } } #endif From 5b7bd0e1cf83ca14d61fc146353311ff59ce30b2 Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:22 -0700 Subject: [PATCH 4/8] replace local_r4k_flush_*cache_ipi with local_r4k_flush_*cache_jz_ipi. and remove r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0). Change-Id: I31252f426dba7326cfe1b13dd1aa587e61e411a2 --- arch/mips/mm/c-jz.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index 069b31f3252124..1e86f5279c493d 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -713,18 +713,18 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) if (!cpu_has_ic_fills_f_dc) { if (end - start >= dcache_size) { /* Flush complete dcache on all CPUs */ - r4k_on_each_cpu(local_r4k_flush_dcache_ipi,0); + r4k_on_each_cpu(local_r4k_flush_dcache_jz_ipi,0); } else { /* Flush dcache by address on this CPU */ protected_blast_dcache_range(start, end); /* Flush complete dcache on other CPUs */ - r4k_on_other_cpu(local_r4k_flush_dcache_ipi,0); + //r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0); } } if (end - start >= icache_size) /* Flush complete icache on all CPUs */ - r4k_on_each_cpu(local_r4k_flush_icache_ipi,0); + r4k_on_each_cpu(local_r4k_flush_icache_jz_ipi,0); else { /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); @@ -736,7 +736,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) } else { /* Flush complete icache on other CPUs */ - r4k_on_other_cpu(local_r4k_flush_icache_ipi,0); + r4k_on_other_cpu(local_r4k_flush_icache_jz_ipi,0); } } } From a9607967c5d1561593ebe2c28a2cf8e041cdf003 Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:31 -0700 Subject: [PATCH 5/8] blast_icache_jz() add INVALIDATE_BTB(). blast_dcache_jz() remove SYNC_WB() for better performance. If user use __flush_cache_all() and then do a DMA transfer, must do SYNC_WB() after do __flush_cache_all(). Change-Id: I55cfbab24b706fab14a9af4f64d24430fbedeb5c --- arch/mips/include/asm/rjzcache.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/include/asm/rjzcache.h b/arch/mips/include/asm/rjzcache.h index 0b2710260c59db..1ab8b8afa2417b 100644 --- a/arch/mips/include/asm/rjzcache.h +++ b/arch/mips/include/asm/rjzcache.h @@ -591,6 +591,8 @@ static inline void blast_dcache_jz(void) } start += 32; }while(start < end); + + //SYNC_WB(); } static inline void blast_icache_jz(void) @@ -632,6 +634,8 @@ static inline void blast_icache_jz(void) } start += 32; }while(start < end); + + INVALIDATE_BTB(); } static inline void blast_dcache32(void) From d5e93d65563c0acc036556c4bc4fc1beaf248283 Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:43 -0700 Subject: [PATCH 6/8] r4k_flush_icache_range() replace r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0) with r4k_on_other_cpu(protected_blast_other_cpu_dcache_range_ipi, &range_addr) for a better performance. Change-Id: Idbfeecfc3437162f22b62f62d3a28ab19377e42a --- arch/mips/mm/c-jz.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index 1e86f5279c493d..f8460867cee400 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -666,6 +666,50 @@ static inline void local_r4k_flush_dcache_jz_ipi(void *args){ r4k_blast_dcache_jz(); } + +/* + The other CPU maybe running in different process(different ASID) whit different address mapping, + so flush dcache all with local_r4k_flush_dcache_ipi() is safe. + But local_r4k_flush_dcache_ipi() flush icache all by index, + both flushed L1 icache and L2 cache, it slowdown the machine performance. + so optimized the routine as following. + */ +static inline void protected_blast_other_cpu_dcache_range_ipi(void *args) +{ + unsigned long lsize; + unsigned long addr; + unsigned long aend; + struct flush_icache_range_args * addrp; + unsigned long start; + unsigned long end; + + addrp = (struct flush_icache_range_args *)args; + start = addrp->start; + end = addrp->end; + + lsize = cpu_dcache_line_size(); + addr = (start & ~(lsize - 1)) | INDEX_BASE; /* INDEX_BASE = 0x80000000 */ + aend = ((end - 1) & ~(lsize - 1)) | INDEX_BASE; + + //printk("protected_blast_other_cpu_dcache_range_ipi id=%d, start=%#x, size=%#x\n", smp_processor_id(), (unsigned int)start, (unsigned int)(end-start)); + + while (1) { + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x0)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x1000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x2000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x3000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x4000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x5000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x6000)); + protected_cache_op(Index_Writeback_Inv_D, (addr + 0x7000)); + if (addr == aend) + break; + addr += lsize; + } + + SYNC_WB(); +} + /* The other CPU maybe running in different process(different ASID) whit different address mapping, so flush icache all with local_r4k_flush_icache_ipi() is safe. @@ -690,7 +734,7 @@ static inline void protected_blast_other_cpu_icache_range_ipi(void *args) addr = (start & ~(lsize - 1)) | INDEX_BASE; /* INDEX_BASE = 0x80000000 */ aend = ((end - 1) & ~(lsize - 1)) | INDEX_BASE; - //printk("protected id=%d, start=%#x, size=%#x\n", smp_processor_id(), (unsigned int)start, (unsigned int)(end-start)); + //printk("protected_blast_other_cpu_icache_range_ipi id=%d, start=%#x, size=%#x\n", smp_processor_id(), (unsigned int)start, (unsigned int)(end-start)); while (1) { protected_cache_op(Index_Invalidate_I, (addr + 0x0)); @@ -717,8 +761,17 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) } else { /* Flush dcache by address on this CPU */ protected_blast_dcache_range(start, end); - /* Flush complete dcache on other CPUs */ - //r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0); + if ( (end-start < PAGE_SIZE)) { + /* Flush dcache_range by index on other CPUs */ + struct flush_icache_range_args range_addr; + range_addr.start = start; + range_addr.end = end; + r4k_on_other_cpu(protected_blast_other_cpu_dcache_range_ipi, &range_addr); + } + else { + /* Flush complete dcache on other CPUs */ + r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0); + } } } @@ -729,6 +782,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); if ( (end-start < PAGE_SIZE)) { + /* Flush icache_range by index on other CPUs */ struct flush_icache_range_args range_addr; range_addr.start = start; range_addr.end = end; From d5c1e28536f23916f0af272d736590a0e828b2f1 Mon Sep 17 00:00:00 2001 From: lgwang Date: Wed, 24 Sep 2014 10:25:51 -0700 Subject: [PATCH 7/8] Update c-jz.c r4k_flush_icache_range(), Flush complete dcache and icache on other CPUs. Test result by 2013-10-25: Flush complete dcache and icache on other CPUs with local_r4k_flush_dcache_jz_ipi() and local_r4k_flush_icache_jz_ipi(), running flushtest is stable 4days. Flush dcache_range and icache_range by index on other CPUs, with protected_blast_other_cpu_dcache_range_ipi() protected_blast_other_cpu_icache_range_ipi(), fails running flushtest after hours. It should be update in the future. Change-Id: I3446c92cbc67ab9aa0a1131384bf6f3ba52735b6 --- arch/mips/mm/c-jz.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index f8460867cee400..a01fb5ba5326fc 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -752,6 +752,15 @@ static inline void protected_blast_other_cpu_icache_range_ipi(void *args) INVALIDATE_BTB(); } +/* + * Test result by 2013-10-25: + * Flush complete dcache and icache on other CPUs with local_r4k_flush_dcache_jz_ipi() + * and local_r4k_flush_icache_jz_ipi(), running flushtest is stable 4days. + * + * Flush dcache_range and icache_range by index on other CPUs, + * with protected_blast_other_cpu_dcache_range_ipi() protected_blast_other_cpu_icache_range_ipi(), + * fails running flushtest after hours. It should be update in the future. + */ static void r4k_flush_icache_range(unsigned long start, unsigned long end) { if (!cpu_has_ic_fills_f_dc) { @@ -761,7 +770,8 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) } else { /* Flush dcache by address on this CPU */ protected_blast_dcache_range(start, end); - if ( (end-start < PAGE_SIZE)) { + //if ( (end-start < PAGE_SIZE)) { + if ( 0 ) { /* Flush dcache_range by index on other CPUs */ struct flush_icache_range_args range_addr; range_addr.start = start; @@ -781,7 +791,8 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) else { /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); - if ( (end-start < PAGE_SIZE)) { + //if ( (end-start < PAGE_SIZE)) { + if (0) { /* Flush icache_range by index on other CPUs */ struct flush_icache_range_args range_addr; range_addr.start = start; From 74c918d1d56e203607f6ef7eacf9938faabbd9d2 Mon Sep 17 00:00:00 2001 From: dsqiu Date: Wed, 24 Sep 2014 10:26:03 -0700 Subject: [PATCH 8/8] fix:flush icache range bug Change-Id: Ibca3dbfa88110576823819c7c9200cc86d014dd6 --- arch/mips/mm/c-jz.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/arch/mips/mm/c-jz.c b/arch/mips/mm/c-jz.c index a01fb5ba5326fc..1d773512ff4451 100755 --- a/arch/mips/mm/c-jz.c +++ b/arch/mips/mm/c-jz.c @@ -154,7 +154,8 @@ static void (* r4k_blast_dcache)(void); static void __cpuinit r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); - r4k_blast_dcache_jz = blast_dcache_jz; + //r4k_blast_dcache_jz = blast_dcache_jz; + r4k_blast_dcache_jz = blast_dcache32; if (dc_lsize == 0) r4k_blast_dcache = (void *)cache_noop; else if (dc_lsize == 16) @@ -283,7 +284,8 @@ static void (* r4k_blast_icache)(void); static void __cpuinit r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); - r4k_blast_icache_jz = blast_icache_jz; +// r4k_blast_icache_jz = blast_icache_jz; + r4k_blast_icache_jz = blast_icache32; if (ic_lsize == 0) r4k_blast_icache = (void *)cache_noop; else if (ic_lsize == 16) @@ -770,18 +772,6 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) } else { /* Flush dcache by address on this CPU */ protected_blast_dcache_range(start, end); - //if ( (end-start < PAGE_SIZE)) { - if ( 0 ) { - /* Flush dcache_range by index on other CPUs */ - struct flush_icache_range_args range_addr; - range_addr.start = start; - range_addr.end = end; - r4k_on_other_cpu(protected_blast_other_cpu_dcache_range_ipi, &range_addr); - } - else { - /* Flush complete dcache on other CPUs */ - r4k_on_other_cpu(local_r4k_flush_dcache_jz_ipi,0); - } } } @@ -789,20 +779,21 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) /* Flush complete icache on all CPUs */ r4k_on_each_cpu(local_r4k_flush_icache_jz_ipi,0); else { + preempt_disable(); /* Flush icache by address on this CPU */ protected_blast_icache_range(start, end); - //if ( (end-start < PAGE_SIZE)) { - if (0) { + if (end-start <= PAGE_SIZE) { /* Flush icache_range by index on other CPUs */ struct flush_icache_range_args range_addr; range_addr.start = start; range_addr.end = end; - r4k_on_other_cpu(protected_blast_other_cpu_icache_range_ipi, &range_addr); + smp_call_function(protected_blast_other_cpu_icache_range_ipi, &range_addr,1); } else { /* Flush complete icache on other CPUs */ - r4k_on_other_cpu(local_r4k_flush_icache_jz_ipi,0); + smp_call_function(local_r4k_flush_icache_jz_ipi,0,1); } + preempt_enable(); } } #endif