From patchwork Thu Sep 17 16:35:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366256 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.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjJp0x1hz9sSW for ; Fri, 18 Sep 2020 02:36:10 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjJn5j8BzDqcX for ; Fri, 18 Sep 2020 02:36:09 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=178.32.125.2; helo=smtpout1.mo529.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo529.mail-out.ovh.net (smtpout1.mo529.mail-out.ovh.net [178.32.125.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJW194PzDqcF for ; Fri, 18 Sep 2020 02:35:52 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.108.1.6]) by mo529.mail-out.ovh.net (Postfix) with ESMTPS id DD3075C30D02; Thu, 17 Sep 2020 18:35:46 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:46 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R0015614afd1-282f-461e-8176-f599e4e1eda4, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:38 +0200 Message-ID: <20200917163544.142593-2-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: 1cf18d22-6375-46e8-abe1-adbbee073c1e X-Ovh-Tracer-Id: 10403878091052846045 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 1/6] core: Add debugfs framework X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This is a very simplistic framework adding a read/write interface to opal drivers. Drivers should define a set of 'opal_debug' handlers, each with custom read/write operations. The device tree is then populated with nodes such as : debug@0 { ibm,chip-id = <0x00>; label = "xive-ivt"; compatible = "ibm,opal-debug"; reg = <0x00>; phandle = <0x805e>; }; which can be freely extended by the driver if needed. The Linux driver can choose to expose the contents of each 'opal_debug' handler through debugfs using the OPAL_DEBUG_READ call. It is relatively easy to implement a simple command interface with the OPAL_DEBUG_WRITE call, to set some values or reset some counters. Signed-off-by: Cédric Le Goater --- include/opal-api.h | 4 ++- include/opal-debug.h | 26 ++++++++++++++ core/opal-debug.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ core/Makefile.inc | 1 + 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 include/opal-debug.h create mode 100644 core/opal-debug.c diff --git a/include/opal-api.h b/include/opal-api.h index e90cab1e9f65..03c414946651 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -227,7 +227,9 @@ #define OPAL_SECVAR_ENQUEUE_UPDATE 178 #define OPAL_PHB_SET_OPTION 179 #define OPAL_PHB_GET_OPTION 180 -#define OPAL_LAST 180 +#define OPAL_DEBUG_READ 181 +#define OPAL_DEBUG_WRITE 182 +#define OPAL_LAST 182 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ diff --git a/include/opal-debug.h b/include/opal-debug.h new file mode 100644 index 000000000000..49d58256af7c --- /dev/null +++ b/include/opal-debug.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2020 IBM Corp. */ + +#ifndef __OPAL_DEBUG_H +#define __OPAL_DEBUG_H + +struct opal_debug; + +struct opal_debug_ops { + const char *compat; + int (*read)(struct opal_debug *d, void *buf, uint64_t size); + int (*write)(struct opal_debug *d, void *buf, uint64_t size); +}; + +struct opal_debug { + const char *name; + void *private; + struct dt_node *node; + const struct opal_debug_ops *ops; +}; + + +extern struct opal_debug *opal_debug_create(const char *name, + const struct opal_debug_ops *ops, void* private); + +#endif diff --git a/core/opal-debug.c b/core/opal-debug.c new file mode 100644 index 000000000000..770489e3031c --- /dev/null +++ b/core/opal-debug.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +/* Copyright 2020 IBM Corp. */ + +#define pr_fmt(fmt) "DEBUG: " fmt + +#include +#include +#include + +#define OPAL_DEBUG_MAX 100 + +static struct dt_node *opal_debug_node; +static int opal_debug_index; +static struct opal_debug opal_debug_handlers[OPAL_DEBUG_MAX]; + +extern struct opal_debug *opal_debug_create(const char *name, + const struct opal_debug_ops *ops, void* private) +{ + const char *compat = ops->compat ? ops->compat : "ibm,opal-debug"; + struct opal_debug *d; + + if (opal_debug_index == OPAL_DEBUG_MAX) { + prlog(PR_ERR, "Maximum number of handlers reached: %d\n", + OPAL_DEBUG_MAX); + return NULL; + } + + d = &opal_debug_handlers[opal_debug_index]; + d->name = name; + d->private = private; + d->ops = ops; + + if (!opal_debug_node) { + opal_debug_node = dt_new_check(opal_node, "debug"); + dt_add_property_cells(opal_debug_node, "#address-cells", 0); + dt_add_property_cells(opal_debug_node, "#size-cells", 0); + } + + d->node = dt_new_addr(opal_debug_node, "debug", opal_debug_index); + dt_add_property_cells(d->node, "reg", opal_debug_index); + dt_add_property_string(d->node, "compatible", compat); + dt_add_property_string(d->node, "label", d->name); + + opal_debug_index++; + + return d; +} + +static int64_t opal_debug_read(uint64_t id, uint64_t buf, uint64_t size) +{ + struct opal_debug *d; + + if (id >= opal_debug_index) + return OPAL_PARAMETER; + + d = &opal_debug_handlers[id]; + + if (!opal_addr_valid((void *)buf) || !size) + return OPAL_PARAMETER; + + if (!d->ops->read) + return OPAL_INTERNAL_ERROR; + + return d->ops->read(d, (void *)buf, size); +} +opal_call(OPAL_DEBUG_READ, opal_debug_read, 3); + +static int64_t opal_debug_write(uint64_t id, uint64_t buf, uint64_t size) +{ + struct opal_debug *d; + + if (id >= opal_debug_index) + return OPAL_PARAMETER; + + d = &opal_debug_handlers[id]; + + if (!opal_addr_valid((void *)buf) || !size) + return OPAL_PARAMETER; + + if (!d->ops->write) + return OPAL_INTERNAL_ERROR; + + return d->ops->write(d, (void *)buf, size); +} +opal_call(OPAL_DEBUG_WRITE, opal_debug_write, 3); diff --git a/core/Makefile.inc b/core/Makefile.inc index 829800e5b27f..ed7003ed7a7a 100644 --- a/core/Makefile.inc +++ b/core/Makefile.inc @@ -13,6 +13,7 @@ CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o powercap.o psr.o CORE_OBJS += pci-dt-slot.o direct-controls.o cpufeatures.o CORE_OBJS += flash-firmware-versions.o opal-dump.o +CORE_OBJS += opal-debug.o ifeq ($(SKIBOOT_GCOV),1) CORE_OBJS += gcov-profiling.o From patchwork Thu Sep 17 16:35:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366266 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjNG6Zm2z9sSW for ; Fri, 18 Sep 2020 02:39:10 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjNG48yjzDqcY for ; Fri, 18 Sep 2020 02:39:10 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=79.137.123.220; helo=smtpout1.mo804.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo804.mail-out.ovh.net (smtpout1.mo804.mail-out.ovh.net [79.137.123.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJY5Z2BzDqcF for ; Fri, 18 Sep 2020 02:35:53 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.108.20.54]) by mo804.mail-out.ovh.net (Postfix) with ESMTPS id 7CDBF62BFFD1; Thu, 17 Sep 2020 18:35:47 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:46 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R00132581310-c179-4fa1-91e0-b39a30063ec0, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:39 +0200 Message-ID: <20200917163544.142593-3-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: b82049d4-0448-4f5a-a315-84c253f9356b X-Ovh-Tracer-Id: 10404159567042153437 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 2/6] xive/p9: Add debugfs entries for internal tables X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The XIVE interrupt controller relies on a set of tables to configure the routing of interrupts from source to target. The IVT associates a source number to an event queue, the EQDT associates an event queue to a notification virtual target (NVT) and the NVTT holds the NVT configuration and serves as memory back store for the interrupt thread context registers. Each table contains valuable information which is interesting to expose. Signed-off-by: Cédric Le Goater --- hw/xive.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/hw/xive.c b/hw/xive.c index fe352fe26885..ccebb1e1d17d 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Always notify from EQ to VP (no EOI on EQs). Will speed up * EOIs at the expense of potentially higher powerbus traffic. @@ -5141,6 +5142,8 @@ static void xive_init_globals(void) xive_block_to_chip[i] = XIVE_INVALID_CHIP; } +static void xive_init_debug(struct xive *x); + void init_xive(void) { struct dt_node *np; @@ -5220,5 +5223,175 @@ void init_xive(void) opal_register(OPAL_XIVE_GET_QUEUE_STATE, opal_xive_get_queue_state, 4); opal_register(OPAL_XIVE_SET_QUEUE_STATE, opal_xive_set_queue_state, 4); opal_register(OPAL_XIVE_GET_VP_STATE, opal_xive_get_vp_state, 2); + + for_each_chip(chip) { + if (chip->xive) + xive_init_debug(chip->xive); + } +} + +static int xive_ivt_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + struct xive_ive *ivt = x->ivt_base; + int i; + int n = 0; + + n += snprintf(buf + n, size - n, "IVT[%d]\n", x->block_id); + for (i = 0; i < XIVE_INT_COUNT; i++) { + struct xive_ive *ive = &ivt[i]; + uint32_t eq_blk, eq_idx, eq_data; + /* TODO: get ESB mmio */ + + if (xive_get_field64(IVE_MASKED, ive->w) || + !xive_get_field64(IVE_VALID, ive->w)) + continue; + n += snprintf(buf + n, size - n, "%08x ", + BLKIDX_TO_GIRQ(x->block_id, i)); + lock(&x->lock); + eq_blk = xive_get_field64(IVE_EQ_BLOCK, ive->w); + eq_idx = xive_get_field64(IVE_EQ_INDEX, ive->w); + eq_data = xive_get_field64(IVE_EQ_DATA, ive->w); + unlock(&x->lock); + + n += snprintf(buf + n, size - n, "eq=%x/%x data=%x\n", + eq_blk, eq_idx, eq_data); + } + + return n; +} + +static int xive_eqt_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + int i, j; + int n = 0; + + n += snprintf(buf + n, size - n, "EQT[%d]\n", x->block_id); + bitmap_for_each_one(*x->eq_map, XIVE_EQ_COUNT >> 3, i) { + for (j = 0; j < NUM_INT_PRIORITIES; j++) { + struct xive_eq *eq; + uint32_t idx = (i << 3) | j; + + eq = xive_get_eq(x, idx); + if (!eq || !xive_get_field32(EQ_W0_VALID, eq->w0)) + continue; + + lock(&x->lock); + xive_eqc_scrub(x, x->block_id, idx); + unlock(&x->lock); + + n += snprintf(buf + n, size - n, + "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + idx, + eq->w0, eq->w1, eq->w2, eq->w3, + eq->w4, eq->w5, eq->w6, eq->w7); + } + } + return n; +} + +static int xive_esc_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + int i, j; + int n = 0; + + n += snprintf(buf + n, size - n, "ESC IVT[%d]\n", x->block_id); + bitmap_for_each_one(*x->eq_map, XIVE_EQ_COUNT >> 3, i) { + for (j = 0; j < NUM_INT_PRIORITIES; j++) { + uint32_t idx = (i << 3) | j; + struct xive_eq *eq; + struct xive_ive *ive; + uint32_t eq_blk, eq_idx, eq_data; + + eq = xive_get_eq(x, idx); + if (!eq || !xive_get_field32(EQ_W0_VALID, eq->w0)) + continue; + if (!xive_get_field32(EQ_W0_ESCALATE_CTL, eq->w0)) + continue; + + ive = (struct xive_ive*)(char *)&eq->w4; + + n += snprintf(buf + n, size - n, "%08x ", + MAKE_ESCALATION_GIRQ(x->block_id, i)); + lock(&x->lock); + xive_eqc_scrub(x, x->block_id, idx); + eq_blk = xive_get_field64(IVE_EQ_BLOCK, ive->w); + eq_idx = xive_get_field64(IVE_EQ_INDEX, ive->w); + eq_data = xive_get_field64(IVE_EQ_DATA, ive->w); + unlock(&x->lock); + + n += snprintf(buf + n, size - n, "eq=%x/%x data=%x\n", + eq_blk, eq_idx, eq_data); + } + } + return n; +} + +static int xive_vpt_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + int i; + int n = 0; + + n += snprintf(buf + n, size - n, "VPT[%d]\n", x->block_id); + for (i = 0; i < XIVE_VP_COUNT; i++) { + struct xive_vp *vp; + + /* Ignore the physical CPU VPs */ + if (i >= XIVE_HW_VP_BASE && + i < (XIVE_HW_VP_BASE + XIVE_HW_VP_COUNT)) + continue; + + vp = xive_get_vp(x, i); + if (!vp || !xive_get_field32(VP_W0_VALID, vp->w0)) + continue; + lock(&x->lock); + xive_vpc_scrub(x, x->block_id, i); + unlock(&x->lock); + n += snprintf(buf + n, size - n, + "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + i, + vp->w0, vp->w1, vp->w2, vp->w3, + vp->w4, vp->w5, vp->w6, vp->w7); + } + return n; +} + +static const struct opal_debug_ops xive_ivt_ops = { + .read = xive_ivt_read, +}; +static const struct opal_debug_ops xive_eqt_ops = { + .read = xive_eqt_read, +}; +static const struct opal_debug_ops xive_esc_ops = { + .read = xive_esc_read, +}; +static const struct opal_debug_ops xive_vpt_ops = { + .read = xive_vpt_read, +}; + +static const struct { + const char *name; + const struct opal_debug_ops *ops; +} xive_debug_handlers[] = { + { "xive-ivt", &xive_ivt_ops, }, + { "xive-eqt", &xive_eqt_ops, }, + { "xive-esc", &xive_esc_ops, }, + { "xive-vpt", &xive_vpt_ops, }, +}; + +static void xive_init_debug(struct xive *x) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(xive_debug_handlers); i++) { + struct opal_debug *d; + d = opal_debug_create(xive_debug_handlers[i].name, + xive_debug_handlers[i].ops, x); + + dt_add_property_cells(d->node, "ibm,chip-id", x->chip_id); + } } From patchwork Thu Sep 17 16:35:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366260 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjKf4jlfz9sRR for ; Fri, 18 Sep 2020 02:36:54 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjKf0Bj7zDqfD for ; Fri, 18 Sep 2020 02:36:54 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=79.137.123.220; helo=smtpout1.mo804.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo804.mail-out.ovh.net (smtpout1.mo804.mail-out.ovh.net [79.137.123.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJW25ZQzDqcQ for ; Fri, 18 Sep 2020 02:35:55 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.108.20.54]) by mo804.mail-out.ovh.net (Postfix) with ESMTPS id 9D91C62BFFD3; Thu, 17 Sep 2020 18:35:47 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:47 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R00138eda0f0-72cd-47b5-b729-e07e03a5bf78, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:40 +0200 Message-ID: <20200917163544.142593-4-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: 6bc31814-3d9d-4672-814f-251ae5c2a806 X-Ovh-Tracer-Id: 10404159567418067933 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 3/6] xive/p9: Add debugfs entries for performance X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" XIVE interrupt controller has some registers collecting internal performance mesures. Expose them through a debug handler. Unfortunately, these can not be reset without a reboot. Signed-off-by: Cédric Le Goater --- include/xive-p9-regs.h | 14 ++++++++++++++ hw/xive.c | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/xive-p9-regs.h b/include/xive-p9-regs.h index fff341cca150..c1dcc7d205c2 100644 --- a/include/xive-p9-regs.h +++ b/include/xive-p9-regs.h @@ -163,6 +163,11 @@ #define X_PC_VPC_CWATCH_DAT7 0x16f #define PC_VPC_CWATCH_DAT7 0x778 +#define X_PC_VPC_ADDITIONAL_PERF_1 0x174 +#define PC_VPC_ADDITIONAL_PERF_1 0x7A0 +#define X_PC_VPC_ADDITIONAL_PERF_2 0x175 +#define PC_VPC_ADDITIONAL_PERF_2 0x7A8 + /* VC0 register offsets */ #define X_VC_GLOBAL_CONFIG 0x200 #define VC_GLOBAL_CONFIG 0x800 @@ -262,6 +267,15 @@ #define VC_SBC_CONF_CIST_BOTH PPC_BIT(45) #define VC_SBC_CONF_NO_UPD_PRF PPC_BIT(59) +#define X_VC_EQC_ADDITIONAL_PERF_1 0x253 +#define VC_EQC_ADDITIONAL_PERF_1 0x970 +#define X_VC_EQC_ADDITIONAL_PERF_2 0x254 +#define VC_EQC_ADDITIONAL_PERF_2 0x978 +#define X_VC_IVC_ADDITIONAL_PERF 0x25B +#define VC_IVC_ADDITIONAL_PERF 0x9F0 +#define X_VC_SBC_ADDITIONAL_PERF 0x263 +#define VC_SBC_ADDITIONAL_PERF 0xA70 + /* VC1 register offsets */ /* VSD Table address register definitions (shared) */ diff --git a/hw/xive.c b/hw/xive.c index ccebb1e1d17d..b13beb575ba1 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -5359,6 +5359,27 @@ static int xive_vpt_read(struct opal_debug *d, void *buf, uint64_t size) return n; } +static int xive_perf_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + int n = 0; + + n += snprintf(buf + n, size - n, "Performance counters [%d]\n", x->block_id); + +#define perf_read(reg) \ + n += snprintf(buf + n, size - n, "%30s = %016llx\n", #reg, \ + in_be64(x->ic_base + reg)) + + perf_read(PC_VPC_ADDITIONAL_PERF_1); + perf_read(PC_VPC_ADDITIONAL_PERF_2); + perf_read(VC_EQC_ADDITIONAL_PERF_1); + perf_read(VC_EQC_ADDITIONAL_PERF_2); + perf_read(VC_IVC_ADDITIONAL_PERF); + perf_read(VC_SBC_ADDITIONAL_PERF); + + return n; +} + static const struct opal_debug_ops xive_ivt_ops = { .read = xive_ivt_read, }; @@ -5371,6 +5392,9 @@ static const struct opal_debug_ops xive_esc_ops = { static const struct opal_debug_ops xive_vpt_ops = { .read = xive_vpt_read, }; +static const struct opal_debug_ops xive_perf_ops = { + .read = xive_perf_read, +}; static const struct { const char *name; @@ -5380,6 +5404,7 @@ static const struct { { "xive-eqt", &xive_eqt_ops, }, { "xive-esc", &xive_esc_ops, }, { "xive-vpt", &xive_vpt_ops, }, + { "xive-perf", &xive_perf_ops, }, }; static void xive_init_debug(struct xive *x) From patchwork Thu Sep 17 16:35:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366264 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.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjMJ0t26z9sRR for ; Fri, 18 Sep 2020 02:38:20 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjMH6xpMzDqdD for ; Fri, 18 Sep 2020 02:38:19 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=79.137.123.220; helo=smtpout1.mo804.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo804.mail-out.ovh.net (smtpout1.mo804.mail-out.ovh.net [79.137.123.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJX2tW4zDqc9 for ; Fri, 18 Sep 2020 02:35:56 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.108.20.54]) by mo804.mail-out.ovh.net (Postfix) with ESMTPS id C191962BFFD4; Thu, 17 Sep 2020 18:35:47 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:47 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R0017dd1148a-3952-48ca-8d60-73116934a7a7, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:41 +0200 Message-ID: <20200917163544.142593-5-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: f042f58c-beef-40e2-aab2-8c3b406eff95 X-Ovh-Tracer-Id: 10404159565598002141 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 4/6] core: Add statistics framework X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This is a set of simple routines to collect statistics on function calls. It can used to measure low level HW operations and track possible issues in locking, polling, etc. Signed-off-by: Cédric Le Goater --- include/stat.h | 49 ++++++++++++++++++++++++ core/stat.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++ core/Makefile.inc | 2 +- 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 include/stat.h create mode 100644 core/stat.c diff --git a/include/stat.h b/include/stat.h new file mode 100644 index 000000000000..dc020862b199 --- /dev/null +++ b/include/stat.h @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * Statistics + * + * Copyright 2020 IBM Corp. + */ + +#ifndef __STAT_H +#define __STAT_H + +#include + +#define STAT_NR_RANGES 10 +#define STAT_RANGE_WIDTH 200 /* values */ +#define STAT_MAX_CALL_TIME 10 /* usecs */ + +struct stat_range { + uint64_t count; + uint64_t sum; + uint64_t min; + uint64_t max; +}; + +struct stat { + const char *name; + uint64_t max_call_time; + uint64_t nr_ranges; + uint64_t count; + struct stat_range all; + struct stat_range ranges[STAT_NR_RANGES]; + + struct lock lock; +}; + + +extern void stat_init(struct stat *s, const char *name, uint64_t max_call_time); +extern void stat_update(struct stat *s, uint64_t call_time); +extern int stat_printf(struct stat *s, void *buf, int size); + +#define stat_call(expr, s) \ +({ \ + uint64_t before = mftb(); \ + int64_t __rc = (expr); \ + uint64_t call_time = tb_to_usecs(mftb() - before); \ + stat_update(s, call_time); \ + __rc; \ +}) + +#endif /* __STAT_H */ diff --git a/core/stat.c b/core/stat.c new file mode 100644 index 000000000000..6d1ddf2f1a80 --- /dev/null +++ b/core/stat.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * Statistics + * + * Copyright 2020 IBM Corp. + */ + +#define pr_fmt(fmt) "STAT: " fmt + +#include +#include +#include +#include + +static void stat_range_reset(struct stat_range *r) +{ + r->count = 0; + r->sum = 0; + r->max = 0; + r->min = 0xFFFFFFFFF; +} + +void stat_init(struct stat *s, const char *name, uint64_t max_call_time) +{ + int i; + + s->name = name; + s->max_call_time = max_call_time; + s->nr_ranges = ARRAY_SIZE(s->ranges); + for (i = 0; i < s->nr_ranges; i++) + stat_range_reset(&s->ranges[i]); + stat_range_reset(&s->all); + init_lock(&s->lock); +} + +static void stat_range_update(struct stat_range *r, uint64_t call_time) +{ + r->sum += call_time; + if (call_time > r->max) + r->max = call_time; + if (call_time < r->min) + r->min = call_time; + r->count++; +} + +#define stat_range_index(s) \ + ((((s)->count) / STAT_RANGE_WIDTH) % (s)->nr_ranges) + +void stat_update(struct stat *s, uint64_t call_time) +{ + int ridx; + struct stat_range *r; + + lock(&s->lock); + + ridx = stat_range_index(s); + r = &s->ranges[ridx]; + + if (!(r->count % STAT_RANGE_WIDTH)) + stat_range_reset(r); + + stat_range_update(r, call_time); + if (s->max_call_time && call_time > s->max_call_time && + call_time > s->all.max) { + /* TODO: simulators need more time */ + prlog(PR_WARNING, "CPU 0x%04x new %s maximum %lld at #%lld\n", + this_cpu()->pir, s->name, r->max, s->count); + backtrace(); + } + stat_range_update(&s->all, call_time); + s->count++; + + unlock(&s->lock); +} + +static int stat_range_printf(struct stat_range *r, void *buf, int size) +{ + return snprintf(buf, size, "#%lld %lld/%lld/%lld - ", + r->count, + r->count ? r->min : 0, + r->sum / r->count, + r->max); +} + +int stat_printf(struct stat *s, void *buf, int size) +{ + int n = 0; + int i; + + if (s->count) { + n += snprintf(buf + n, size - n, "%35s: ", s->name); + n += stat_range_printf(&s->all, buf + n, size - n); + for (i = 0; i < s->nr_ranges; i++) + n += stat_range_printf(&s->ranges[i], buf + n, size - n); + n += snprintf(buf + n, size - n,"\n"); + } + return n; +} diff --git a/core/Makefile.inc b/core/Makefile.inc index ed7003ed7a7a..326fc7917631 100644 --- a/core/Makefile.inc +++ b/core/Makefile.inc @@ -13,7 +13,7 @@ CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o powercap.o psr.o CORE_OBJS += pci-dt-slot.o direct-controls.o cpufeatures.o CORE_OBJS += flash-firmware-versions.o opal-dump.o -CORE_OBJS += opal-debug.o +CORE_OBJS += opal-debug.o stat.o ifeq ($(SKIBOOT_GCOV),1) CORE_OBJS += gcov-profiling.o From patchwork Thu Sep 17 16:35:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366263 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.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjLp2WkKz9sSW for ; Fri, 18 Sep 2020 02:37:54 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjLp0ccFzDqfH for ; Fri, 18 Sep 2020 02:37:54 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=79.137.123.220; helo=smtpout1.mo804.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo804.mail-out.ovh.net (smtpout1.mo804.mail-out.ovh.net [79.137.123.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJW5clNzDqcT for ; Fri, 18 Sep 2020 02:35:55 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.109.156.98]) by mo804.mail-out.ovh.net (Postfix) with ESMTPS id 258D462BFFD7; Thu, 17 Sep 2020 18:35:48 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:47 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R0016632b280-0a42-4e95-b3f7-d218360314b7, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:42 +0200 Message-ID: <20200917163544.142593-6-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: 1faf7e83-89f9-4196-9756-e323e52b89a2 X-Ovh-Tracer-Id: 10404159567241841629 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 5/6] xive/p9: Add statistics for HW procedures X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Common XIVE HW procedures are cache updates and synchronization to ensure pending interrupts have reached their event queues. These can be done frequently in some scenarios. Collect some statistics for these procedures and expose the results in a debug handler to be read from Linux. The write handler does a reset. Signed-off-by: Cédric Le Goater --- hw/xive.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/hw/xive.c b/hw/xive.c index b13beb575ba1..abdb2115a1a2 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Always notify from EQ to VP (no EOI on EQs). Will speed up * EOIs at the expense of potentially higher powerbus traffic. @@ -357,6 +358,32 @@ static inline void log_print(struct xive_cpu_state *xs __unused) { } #endif /* XIVE_PERCPU_LOG */ +/* + * Statistics + */ +enum { + XIVE_IVC_SCRUB, + XIVE_VPC_SCRUB, + XIVE_VPC_SCRUB_CLEAN, + XIVE_EQC_SCRUB, + XIVE_SYNC, + XIVE_SYNC_NOLOCK, + XIVE_VC_CACHE_KILL, + XIVE_PC_CACHE_KILL, + XIVE_STAT_LAST, +}; + +static const char *xive_stat_names[] = { + "XIVE_IVC_SCRUB", + "XIVE_VPC_SCRUB", + "XIVE_VPC_SCRUB_CLEAN", + "XIVE_EQC_SCRUB", + "XIVE_SYNC", + "XIVE_SYNC_NOLOCK", + "XIVE_VC_CACHE_KILL", + "XIVE_PC_CACHE_KILL", +}; + struct xive { uint32_t chip_id; uint32_t block_id; @@ -463,6 +490,8 @@ struct xive { /* In memory queue overflow */ void *q_ovf; + + struct stat stat[XIVE_STAT_LAST]; }; #define XIVE_CAN_STORE_EOI(x) XIVE_STORE_EOI_ENABLED @@ -1202,26 +1231,34 @@ static int64_t __xive_cache_scrub(struct xive *x, enum xive_cache_type ctype, return 0; } -static int64_t xive_ivc_scrub(struct xive *x, uint64_t block, uint64_t idx) +static int64_t __xive_ivc_scrub(struct xive *x, uint64_t block, uint64_t idx) { /* IVC has no "want_inval" bit, it always invalidates */ return __xive_cache_scrub(x, xive_cache_ivc, block, idx, false, false); } +#define xive_ivc_scrub(x, b, i) \ + stat_call(__xive_ivc_scrub(x, b, i), &x->stat[XIVE_IVC_SCRUB]) -static int64_t xive_vpc_scrub(struct xive *x, uint64_t block, uint64_t idx) +static int64_t __xive_vpc_scrub(struct xive *x, uint64_t block, uint64_t idx) { return __xive_cache_scrub(x, xive_cache_vpc, block, idx, false, false); } +#define xive_vpc_scrub(x, b, i) \ + stat_call(__xive_vpc_scrub(x, b, i), &x->stat[XIVE_VPC_SCRUB]) -static int64_t xive_vpc_scrub_clean(struct xive *x, uint64_t block, uint64_t idx) +static int64_t __xive_vpc_scrub_clean(struct xive *x, uint64_t block, uint64_t idx) { return __xive_cache_scrub(x, xive_cache_vpc, block, idx, true, false); } +#define xive_vpc_scrub_clean(x, b, i) \ + stat_call(__xive_vpc_scrub_clean(x, b, i), &x->stat[XIVE_VPC_SCRUB_CLEAN]) -static int64_t xive_eqc_scrub(struct xive *x, uint64_t block, uint64_t idx) +static int64_t __xive_eqc_scrub(struct xive *x, uint64_t block, uint64_t idx) { return __xive_cache_scrub(x, xive_cache_eqc, block, idx, false, false); } +#define xive_eqc_scrub(x, b, i) \ + stat_call(__xive_eqc_scrub(x, b, i), &x->stat[XIVE_EQC_SCRUB]) static int64_t __xive_cache_watch(struct xive *x, enum xive_cache_type ctype, uint64_t block, uint64_t idx, @@ -2280,13 +2317,11 @@ static void xive_update_irq_mask(struct xive_src *s, uint32_t idx, bool masked) in_be64(mmio_base + offset); } -static int64_t xive_sync(struct xive *x) +static int64_t __xive_sync_nolock(struct xive *x) { uint64_t r; void *p; - lock(&x->lock); - /* Second 2K range of second page */ p = x->ic_base + (1 << x->ic_shift) + 0x800; @@ -2316,10 +2351,20 @@ static int64_t xive_sync(struct xive *x) /* Workaround HW issue, read back before allowing a new sync */ xive_regr(x, VC_GLOBAL_CONFIG); + return 0; +} +#define xive_sync_nolock(x) \ + stat_call(__xive_sync_nolock(x), &x->stat[XIVE_SYNC_NOLOCK]) + +static int64_t __xive_sync(struct xive *x) +{ + lock(&x->lock); + xive_sync_nolock(x); unlock(&x->lock); return 0; } +#define xive_sync(x) stat_call(__xive_sync(x), &x->stat[XIVE_SYNC]) static int64_t __xive_set_irq_config(struct irq_source *is, uint32_t girq, uint64_t vp, uint8_t prio, uint32_t lirq, @@ -2586,6 +2631,16 @@ void xive_register_ipi_source(uint32_t base, uint32_t count, void *data, flags, false, data, ops); } +#define XIVE_STAT_MAX_TIME 50 /* usecs */ + +static void xive_stat_init(struct xive *x) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(x->stat); i++) + stat_init(&x->stat[i], xive_stat_names[i], XIVE_STAT_MAX_TIME); +} + static struct xive *init_one_xive(struct dt_node *np) { struct xive *x; @@ -2695,6 +2750,8 @@ static struct xive *init_one_xive(struct dt_node *np) false, NULL, NULL); + xive_stat_init(x); + return x; fail: xive_err(x, "Initialization failed...\n"); @@ -4357,7 +4414,7 @@ static void xive_cleanup_cpu_tima(struct cpu_thread *c) xive_regw(x, PC_TCTXT_INDIR0, 0); } -static int64_t xive_vc_ind_cache_kill(struct xive *x, uint64_t type) +static int64_t __xive_vc_ind_cache_kill(struct xive *x, uint64_t type) { uint64_t val; @@ -4378,8 +4435,10 @@ static int64_t xive_vc_ind_cache_kill(struct xive *x, uint64_t type) } return 0; } +#define xive_vc_ind_cache_kill(x, type) \ + stat_call(__xive_vc_ind_cache_kill(x, type), &x->stat[XIVE_VC_CACHE_KILL]) -static int64_t xive_pc_ind_cache_kill(struct xive *x) +static int64_t __xive_pc_ind_cache_kill(struct xive *x) { uint64_t val; @@ -4399,6 +4458,8 @@ static int64_t xive_pc_ind_cache_kill(struct xive *x) } return 0; } +#define xive_pc_ind_cache_kill(x) \ + stat_call(__xive_pc_ind_cache_kill(x), &x->stat[XIVE_PC_CACHE_KILL]) static void xive_cleanup_vp_ind(struct xive *x) { @@ -5380,6 +5441,29 @@ static int xive_perf_read(struct opal_debug *d, void *buf, uint64_t size) return n; } +static int xive_stat_read(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + int n = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(x->stat); i++) + n += stat_printf(&x->stat[i], buf + n, size - n); + return n; +} + +static int xive_stat_write(struct opal_debug *d, void *buf, uint64_t size) +{ + struct xive *x = d->private; + + if (!strncmp(buf, "reset", size)) { + xive_stat_init(x); + return OPAL_SUCCESS; + } else { + return OPAL_PARAMETER; + } +} + static const struct opal_debug_ops xive_ivt_ops = { .read = xive_ivt_read, }; @@ -5395,6 +5479,10 @@ static const struct opal_debug_ops xive_vpt_ops = { static const struct opal_debug_ops xive_perf_ops = { .read = xive_perf_read, }; +static const struct opal_debug_ops xive_stat_ops = { + .read = xive_stat_read, + .write = xive_stat_write, +}; static const struct { const char *name; @@ -5405,6 +5493,7 @@ static const struct { { "xive-esc", &xive_esc_ops, }, { "xive-vpt", &xive_vpt_ops, }, { "xive-perf", &xive_perf_ops, }, + { "xive-stat", &xive_stat_ops, }, }; static void xive_init_debug(struct xive *x) From patchwork Thu Sep 17 16:35:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 1366262 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BsjLJ5D1sz9sRR for ; Fri, 18 Sep 2020 02:37:28 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4BsjLJ46pLzDqcT for ; Fri, 18 Sep 2020 02:37:28 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kaod.org (client-ip=79.137.123.220; helo=smtpout1.mo804.mail-out.ovh.net; envelope-from=clg@kaod.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=kaod.org Received: from smtpout1.mo804.mail-out.ovh.net (smtpout1.mo804.mail-out.ovh.net [79.137.123.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4BsjJW1sVtzDqcH for ; Fri, 18 Sep 2020 02:35:54 +1000 (AEST) Received: from mxplan5.mail.ovh.net (unknown [10.109.143.25]) by mo804.mail-out.ovh.net (Postfix) with ESMTPS id 7F1B762BFFD8; Thu, 17 Sep 2020 18:35:48 +0200 (CEST) Received: from kaod.org (37.59.142.96) by DAG4EX1.mxp5.local (172.16.2.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Thu, 17 Sep 2020 18:35:47 +0200 Authentication-Results: garm.ovh; auth=pass (GARM-96R001f949c150-06ae-42d2-8808-79cbd4748ed1, FF1720B74B3888C93CA5040C1F5ACCC945AC33B8) smtp.auth=clg@kaod.org From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: Date: Thu, 17 Sep 2020 18:35:43 +0200 Message-ID: <20200917163544.142593-7-clg@kaod.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200917163544.142593-1-clg@kaod.org> References: <20200917163544.142593-1-clg@kaod.org> MIME-Version: 1.0 X-Originating-IP: [37.59.142.96] X-ClientProxiedBy: DAG1EX1.mxp5.local (172.16.2.1) To DAG4EX1.mxp5.local (172.16.2.31) X-Ovh-Tracer-GUID: 25a1d9d4-2155-4f54-93fd-f794ea7d08d7 X-Ovh-Tracer-Id: 10404441040306998237 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrtdeggddutdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufffkffojghfgggtgfhisehtkeertdertdejnecuhfhrohhmpeevrogurhhitgcunfgvucfiohgrthgvrhcuoegtlhhgsehkrghougdrohhrgheqnecuggftrfgrthhtvghrnhepheehfeegjeeitdfffeetjeduveejueefuefgtdefueelueetveeliefhhffgtdelnecukfhppedtrddtrddtrddtpdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdqohhuthdphhgvlhhopehmgihplhgrnhehrdhmrghilhdrohhvhhdrnhgvthdpihhnvghtpedtrddtrddtrddtpdhmrghilhhfrhhomheptghlgheskhgrohgurdhorhhgpdhrtghpthhtoheptghlgheskhgrohgurdhorhhg Subject: [Skiboot] [RFC PATCH 6/6] xive/p9: Allocate all XIVE structures on a selected chip X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Currently, the NVTs and ENDs are distributed across the chips of the system. For test and performance, it is interesting to have a better control on the allocation of the XIVE structures. Introduce a way to force the allocation of the NVTs, the associated ENDs and the IPIs on a XIVE preferred chip. The NVTs and associated ENDs of the HW threads are still allocated on their respective chip but for all OS interrupt contexts, the XIVE structures are allocated on the preferred chip. This behavior can be changed with the debugfs handler. Signed-off-by: Cédric Le Goater --- hw/xive.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/hw/xive.c b/hw/xive.c index abdb2115a1a2..112b837f8a80 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -607,6 +607,7 @@ static uint32_t xive_chip_to_block(uint32_t chip_id) static uint32_t xive_chips_alloc_bits = 0; static struct buddy *xive_vp_buddy; static struct lock xive_buddy_lock = LOCK_UNLOCKED; +static uint32_t xive_preferred_chip = OPAL_XIVE_ANY_CHIP; /* VP# decoding/encoding */ static bool xive_decode_vp(uint32_t vp, uint32_t *blk, uint32_t *idx, @@ -645,6 +646,9 @@ static bool xive_decode_vp(uint32_t vp, uint32_t *blk, uint32_t *idx, if (blk) *blk = (index >> (o - n)) & ((1 << n) - 1); + if (xive_preferred_chip != OPAL_XIVE_ANY_CHIP) + *blk = xive_chip_to_block(xive_preferred_chip); + /* Return order as well if asked for */ if (order) *order = o; @@ -1005,13 +1009,24 @@ static bool xive_provision_vp_ind(struct xive *x, uint32_t vp_idx, uint32_t orde return true; } +static void xive_init_vp_allocator_chip(uint32_t chip_id) +{ + if (chip_id == OPAL_XIVE_ANY_CHIP) { + xive_chips_alloc_bits = ilog2(xive_block_count); + prlog(PR_INFO, "XIVE: %d chips considered for VP allocations\n", + 1 << xive_chips_alloc_bits); + } else { + xive_chips_alloc_bits = 0; + prlog(PR_INFO, "XIVE: single chip %d considered for VP allocations\n", + chip_id); + } + xive_preferred_chip = chip_id; +} + static void xive_init_vp_allocator(void) { /* Initialize chip alloc bits */ - xive_chips_alloc_bits = ilog2(xive_block_count); - - prlog(PR_INFO, "XIVE: %d chips considered for VP allocations\n", - 1 << xive_chips_alloc_bits); + xive_init_vp_allocator_chip(OPAL_XIVE_ANY_CHIP); /* Allocate a buddy big enough for XIVE_VP_ORDER allocations. * @@ -1052,7 +1067,9 @@ static uint32_t xive_alloc_vps(uint32_t order) /* Provision on every chip considered for allocation */ for (i = 0; i < (1 << xive_chips_alloc_bits); i++) { - struct xive *x = xive_from_pc_blk(i); + uint32_t blk = xive_preferred_chip == OPAL_XIVE_ANY_CHIP ? + i : xive_chip_to_block(xive_preferred_chip); + struct xive *x = xive_from_pc_blk(blk); bool success; /* Return internal error & log rather than assert ? */ @@ -4718,8 +4735,13 @@ static int64_t opal_xive_free_vp_block(uint64_t vp_base) return OPAL_PARAMETER; if (group) return OPAL_PARAMETER; - if (blk) - return OPAL_PARAMETER; + if (xive_preferred_chip == OPAL_XIVE_ANY_CHIP) { + if (blk) + return OPAL_PARAMETER; + } else { + if (blk != xive_chip_to_block(xive_preferred_chip)) + return OPAL_PARAMETER; + } if (order < (xive_chips_alloc_bits + 1)) return OPAL_PARAMETER; if (idx & ((1 << (order - xive_chips_alloc_bits)) - 1)) @@ -4913,7 +4935,10 @@ static int64_t opal_xive_allocate_irq(uint32_t chip_id) if (chip_id == OPAL_XIVE_ANY_CHIP) { try_all = true; - chip_id = this_cpu()->chip_id; + if (xive_preferred_chip == OPAL_XIVE_ANY_CHIP) + chip_id = this_cpu()->chip_id; + else + chip_id = xive_preferred_chip; } chip = get_chip(chip_id); if (!chip) @@ -5464,6 +5489,49 @@ static int xive_stat_write(struct opal_debug *d, void *buf, uint64_t size) } } +static int xive_vp_alloc_read(struct opal_debug *d __unused, void *buf, + uint64_t size) +{ + int n = 0; + + if (xive_chips_alloc_bits) + n += snprintf(buf + n, size - n, "VP allocator : distributed\n"); + else + n += snprintf(buf + n, size - n, "VP allocator : single chip %d\n", + xive_preferred_chip); + + return n; +} + +static int xive_vp_alloc_write(struct opal_debug *d __unused, void *buf, + uint64_t size) +{ + int chip_id; + + if (!strncmp(buf, "distributed", size)) { + chip_id = OPAL_XIVE_ANY_CHIP; + } else if (!strncmp(buf, "single", size)) { + chip_id = 0; + } else { + char *p = NULL; + + chip_id = strtol(buf, &p, 10); + if (*p || p == buf) + return OPAL_PARAMETER; + if (!get_chip(chip_id)) + return OPAL_PARAMETER; + } + + if (xive_preferred_chip != chip_id) + xive_init_vp_allocator_chip(chip_id); + return OPAL_SUCCESS; +} + +static const struct opal_debug_ops xive_vp_alloc_ops = { + .read = xive_vp_alloc_read, + .write = xive_vp_alloc_write, +}; + static const struct opal_debug_ops xive_ivt_ops = { .read = xive_ivt_read, }; @@ -5494,6 +5562,7 @@ static const struct { { "xive-vpt", &xive_vpt_ops, }, { "xive-perf", &xive_perf_ops, }, { "xive-stat", &xive_stat_ops, }, + { "xive-vp-alloc", &xive_vp_alloc_ops, }, }; static void xive_init_debug(struct xive *x)