From patchwork Wed May 29 08:44:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 165336 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp9580094ili; Wed, 29 May 2019 01:44:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqypqeV0+Noc4jp/y2K5HEWLVv9KfG0dmIN6JSipFQ0be0Ctsx+JJoR1qXueRLayURX5gANS X-Received: by 2002:a65:48c3:: with SMTP id o3mr30225909pgs.351.1559119493251; Wed, 29 May 2019 01:44:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559119493; cv=none; d=google.com; s=arc-20160816; b=W6AO04sHVX3r/ZZEbo6zCptKjIXibA9oPcCENRx+zF2ojlIqAa4PzeqCSpT+pireLv l7BNrwloH/a3cBJleobMl1h6y106JbOWQjZSqG0u7bRqJzMA5hBUE1bSrYY7VW5sBJGz nlm8qUHimFYV42jBw7KIw3KOLby9l7L2B2cM/v6TaTOS5sIJP6euOPhe8VEVfOAVJItj uNdA/43lynOWTMcnCoTIgnzkdKr2nLFz3kb/OgSAsiShxtJ0ZtH6V1hL77kbRLQnHG0F +aar7c2/amrDC+U/VGmqCAL2Rc5JSg+ZVhmP5i+uo9lETVaCk1bS8qVN5Mv3USq3WTLB 5ciA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :content-language:accept-language:in-reply-to:references:message-id :date:thread-index:thread-topic:subject:cc:to:from:dkim-signature :dkim-signature; bh=yHYwU54umMELZAQMIPMJ37PnFVJnG63kxP1wbyaS+CM=; b=jZQeET17xR4FJ6tqg66mrL9Ef1wkIYyxHdP0Qb8XtnzWmo9BaORBLUvrIqDn85gynJ SeZo+25BXurF/daFuUTqBaawtF8JRX0cStUXoS10bOmI05FFrkwzijXLeHACngJl8kL/ C5XzkCZXGZlmnZ8YH5YJLvzSDXDc7Y9vSjqBF5JubxBcYhgqN5rGQ5J7MhRSaTgocVFx y1WVG0nOwQ7qgqk9eitMkw1p5qDp0/J2ofUIOui6LSPwzrx2n57o6vNorM8P03f1qlpj vRRqHQAHdklTmw8kWbKF2dZ3lj+HhB3ChCK2TqLP2uMWPFyFKXowZiXfvV+kXrbWIk69 vBqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0818 header.b=OduGwTVW; dkim=pass header.i=@marvell.onmicrosoft.com header.s=selector2-marvell-onmicrosoft-com header.b=THK+d77n; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=marvell.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n7si24246780pgq.459.2019.05.29.01.44.52; Wed, 29 May 2019 01:44:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0818 header.b=OduGwTVW; dkim=pass header.i=@marvell.onmicrosoft.com header.s=selector2-marvell-onmicrosoft-com header.b=THK+d77n; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=marvell.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726879AbfE2Iow (ORCPT + 30 others); Wed, 29 May 2019 04:44:52 -0400 Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:49570 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726786AbfE2Iop (ORCPT ); Wed, 29 May 2019 04:44:45 -0400 Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x4T8do5H017769; Wed, 29 May 2019 01:44:38 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pfpt0818; bh=yHYwU54umMELZAQMIPMJ37PnFVJnG63kxP1wbyaS+CM=; b=OduGwTVWe8/YBsjormnIyGxEOqTjB0bimAy19N+JWUqdXTTw+GGDTZ3yb9lVhrE26slv ZfkGbjmpHBC1dM7MAYZf2uiAuePxqeDzu36+1ffS5UL5OrkyRm+OxH0XD8+iJRIqGMRO SPo4VIbI/0eDC0uhvFSro3dFNr92Oc38O1naE+x7NR5+MrHvHV/bV/YNzaHnU8zqrt+M As1/IuoczDqRjQZtjPfEVz1anCYV129PBh/CNNHx+bsjQci4ZmRDow6MR2WArUHAA5k+ mGdrRYfTKrn38rLvvFLjhtqf8nxaqJRvYoO0GnXe6jYC+TwWJUMWYOBSim2Pr42aPd+J zA== Received: from sc-exch04.marvell.com ([199.233.58.184]) by mx0b-0016f401.pphosted.com with ESMTP id 2sskp88p6g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 29 May 2019 01:44:37 -0700 Received: from SC-EXCH04.marvell.com (10.93.176.84) by SC-EXCH04.marvell.com (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Wed, 29 May 2019 01:44:36 -0700 Received: from NAM03-CO1-obe.outbound.protection.outlook.com (104.47.40.53) by SC-EXCH04.marvell.com (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1367.3 via Frontend Transport; Wed, 29 May 2019 01:44:36 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.onmicrosoft.com; s=selector2-marvell-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yHYwU54umMELZAQMIPMJ37PnFVJnG63kxP1wbyaS+CM=; b=THK+d77n6PANHEDEJ7PwclhPhC67li/3eZe3OXn1wr9BMWraMduPdTDrGP1Xk+nDKQMKz7v6V/hsZ+qzGKYiz4sdXSfAFqYJYe0W9wgk3B1KUsP/dXJCN1akKFZC6Vea4QP+yG+IIgk4DNqRqw60duM86BWhWnG3h165QI6qm7E= Received: from MN2PR18MB3408.namprd18.prod.outlook.com (10.255.238.217) by MN2PR18MB3437.namprd18.prod.outlook.com (10.255.239.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1922.20; Wed, 29 May 2019 08:44:33 +0000 Received: from MN2PR18MB3408.namprd18.prod.outlook.com ([fe80::7c9a:f3bf:fe2e:fe4a]) by MN2PR18MB3408.namprd18.prod.outlook.com ([fe80::7c9a:f3bf:fe2e:fe4a%4]) with mapi id 15.20.1922.021; Wed, 29 May 2019 08:44:33 +0000 From: Robert Richter To: Borislav Petkov , Tony Luck , "James Morse" , Mauro Carvalho Chehab CC: "linux-edac@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Robert Richter Subject: [PATCH 13/21] EDAC, ghes: Rework memory hierarchy detection Thread-Topic: [PATCH 13/21] EDAC, ghes: Rework memory hierarchy detection Thread-Index: AQHVFfq8/D/t80TYn0adLRIpgQ6mjA== Date: Wed, 29 May 2019 08:44:32 +0000 Message-ID: <20190529084344.28562-14-rrichter@marvell.com> References: <20190529084344.28562-1-rrichter@marvell.com> In-Reply-To: <20190529084344.28562-1-rrichter@marvell.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM6PR01CA0046.eurprd01.prod.exchangelabs.com (2603:10a6:20b:e0::23) To MN2PR18MB3408.namprd18.prod.outlook.com (2603:10b6:208:16c::25) x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.20.1 x-originating-ip: [78.54.13.57] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2743c187-3161-48a1-4158-08d6e411def9 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600148)(711020)(4605104)(1401327)(2017052603328)(7193020); SRVR:MN2PR18MB3437; x-ms-traffictypediagnostic: MN2PR18MB3437: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:595; x-forefront-prvs: 0052308DC6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(346002)(396003)(376002)(39860400002)(136003)(189003)(199004)(8936002)(4326008)(53936002)(50226002)(110136005)(107886003)(68736007)(36756003)(5660300002)(54906003)(11346002)(26005)(186003)(52116002)(2906002)(2616005)(476003)(446003)(6506007)(14454004)(66476007)(25786009)(478600001)(386003)(86362001)(486006)(81166006)(81156014)(8676002)(305945005)(316002)(7736002)(256004)(99286004)(76176011)(6512007)(6436002)(73956011)(64756008)(66446008)(66556008)(66066001)(3846002)(66946007)(1076003)(6486002)(102836004)(71190400001)(71200400001)(6116002); DIR:OUT; SFP:1101; SCL:1; SRVR:MN2PR18MB3437; H:MN2PR18MB3408.namprd18.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: marvell.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: zoK7d2nxjLTHwa7WJq9EFVYv+vHvhWG+DUyvdOlOAzbzFY87MBA2lvguq3crRT44lAiLPHAH9Iv4tyNXaGi1Nd3FP31q/b2x3YwONa/rbbMYPy17DwheGE/u7l8UlGephS/Djkd+AFD5IagKrWsT/3wDPCp5YWms7CaA+uwjwUAIh8jwgM29r6FXe452Ca/thVMDasnmRuUQ8+OYXHl/+L0UuCk+ewy6Nk0AuxIELNgJEuMKpcJqtYcXnrgl1g2InDCQdKHjLow2cakWj2EjW+qY4J2I89KgsAnTSvJivXZg1t50MXxLSDnPX975c1VwHdlcCbKKD5o+9yObecB2SZQGgHBK/o3BaDXE2oWulIdejdHGd4sBuoK8xO9x/kSURV7g800l4ZET1/4UWjW9uJtdMvr7L564Cb9/J1g2KAM= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 2743c187-3161-48a1-4158-08d6e411def9 X-MS-Exchange-CrossTenant-originalarrivaltime: 29 May 2019 08:44:32.9630 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 70e1fb47-1155-421d-87fc-2e58f638b6e0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: rrichter@marvell.com X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR18MB3437 X-OriginatorOrg: marvell.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-05-29_05:, , signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In a later patch we want add more information about the memory hierarchy (NUMA topology, DIMM label information). Rework memory hierarchy detection to make the code extendable for this. The general approach is roughly like: mem_info_setup(); for_each_node(nid) { mci = edac_mc_alloc(nid); mci_add_dimm_info(mci); edac_mc_add_mc(mci); }; This patch introduces mem_info_setup() and mci_add_dimm_info(). All data of the memory hierarchy is collected in a local struct ghes_mem_info. Note: Per (NUMA) node registration will be implemented in a later patch. Signed-off-by: Robert Richter --- drivers/edac/ghes_edac.c | 166 +++++++++++++++++++++++++++++---------- 1 file changed, 126 insertions(+), 40 deletions(-) -- 2.20.1 diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index ea4d53043199..50f4ee36b755 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -67,17 +67,38 @@ struct memdev_dmi_entry { u16 conf_mem_clk_speed; } __attribute__((__packed__)); -struct ghes_edac_dimm_fill { - struct mem_ctl_info *mci; - unsigned count; +struct ghes_dimm_info { + struct dimm_info dimm_info; + int idx; +}; + +struct ghes_mem_info { + int num_dimm; + struct ghes_dimm_info *dimms; }; +struct ghes_mem_info mem_info; + +#define for_each_dimm(dimm) \ + for (dimm = mem_info.dimms; \ + dimm < mem_info.dimms + mem_info.num_dimm; \ + dimm++) + static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg) { - int *num_dimm = arg; - if (dh->type == DMI_ENTRY_MEM_DEVICE) - (*num_dimm)++; + mem_info.num_dimm++; +} + +static void ghes_dimm_info_init(void) +{ + struct ghes_dimm_info *dimm; + int idx = 0; + + for_each_dimm(dimm) { + dimm->idx = idx; + idx++; + } } static int get_dimm_smbios_index(u16 handle) @@ -94,18 +115,17 @@ static int get_dimm_smbios_index(u16 handle) static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) { - struct ghes_edac_dimm_fill *dimm_fill = arg; - struct mem_ctl_info *mci = dimm_fill->mci; - if (dh->type == DMI_ENTRY_MEM_DEVICE) { + int *idx = arg; struct memdev_dmi_entry *entry = (struct memdev_dmi_entry *)dh; - struct dimm_info *dimm = edac_get_dimm(mci, dimm_fill->count, - 0, 0); + struct ghes_dimm_info *mi = &mem_info.dimms[*idx]; + struct dimm_info *dimm = &mi->dimm_info; u16 rdr_mask = BIT(7) | BIT(13); + mi->phys_handle = entry->phys_mem_array_handle; + if (entry->size == 0xffff) { - pr_info("Can't get DIMM%i size\n", - dimm_fill->count); + pr_info("Can't get DIMM%i size\n", mi->idx); dimm->nr_pages = MiB_TO_PAGES(32);/* Unknown */ } else if (entry->size == 0x7fff) { dimm->nr_pages = MiB_TO_PAGES(entry->extended_size); @@ -179,7 +199,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) if (dimm->nr_pages) { edac_dbg(1, "DIMM%i: %s size = %d MB%s\n", - dimm_fill->count, edac_mem_types[dimm->mtype], + mi->idx, edac_mem_types[dimm->mtype], PAGES_TO_MiB(dimm->nr_pages), (dimm->edac_mode != EDAC_NONE) ? "(ECC)" : ""); edac_dbg(2, "\ttype %d, detail 0x%02x, width %d(total %d)\n", @@ -189,8 +209,83 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) dimm->smbios_handle = entry->handle; - dimm_fill->count++; + (*idx)++; + } +} + +static int mem_info_setup(void) +{ + int idx = 0; + + memset(&mem_info, 0, sizeof(mem_info)); + + /* Get the number of DIMMs */ + dmi_walk(ghes_edac_count_dimms, NULL); + if (!mem_info.num_dimm) + return -EINVAL; + + mem_info.dimms = kcalloc(mem_info.num_dimm, + sizeof(*mem_info.dimms), GFP_KERNEL); + if (!mem_info.dimms) + return -ENOMEM; + + ghes_dimm_info_init(); + dmi_walk(ghes_edac_dmidecode, &idx); + + return 0; +} + +static int mem_info_setup_fake(void) +{ + struct ghes_dimm_info *ghes_dimm; + struct dimm_info *dimm; + + memset(&mem_info, 0, sizeof(mem_info)); + + ghes_dimm = kzalloc(sizeof(*mem_info.dimms), GFP_KERNEL); + if (!ghes_dimm) + return -ENOMEM; + + mem_info.num_dimm = 1; + mem_info.dimms = ghes_dimm; + + ghes_dimm_info_init(); + + dimm = &ghes_dimm->dimm_info; + dimm->nr_pages = 1; + dimm->grain = 128; + dimm->mtype = MEM_UNKNOWN; + dimm->dtype = DEV_UNKNOWN; + dimm->edac_mode = EDAC_SECDED; + + return 0; +} + +static void mci_add_dimm_info(struct mem_ctl_info *mci) +{ + struct dimm_info *mci_dimm, *dmi_dimm; + struct ghes_dimm_info *dimm; + int index = 0; + + for_each_dimm(dimm) { + dmi_dimm = &dimm->dimm_info; + mci_dimm = edac_get_dimm_by_index(mci, index); + + index++; + if (index > mci->tot_dimms) + break; + + mci_dimm->nr_pages = dmi_dimm->nr_pages; + mci_dimm->mtype = dmi_dimm->mtype; + mci_dimm->edac_mode = dmi_dimm->edac_mode; + mci_dimm->dtype = dmi_dimm->dtype; + mci_dimm->grain = dmi_dimm->grain; + mci_dimm->smbios_handle = dmi_dimm->smbios_handle; } + + if (index != mci->tot_dimms) + pr_warn("Unexpected number of DIMMs: %d (exp. %d)\n", + index, mci->tot_dimms); } void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) @@ -451,10 +546,9 @@ static struct acpi_platform_list plat_list[] = { int ghes_edac_register(struct ghes *ghes, struct device *dev) { bool fake = false; - int rc, num_dimm = 0; + int rc; struct mem_ctl_info *mci; struct edac_mc_layer layers[1]; - struct ghes_edac_dimm_fill dimm_fill; int idx = -1; if (IS_ENABLED(CONFIG_X86)) { @@ -472,22 +566,24 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) if (atomic_inc_return(&ghes_init) > 1) return 0; - /* Get the number of DIMMs */ - dmi_walk(ghes_edac_count_dimms, &num_dimm); - - /* Check if we've got a bogus BIOS */ - if (num_dimm == 0) { + rc = mem_info_setup(); + if (rc == -EINVAL) { + /* we've got a bogus BIOS */ fake = true; - num_dimm = 1; + rc = mem_info_setup_fake(); + } + if (rc < 0) { + pr_err("Can't allocate memory for DIMM data\n"); + return rc; } layers[0].type = EDAC_MC_LAYER_ALL_MEM; - layers[0].size = num_dimm; + layers[0].size = mem_info.num_dimm; layers[0].is_virt_csrow = true; mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct ghes_edac_pvt)); if (!mci) { - pr_info("Can't allocate memory for EDAC data\n"); + pr_err("Can't allocate memory for EDAC data\n"); return -ENOMEM; } @@ -513,26 +609,14 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) pr_info("So, the end result of using this driver varies from vendor to vendor.\n"); pr_info("If you find incorrect reports, please contact your hardware vendor\n"); pr_info("to correct its BIOS.\n"); - pr_info("This system has %d DIMM sockets.\n", num_dimm); + pr_info("This system has %d DIMM sockets.\n", mem_info.num_dimm); } - if (!fake) { - dimm_fill.count = 0; - dimm_fill.mci = mci; - dmi_walk(ghes_edac_dmidecode, &dimm_fill); - } else { - struct dimm_info *dimm = edac_get_dimm(mci, 0, 0, 0); - - dimm->nr_pages = 1; - dimm->grain = 128; - dimm->mtype = MEM_UNKNOWN; - dimm->dtype = DEV_UNKNOWN; - dimm->edac_mode = EDAC_SECDED; - } + mci_add_dimm_info(mci); rc = edac_mc_add_mc(mci); if (rc < 0) { - pr_info("Can't register at EDAC core\n"); + pr_err("Can't register at EDAC core\n"); edac_mc_free(mci); return -ENODEV; } @@ -549,4 +633,6 @@ void ghes_edac_unregister(struct ghes *ghes) mci = ghes_pvt->mci; edac_mc_del_mc(mci->pdev); edac_mc_free(mci); + + kfree(mem_info.dimms); }