From patchwork Tue Nov 21 09:32:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 839942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yh0pw3GSHz9s5L for ; Tue, 21 Nov 2017 20:36:56 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3yh0pw2WMMzDrYn for ; Tue, 21 Nov 2017 20:36:56 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) 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 3yh0pL5ZlKzDrLV for ; Tue, 21 Nov 2017 20:36:26 +1100 (AEDT) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id vAL9Wa5E008691; Tue, 21 Nov 2017 03:32:42 -0600 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Tue, 21 Nov 2017 20:32:24 +1100 Message-Id: <20171121093231.28909-3-benh@kernel.crashing.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171121093231.28909-1-benh@kernel.crashing.org> References: <20171121093231.28909-1-benh@kernel.crashing.org> Subject: [Skiboot] [PATCH v2 03/10] xive: Improve cleaning up of EQs X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Factors out the function that sets an EQ back to a clean state and add a cleaning pass for queue left enabled when freeing a block of VPs. Signed-off-by: Benjamin Herrenschmidt --- hw/xive.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/hw/xive.c b/hw/xive.c index 2f1ad578..c9690aad 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -3945,6 +3945,13 @@ static int64_t opal_xive_get_queue_info(uint64_t vp, uint32_t prio, return OPAL_SUCCESS; } +static void xive_cleanup_eq(struct xive_eq *eq) +{ + eq->w0 = eq->w0 & EQ_W0_FIRMWARE; + eq->w1 = EQ_W1_ESe_Q | EQ_W1_ESn_Q; + eq->w2 = eq->w3 = eq->w4 = eq->w5 = eq->w6 = eq->w7 = 0; +} + static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio, uint64_t qpage, uint64_t qsize, @@ -4034,12 +4041,8 @@ static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio, * otherwise escalations won't work. */ eq.w0 |= EQ_W0_VALID | EQ_W0_BACKLOG; - } else { - /* Clear everything and set PQ bits to 01 */ - eq.w0 = old_eq->w0 & EQ_W0_FIRMWARE; - eq.w1 = EQ_W1_ESe_Q | EQ_W1_ESn_Q; - eq.w2 = eq.w3 = eq.w4 = eq.w5 = eq.w6 = eq.w7 = 0; - } + } else + xive_cleanup_eq(&eq); /* Update EQ, non-synchronous */ lock(&x->lock); @@ -4313,7 +4316,6 @@ static void xive_reset_one(struct xive *x) if (i == 0) continue; eq_firmware = false; - memset(&eq0, 0, sizeof(eq0)); for (j = 0; j < 8; j++) { uint32_t idx = (i << 3) | j; @@ -4325,7 +4327,8 @@ static void xive_reset_one(struct xive *x) * we will incorrectly free the EQs that are reserved * for the physical CPUs */ - eq0.w0 = eq->w0 & EQ_W0_FIRMWARE; + eq0 = *eq; + xive_cleanup_eq(&eq0); xive_eqc_cache_update(x, x->block_id, idx, 0, 4, &eq0, false, true); if (eq->w0 & EQ_W0_FIRMWARE) @@ -4477,7 +4480,7 @@ static int64_t opal_xive_reset(uint64_t version) static int64_t opal_xive_free_vp_block(uint64_t vp_base) { - uint32_t blk, idx, i, count; + uint32_t blk, idx, i, j, count; uint8_t order; bool group; @@ -4536,15 +4539,35 @@ static int64_t opal_xive_free_vp_block(uint64_t vp_base) continue; eq_blk = vp->w1 >> 28; eq_idx = vp->w1 & 0x0fffffff; + + lock(&x->lock); + + /* Ensure EQs are disabled and cleaned up. Ideally the caller + * should have done it but we double check it here + */ + for (j = 0; j < 7; j++) { + struct xive *eq_x = xive_from_vc_blk(eq_blk); + struct xive_eq eq, *orig_eq = xive_get_eq(eq_x, eq_idx + j); + + if (!(orig_eq->w0 & EQ_W0_VALID)) + continue; + + prlog(PR_WARNING, "XIVE: freeing VP %d with queue %d active\n", + vp_id, j); + eq = *orig_eq; + xive_cleanup_eq(&eq); + xive_eqc_cache_update(x, eq_blk, eq_idx + j, 0, 4, &eq, false, true); + } + + /* Mark it not populated so we don't try to free it again */ vp->w1 = 0; if (eq_blk != blk) { prerror("XIVE: Block mismatch trying to free EQs\n"); + unlock(&x->lock); return OPAL_INTERNAL_ERROR; } - /* XX Ensure the EQs are disabled */ - lock(&x->lock); xive_free_eq_set(x, eq_idx); unlock(&x->lock); }