lkml.org 
[lkml]   [2014]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.10 14/44] powerpc/perf: Never program book3s PMCs with values >= 0x80000000
    Date
    3.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Anton Blanchard <anton@samba.org>

    commit f56029410a13cae3652d1f34788045c40a13ffc7 upstream.

    We are seeing a lot of PMU warnings on POWER8:

    Can't find PMC that caused IRQ

    Looking closer, the active PMC is 0 at this point and we took a PMU
    exception on the transition from negative to 0. Some versions of POWER8
    have an issue where they edge detect and not level detect PMC overflows.

    A number of places program the PMC with (0x80000000 - period_left),
    where period_left can be negative. We can either fix all of these or
    just ensure that period_left is always >= 1.

    This patch takes the second option.

    Signed-off-by: Anton Blanchard <anton@samba.org>
    Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/powerpc/perf/core-book3s.c | 17 ++++++++++++++++-
    1 file changed, 16 insertions(+), 1 deletion(-)

    --- a/arch/powerpc/perf/core-book3s.c
    +++ b/arch/powerpc/perf/core-book3s.c
    @@ -749,7 +749,22 @@ static void power_pmu_read(struct perf_e
    } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);

    local64_add(delta, &event->count);
    - local64_sub(delta, &event->hw.period_left);
    +
    + /*
    + * A number of places program the PMC with (0x80000000 - period_left).
    + * We never want period_left to be less than 1 because we will program
    + * the PMC with a value >= 0x800000000 and an edge detected PMC will
    + * roll around to 0 before taking an exception. We have seen this
    + * on POWER8.
    + *
    + * To fix this, clamp the minimum value of period_left to 1.
    + */
    + do {
    + prev = local64_read(&event->hw.period_left);
    + val = prev - delta;
    + if (val < 1)
    + val = 1;
    + } while (local64_cmpxchg(&event->hw.period_left, prev, val) != prev);
    }

    /*



    \
     
     \ /
      Last update: 2014-07-16 02:01    [W:2.410 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site