From patchwork Thu Apr 20 22:59:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 753034 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w8DqN1fh1z9s73 for ; Fri, 21 Apr 2017 09:00:32 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3w8DqN0QYTzDqLx for ; Fri, 21 Apr 2017 09:00:32 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3w8Dq410THzDq5b for ; Fri, 21 Apr 2017 09:00:15 +1000 (AEST) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v3KMxwaL021533; Thu, 20 Apr 2017 17:59:59 -0500 Message-ID: <1492729197.25766.156.camel@kernel.crashing.org> From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Fri, 21 Apr 2017 08:59:57 +1000 X-Mailer: Evolution 3.22.6 (3.22.6-1.fc25) Mime-Version: 1.0 Subject: [Skiboot] [PATCH] xive: Fix potential for lost IPIs when manipulating CPPR X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Neuling Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" We don't trigger the IPI in set_mfrr() if the CPPR of the destination is more favored than the MFRR. However, we fail to re-evaluate it when the CPPR later changes. This fixes it. The way this is implemented can lead to spurious IPIs but these are harmless. Signed-off-by: Benjamin Herrenschmidt --- hw/xive.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/hw/xive.c b/hw/xive.c index 1e2648c..eb75f5f 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -3066,6 +3066,24 @@ static inline uint8_t opal_xive_check_pending(struct xive_cpu_state *xs, return xs->pending & mask; } +static void opal_xive_update_cppr(struct xive_cpu_state *xs, u8 cppr) +{ + /* Peform the update */ + xs->cppr = cppr; + out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, cppr); + + /* Trigger the IPI if it's still more favored than the CPPR + * + * This can lead to a bunch of spurrious retriggers if the + * IPI is queued up behind other interrupts but that's not + * a big deal and keeps the code simpler + */ + if (xs->mfrr < cppr) { + xive_ipi_trigger(xs->xive, GIRQ_TO_IDX(xs->ipi_irq)); + xs->ipi_sent = true; + } +} + static int64_t opal_xive_eoi(uint32_t xirr) { struct cpu_thread *c = this_cpu(); @@ -3150,13 +3168,6 @@ static int64_t opal_xive_eoi(uint32_t xirr) /* Is it an IPI ? */ if (special_ipi) { xive_ipi_eoi(src_x, idx); - - /* Check mfrr and eventually re-trigger. We check - * against the new CPPR since we are about to update - * the HW. - */ - if (xs->mfrr < cppr) - xive_ipi_trigger(src_x, idx); } else { /* Otherwise go through the source mechanism */ xive_vdbg(src_x, "EOI of IDX %x in EXT range\n", idx); @@ -3167,8 +3178,7 @@ static int64_t opal_xive_eoi(uint32_t xirr) } /* Finally restore CPPR */ - xs->cppr = cppr; - out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, cppr); + opal_xive_update_cppr(xs, cppr); xive_cpu_vdbg(c, " pending=0x%x cppr=%d\n", xs->pending, cppr); @@ -3297,8 +3307,7 @@ static int64_t opal_xive_get_xirr(uint32_t *out_xirr, bool just_poll) } else { /* Nothing was active, this is a fluke, restore CPPR */ - xs->cppr = old_cppr; - out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, old_cppr); + opal_xive_update_cppr(xs, old_cppr); xive_cpu_vdbg(c, " nothing active, restored CPPR to %d\n", old_cppr); } @@ -3328,9 +3337,7 @@ static int64_t opal_xive_set_cppr(uint8_t cppr) xive_cpu_vdbg(c, "CPPR setting to %d\n", cppr); lock(&xs->lock); - c->xstate->cppr = cppr; - out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, cppr); - + opal_xive_update_cppr(xs, cppr); unlock(&xs->lock); return OPAL_SUCCESS;