[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>
This commit is contained in:
parent
ab87e8dc88
commit
dc40127ca5
|
@ -26,7 +26,7 @@
|
||||||
BEGIN_FTR_SECTION; \
|
BEGIN_FTR_SECTION; \
|
||||||
mfspr r0,SPRN_PURR; /* get PURR and */ \
|
mfspr r0,SPRN_PURR; /* get PURR and */ \
|
||||||
std r0,STK_PARM(r6)(r1); /* save for later */ \
|
std r0,STK_PARM(r6)(r1); /* save for later */ \
|
||||||
END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
|
END_FTR_SECTION_IFSET(CPU_FTR_PURR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* postcall is performed immediately before function return which
|
* postcall is performed immediately before function return which
|
||||||
|
@ -43,7 +43,7 @@ BEGIN_FTR_SECTION; \
|
||||||
mfspr r8,SPRN_PURR; /* PURR after */ \
|
mfspr r8,SPRN_PURR; /* PURR after */ \
|
||||||
ld r6,STK_PARM(r6)(r1); /* PURR before */ \
|
ld r6,STK_PARM(r6)(r1); /* PURR before */ \
|
||||||
subf r6,r6,r8; /* delta */ \
|
subf r6,r6,r8; /* delta */ \
|
||||||
END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
|
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
|
||||||
ld r5,STK_PARM(r5)(r1); /* timebase before */ \
|
ld r5,STK_PARM(r5)(r1); /* timebase before */ \
|
||||||
subf r5,r5,r7; /* time delta */ \
|
subf r5,r5,r7; /* time delta */ \
|
||||||
\
|
\
|
||||||
|
@ -66,7 +66,7 @@ BEGIN_FTR_SECTION; \
|
||||||
ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
|
ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
|
||||||
add r7,r7,r6; \
|
add r7,r7,r6; \
|
||||||
std r7,HCALL_STAT_PURR(r4); \
|
std r7,HCALL_STAT_PURR(r4); \
|
||||||
END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
|
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
|
||||||
1:
|
1:
|
||||||
#else
|
#else
|
||||||
#define HCALL_INST_PRECALL
|
#define HCALL_INST_PRECALL
|
||||||
|
|
|
@ -34,7 +34,7 @@ DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
|
||||||
*/
|
*/
|
||||||
static void *hc_start(struct seq_file *m, loff_t *pos)
|
static void *hc_start(struct seq_file *m, loff_t *pos)
|
||||||
{
|
{
|
||||||
if ((int)*pos < HCALL_STAT_ARRAY_SIZE)
|
if ((int)*pos < (HCALL_STAT_ARRAY_SIZE-1))
|
||||||
return (void *)(unsigned long)(*pos + 1);
|
return (void *)(unsigned long)(*pos + 1);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -57,7 +57,7 @@ static int hc_show(struct seq_file *m, void *p)
|
||||||
struct hcall_stats *hs = (struct hcall_stats *)m->private;
|
struct hcall_stats *hs = (struct hcall_stats *)m->private;
|
||||||
|
|
||||||
if (hs[h_num].num_calls) {
|
if (hs[h_num].num_calls) {
|
||||||
if (!cpu_has_feature(CPU_FTR_PURR))
|
if (cpu_has_feature(CPU_FTR_PURR))
|
||||||
seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2,
|
seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2,
|
||||||
hs[h_num].num_calls,
|
hs[h_num].num_calls,
|
||||||
hs[h_num].tb_total,
|
hs[h_num].tb_total,
|
||||||
|
|
|
@ -252,8 +252,6 @@ struct hcall_stats {
|
||||||
unsigned long tb_total; /* total wall time (mftb) of calls. */
|
unsigned long tb_total; /* total wall time (mftb) of calls. */
|
||||||
unsigned long purr_total; /* total cpu time (PURR) of calls. */
|
unsigned long purr_total; /* total cpu time (PURR) of calls. */
|
||||||
};
|
};
|
||||||
void update_hcall_stats(unsigned long opcode, unsigned long tb_delta,
|
|
||||||
unsigned long purr_delta);
|
|
||||||
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
|
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
Loading…
Reference in New Issue