static s64 get_insn_ctr(void)
{ int ctr; unsignedlong counta;
do {
ctr = atomic_read(&instruction_counter);
counta = mfspr(SPRN_COUNTA);
} while (ctr != atomic_read(&instruction_counter));
return ((s64)ctr << 16) | (counta >> 16);
}
staticint event_type(struct perf_event *event)
{ switch (event->attr.type) { case PERF_TYPE_HARDWARE: if (event->attr.config == PERF_COUNT_HW_CPU_CYCLES) return PERF_8xx_ID_CPU_CYCLES; if (event->attr.config == PERF_COUNT_HW_INSTRUCTIONS) return PERF_8xx_ID_HW_INSTRUCTIONS; break; case PERF_TYPE_HW_CACHE: if (event->attr.config == ITLB_LOAD_MISS) return PERF_8xx_ID_ITLB_LOAD_MISS; if (event->attr.config == DTLB_LOAD_MISS) return PERF_8xx_ID_DTLB_LOAD_MISS; break; case PERF_TYPE_RAW: break; default: return -ENOENT;
} return -EOPNOTSUPP;
}
staticint mpc8xx_pmu_event_init(struct perf_event *event)
{ int type = event_type(event);
if (type < 0) return type; return 0;
}
staticint mpc8xx_pmu_add(struct perf_event *event, int flags)
{ int type = event_type(event);
s64 val = 0;
if (type < 0) return type;
switch (type) { case PERF_8xx_ID_CPU_CYCLES:
val = get_tb(); break; case PERF_8xx_ID_HW_INSTRUCTIONS: if (atomic_inc_return(&insn_ctr_ref) == 1)
mtspr(SPRN_ICTRL, 0xc0080007);
val = get_insn_ctr(); break; case PERF_8xx_ID_ITLB_LOAD_MISS: if (atomic_inc_return(&itlb_miss_ref) == 1) { unsignedlong target = patch_site_addr(&patch__itlbmiss_perf);
patch_branch_site(&patch__itlbmiss_exit_1, target, 0);
}
val = itlb_miss_counter; break; case PERF_8xx_ID_DTLB_LOAD_MISS: if (atomic_inc_return(&dtlb_miss_ref) == 1) { unsignedlong target = patch_site_addr(&patch__dtlbmiss_perf);
/* If it was the last user, stop counting to avoid useless overhead */ switch (event_type(event)) { case PERF_8xx_ID_CPU_CYCLES: break; case PERF_8xx_ID_HW_INSTRUCTIONS: if (atomic_dec_return(&insn_ctr_ref) == 0)
mtspr(SPRN_ICTRL, 7); break; case PERF_8xx_ID_ITLB_LOAD_MISS: if (atomic_dec_return(&itlb_miss_ref) == 0)
patch_instruction_site(&patch__itlbmiss_exit_1, insn); break; case PERF_8xx_ID_DTLB_LOAD_MISS: if (atomic_dec_return(&dtlb_miss_ref) == 0)
patch_instruction_site(&patch__dtlbmiss_exit_1, insn); break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.