diff options
author | Anton Blanchard <anton@samba.org> | 2007-01-08 10:43:02 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-01-09 01:03:03 -0500 |
commit | dc40127ca5c6e1da48d2b5f9d0c65b5795faac12 (patch) | |
tree | 7d57b9a53adc8f4416380b126108d1e458a8e20c | |
parent | ab87e8dc88a7cae341c403547cea6b022f5ac023 (diff) |
[POWERPC] Fix bugs in the hypervisor call stats code
There were a few issues with the HCALL_STATS code:
- PURR cpu feature checks were backwards
- We iterated one entry off the end of the hcall_stats array
- Remove dead update_hcall_stats() function prototype
I noticed one thing while debugging, and that is we call H_ENTER (to set
up the MMU hashtable in early init) before we have done the cpu fixups.
This means we will execute the PURR SPR reads even on a CPU that isnt
capable of it. I wonder if we can move the CPU feature fixups earlier.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/pseries/hvCall.S | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hvCall_inst.c | 4 | ||||
-rw-r--r-- | include/asm-powerpc/hvcall.h | 2 |
3 files changed, 5 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 527da445aaa..5c7e3878989 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -26,7 +26,7 @@ | |||
26 | BEGIN_FTR_SECTION; \ | 26 | BEGIN_FTR_SECTION; \ |
27 | mfspr r0,SPRN_PURR; /* get PURR and */ \ | 27 | mfspr r0,SPRN_PURR; /* get PURR and */ \ |
28 | std r0,STK_PARM(r6)(r1); /* save for later */ \ | 28 | std r0,STK_PARM(r6)(r1); /* save for later */ \ |
29 | END_FTR_SECTION_IFCLR(CPU_FTR_PURR); | 29 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * postcall is performed immediately before function return which | 32 | * postcall is performed immediately before function return which |
@@ -43,7 +43,7 @@ BEGIN_FTR_SECTION; \ | |||
43 | mfspr r8,SPRN_PURR; /* PURR after */ \ | 43 | mfspr r8,SPRN_PURR; /* PURR after */ \ |
44 | ld r6,STK_PARM(r6)(r1); /* PURR before */ \ | 44 | ld r6,STK_PARM(r6)(r1); /* PURR before */ \ |
45 | subf r6,r6,r8; /* delta */ \ | 45 | subf r6,r6,r8; /* delta */ \ |
46 | END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ | 46 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ |
47 | ld r5,STK_PARM(r5)(r1); /* timebase before */ \ | 47 | ld r5,STK_PARM(r5)(r1); /* timebase before */ \ |
48 | subf r5,r5,r7; /* time delta */ \ | 48 | subf r5,r5,r7; /* time delta */ \ |
49 | \ | 49 | \ |
@@ -66,7 +66,7 @@ BEGIN_FTR_SECTION; \ | |||
66 | ld r7,HCALL_STAT_PURR(r4); /* PURR */ \ | 66 | ld r7,HCALL_STAT_PURR(r4); /* PURR */ \ |
67 | add r7,r7,r6; \ | 67 | add r7,r7,r6; \ |
68 | std r7,HCALL_STAT_PURR(r4); \ | 68 | std r7,HCALL_STAT_PURR(r4); \ |
69 | END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ | 69 | END_FTR_SECTION_IFSET(CPU_FTR_PURR); \ |
70 | 1: | 70 | 1: |
71 | #else | 71 | #else |
72 | #define HCALL_INST_PRECALL | 72 | #define HCALL_INST_PRECALL |
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 80181c4c49e..3ddc04925d5 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
@@ -34,7 +34,7 @@ DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats); | |||
34 | */ | 34 | */ |
35 | static void *hc_start(struct seq_file *m, loff_t *pos) | 35 | static void *hc_start(struct seq_file *m, loff_t *pos) |
36 | { | 36 | { |
37 | if ((int)*pos < HCALL_STAT_ARRAY_SIZE) | 37 | if ((int)*pos < (HCALL_STAT_ARRAY_SIZE-1)) |
38 | return (void *)(unsigned long)(*pos + 1); | 38 | return (void *)(unsigned long)(*pos + 1); |
39 | 39 | ||
40 | return NULL; | 40 | return NULL; |
@@ -57,7 +57,7 @@ static int hc_show(struct seq_file *m, void *p) | |||
57 | struct hcall_stats *hs = (struct hcall_stats *)m->private; | 57 | struct hcall_stats *hs = (struct hcall_stats *)m->private; |
58 | 58 | ||
59 | if (hs[h_num].num_calls) { | 59 | if (hs[h_num].num_calls) { |
60 | if (!cpu_has_feature(CPU_FTR_PURR)) | 60 | if (cpu_has_feature(CPU_FTR_PURR)) |
61 | seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2, | 61 | seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2, |
62 | hs[h_num].num_calls, | 62 | hs[h_num].num_calls, |
63 | hs[h_num].tb_total, | 63 | hs[h_num].tb_total, |
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h index 257d1cecb8c..7a500732b67 100644 --- a/include/asm-powerpc/hvcall.h +++ b/include/asm-powerpc/hvcall.h | |||
@@ -252,8 +252,6 @@ struct hcall_stats { | |||
252 | unsigned long tb_total; /* total wall time (mftb) of calls. */ | 252 | unsigned long tb_total; /* total wall time (mftb) of calls. */ |
253 | unsigned long purr_total; /* total cpu time (PURR) of calls. */ | 253 | unsigned long purr_total; /* total cpu time (PURR) of calls. */ |
254 | }; | 254 | }; |
255 | void update_hcall_stats(unsigned long opcode, unsigned long tb_delta, | ||
256 | unsigned long purr_delta); | ||
257 | #define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1) | 255 | #define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1) |
258 | 256 | ||
259 | #endif /* __ASSEMBLY__ */ | 257 | #endif /* __ASSEMBLY__ */ |