From 106d4087a9e5e770d6049e54838dcb8265d75933 Mon Sep 17 00:00:00 2001 From: John Levon Date: Sat, 8 Mar 2003 18:31:41 -0800 Subject: [PATCH] [PATCH] fix oprofile on x86 > 1 counter Without this we have a choice between dropping lots of counter events for counters > 0, or getting dazed and confused. This brings it inline with the 2.4 module code. Tested on my 2-way. Also fix a typo from Steven Cole, and remove some unnecessary code --- arch/alpha/oprofile/op_model_ev4.c | 2 +- arch/i386/oprofile/op_model_athlon.c | 5 +++-- arch/i386/oprofile/op_model_p4.c | 5 +++-- arch/i386/oprofile/op_model_ppro.c | 11 +++++++++-- drivers/oprofile/cpu_buffer.c | 3 --- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/alpha/oprofile/op_model_ev4.c b/arch/alpha/oprofile/op_model_ev4.c index a817e4db9ee9a..5f06d319896a3 100644 --- a/arch/alpha/oprofile/op_model_ev4.c +++ b/arch/alpha/oprofile/op_model_ev4.c @@ -34,7 +34,7 @@ ev4_reg_setup(struct op_register_config *reg, for these "disabled" counter overflows are ignored by the interrupt handler. - This is most irritating, becuase the hardware *can* enable and + This is most irritating, because the hardware *can* enable and disable the interrupts for these counters independently, but the wrperfmon interface doesn't allow it. */ diff --git a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c index 3c3478b61e603..4f55d1da6f600 100644 --- a/arch/i386/oprofile/op_model_athlon.c +++ b/arch/i386/oprofile/op_model_athlon.c @@ -104,10 +104,11 @@ static int athlon_check_ctrs(unsigned int const cpu, if (CTR_OVERFLOWED(low)) { oprofile_add_sample(eip, is_kernel, i, cpu); CTR_WRITE(reset_value[i], msrs, i); - return 1; } } - return 0; + + /* See op_model_ppro.c */ + return 1; } diff --git a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c index a58cfcc837da7..ba00b67b7e2bd 100644 --- a/arch/i386/oprofile/op_model_p4.c +++ b/arch/i386/oprofile/op_model_p4.c @@ -608,13 +608,14 @@ static int p4_check_ctrs(unsigned int const cpu, CTR_WRITE(reset_value[i], real); /* P4 quirk: you have to re-unmask the apic vector */ apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); - return 1; } } /* P4 quirk: you have to re-unmask the apic vector */ apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); - return 0; + + /* See op_model_ppro.c */ + return 1; } diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c index 80c9ae83d044a..d9f38d6853955 100644 --- a/arch/i386/oprofile/op_model_ppro.c +++ b/arch/i386/oprofile/op_model_ppro.c @@ -98,10 +98,17 @@ static int ppro_check_ctrs(unsigned int const cpu, if (CTR_OVERFLOWED(low)) { oprofile_add_sample(eip, is_kernel, i, cpu); CTR_WRITE(reset_value[i], msrs, i); - return 1; } } - return 0; + + /* We can't work out if we really handled an interrupt. We + * might have caught a *second* counter just after overflowing + * the interrupt for this counter then arrives + * and we don't find a counter that's overflowed, so we + * would return 0 and get dazed + confused. Instead we always + * assume we found an overflow. This sucks. + */ + return 1; } diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index fd8c5745bed65..9065b9fd72192 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -85,9 +85,6 @@ static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b) unsigned long head = b->head_pos; unsigned long tail = b->tail_pos; - if (tail == head) - return b->buffer_size; - if (tail > head) return tail - head; -- 2.53.0