Skip to content

Commit 0a57549

Browse files
committed
parisc: Avoid calling SMP cache flush functions on cache-less machines
At least the qemu virtual machine does not provide D- and I-caches, so skip triggering SMP irqs to flush caches on such machines. Further optimize the caching code by using static branches and making some functions static. Signed-off-by: Helge Deller <deller@gmx.de>
1 parent a58e9d0 commit 0a57549

3 files changed

Lines changed: 40 additions & 34 deletions

File tree

arch/parisc/include/asm/cacheflush.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,11 @@
99
/* The usual comment is "Caches aren't brain-dead on the <architecture>".
1010
* Unfortunately, that doesn't apply to PA-RISC. */
1111

12-
/* Internal implementation */
13-
void flush_data_cache_local(void *); /* flushes local data-cache only */
14-
void flush_instruction_cache_local(void *); /* flushes local code-cache only */
15-
#ifdef CONFIG_SMP
16-
void flush_data_cache(void); /* flushes data-cache only (all processors) */
17-
void flush_instruction_cache(void); /* flushes i-cache only (all processors) */
18-
#else
19-
#define flush_data_cache() flush_data_cache_local(NULL)
20-
#define flush_instruction_cache() flush_instruction_cache_local(NULL)
21-
#endif
12+
#include <linux/jump_label.h>
13+
14+
DECLARE_STATIC_KEY_TRUE(parisc_has_cache);
15+
DECLARE_STATIC_KEY_TRUE(parisc_has_dcache);
16+
DECLARE_STATIC_KEY_TRUE(parisc_has_icache);
2217

2318
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
2419

arch/parisc/kernel/alternative.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <asm/processor.h>
99
#include <asm/sections.h>
1010
#include <asm/alternative.h>
11+
#include <asm/cacheflush.h>
1112

1213
#include <linux/module.h>
1314

@@ -107,5 +108,14 @@ void __init apply_alternatives_all(void)
107108
apply_alternatives((struct alt_instr *) &__alt_instructions,
108109
(struct alt_instr *) &__alt_instructions_end, NULL);
109110

111+
if (cache_info.dc_size == 0 && cache_info.ic_size == 0) {
112+
pr_info("alternatives: optimizing cache-flushes.\n");
113+
static_branch_disable(&parisc_has_cache);
114+
}
115+
if (cache_info.dc_size == 0)
116+
static_branch_disable(&parisc_has_dcache);
117+
if (cache_info.ic_size == 0)
118+
static_branch_disable(&parisc_has_icache);
119+
110120
set_kernel_text_rw(0);
111121
}

arch/parisc/kernel/cache.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ EXPORT_SYMBOL(flush_dcache_page_asm);
3838
void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
3939
void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
4040

41+
/* Internal implementation in arch/parisc/kernel/pacache.S */
42+
void flush_data_cache_local(void *); /* flushes local data-cache only */
43+
void flush_instruction_cache_local(void); /* flushes local code-cache only */
4144

4245
/* On some machines (i.e., ones with the Merced bus), there can be
4346
* only a single PxTLB broadcast at a time; this must be guaranteed
@@ -58,26 +61,35 @@ struct pdc_cache_info cache_info __ro_after_init;
5861
static struct pdc_btlb_info btlb_info __ro_after_init;
5962
#endif
6063

61-
#ifdef CONFIG_SMP
62-
void
63-
flush_data_cache(void)
64+
DEFINE_STATIC_KEY_TRUE(parisc_has_cache);
65+
DEFINE_STATIC_KEY_TRUE(parisc_has_dcache);
66+
DEFINE_STATIC_KEY_TRUE(parisc_has_icache);
67+
68+
static void cache_flush_local_cpu(void *dummy)
6469
{
65-
on_each_cpu(flush_data_cache_local, NULL, 1);
70+
if (static_branch_likely(&parisc_has_icache))
71+
flush_instruction_cache_local();
72+
if (static_branch_likely(&parisc_has_dcache))
73+
flush_data_cache_local(NULL);
6674
}
67-
void
68-
flush_instruction_cache(void)
75+
76+
void flush_cache_all_local(void)
6977
{
70-
on_each_cpu(flush_instruction_cache_local, NULL, 1);
78+
cache_flush_local_cpu(NULL);
7179
}
72-
#endif
7380

74-
void
75-
flush_cache_all_local(void)
81+
void flush_cache_all(void)
82+
{
83+
if (static_branch_likely(&parisc_has_cache))
84+
on_each_cpu(cache_flush_local_cpu, NULL, 1);
85+
}
86+
87+
static inline void flush_data_cache(void)
7688
{
77-
flush_instruction_cache_local(NULL);
78-
flush_data_cache_local(NULL);
89+
if (static_branch_likely(&parisc_has_dcache))
90+
on_each_cpu(flush_data_cache_local, NULL, 1);
7991
}
80-
EXPORT_SYMBOL(flush_cache_all_local);
92+
8193

8294
/* Virtual address of pfn. */
8395
#define pfn_va(pfn) __va(PFN_PHYS(pfn))
@@ -375,7 +387,6 @@ EXPORT_SYMBOL(flush_dcache_page);
375387

376388
/* Defined in arch/parisc/kernel/pacache.S */
377389
EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
378-
EXPORT_SYMBOL(flush_data_cache_local);
379390
EXPORT_SYMBOL(flush_kernel_icache_range_asm);
380391

381392
#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
@@ -517,16 +528,6 @@ int __flush_tlb_range(unsigned long sid, unsigned long start,
517528
return 0;
518529
}
519530

520-
static void cacheflush_h_tmp_function(void *dummy)
521-
{
522-
flush_cache_all_local();
523-
}
524-
525-
void flush_cache_all(void)
526-
{
527-
on_each_cpu(cacheflush_h_tmp_function, NULL, 1);
528-
}
529-
530531
static inline unsigned long mm_total_size(struct mm_struct *mm)
531532
{
532533
struct vm_area_struct *vma;

0 commit comments

Comments
 (0)