From patchwork Mon Jun 24 15:09:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 167622 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp4348856ilk; Mon, 24 Jun 2019 08:10:30 -0700 (PDT) X-Google-Smtp-Source: APXvYqyCX3WI1zTcO59pkJrMtS/etGZlhPJKDtT5yZo1TSGAk3f8klJhvyoiwVgXEaJYSPrh0VzA X-Received: by 2002:a17:902:9688:: with SMTP id n8mr66110294plp.227.1561389030286; Mon, 24 Jun 2019 08:10:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561389030; cv=none; d=google.com; s=arc-20160816; b=AhdZinVahs4lfLV87OC4pWgbtz5Z3j+iFUexJ0+Wut6tPFyk0EwoxBvQjC84dnQPxu nzM66BPfg40Y0RWDCNbiy5IvCULttAy1dYaiGvJoq4o8UQC4yjLcsKs1FpqhUwzsPUzK 7er5bGTvhPBBFpA/7xzAB2wts7uEm9Xfm+hNSPcW4HFjhtZQ6DOIdTl7GYCFJp6RpVB8 ficlMFIJ+E/BOlqI7knK4C8U+/Rw7YyTWwvBf6VFu8BPoYBWJi8jeVyVwehfNTaz+uMg xrX1TtG76E5lUqj7DwXCLMZ0Kumt5zmYF5CNqAh749ckVeGAc2ejFkbLgKEa04goXArJ cfJQ== 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=bfflnRYpDvVdGA7neySELZzZvsBkLFBVWu6IDjZu6HQ=; b=pmW36rdXaQ9t28hQRg4/EOxa40jWKRM3x7AbSTaZzFWjAcQ+tQJgeA/QklPc2LLxAV oEHIgtADv8CwxdSBb9xAM0k9/6BxIb5c3EqlV12RUDG2yoEVe+TB80EoX5LPDaN9SmAL lPChvPsKE7hE9syx7sQvVGyzqQxtdy51jSvgBrgz0xs7pD+EQ/MkeWg/1RHrf8j7LPRx QtWp44RvVIadLBcQCPPKTc2YrLfaY/bePtomu/uy02lRomkg+6zsYCFtLt3xx9JGTBrj GyTDblf7uvRbmOO0FQbAIWiM8JMboqac6gd0GCu7D8fHpHlGw2/QQ0M3AYbF/26gZIVH rE8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0818 header.b=M5rHCx7J; dkim=pass header.i=@marvell.onmicrosoft.com header.s=selector2-marvell-onmicrosoft-com header.b=m91mrY0i; 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 a14si11359572pfo.37.2019.06.24.08.10.29; Mon, 24 Jun 2019 08:10:30 -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=M5rHCx7J; dkim=pass header.i=@marvell.onmicrosoft.com header.s=selector2-marvell-onmicrosoft-com header.b=m91mrY0i; 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 S1731101AbfFXPK2 (ORCPT + 30 others); Mon, 24 Jun 2019 11:10:28 -0400 Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:21666 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730643AbfFXPJd (ORCPT ); Mon, 24 Jun 2019 11:09:33 -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 x5OF8C7s025877; Mon, 24 Jun 2019 08:09:27 -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=bfflnRYpDvVdGA7neySELZzZvsBkLFBVWu6IDjZu6HQ=; b=M5rHCx7JR5QPTrHc/KvthGz447imA11rIgVvZ3UDz/YuDDmnpIu0h2ZNWeLTRM7qmMvS JvKn7gRNHYq4SqR44NDhbn+Bg1OCQwKTgfPe0hwTbXtptobZSU4np69w1SJxaMJOmGdM rVxU7jxWB38JrN2RMllxdsPkAyoS3JEu8PWz7oprLdCyezzHpcfBxhkzeVZP3Yjv8zQU 1A9yZHD3ZZIkg6uct/jGZPMOzpVCwMe1ncTdf38QJaGWKy6GAYK74xdWsd0q2IqbkGz8 04dZDClUonaZiur5n6uH9UVBtDY+0Ix4MbH2WzLKAVdY7LYRT4/tLMxvEiQakmagNwis vQ== Received: from sc-exch03.marvell.com ([199.233.58.183]) by mx0b-0016f401.pphosted.com with ESMTP id 2t9kujf7tc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 24 Jun 2019 08:09:27 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Mon, 24 Jun 2019 08:09:25 -0700 Received: from NAM03-BY2-obe.outbound.protection.outlook.com (104.47.42.57) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1367.3 via Frontend Transport; Mon, 24 Jun 2019 08:09:25 -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=bfflnRYpDvVdGA7neySELZzZvsBkLFBVWu6IDjZu6HQ=; b=m91mrY0ixUbxvGes4T3rUlpAEQr8fxz8N1Bvp1j+b5619HSlvZkkQ5eTe+53gf3Qz6UuRdOzYqA/pgqQVbDzpVUMgLgAbGi7+DUBFBPFp5N2CdOk6QvcePEJgkQLO/jg0Pw/Q0YiGeiGN3ZHbIDVBMFLpERjjf7cY01LEcar+LE= Received: from MN2PR18MB3408.namprd18.prod.outlook.com (10.255.238.217) by MN2PR18MB3197.namprd18.prod.outlook.com (10.255.236.158) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2008.13; Mon, 24 Jun 2019 15:09:24 +0000 Received: from MN2PR18MB3408.namprd18.prod.outlook.com ([fe80::d3:794c:1b94:cf3]) by MN2PR18MB3408.namprd18.prod.outlook.com ([fe80::d3:794c:1b94:cf3%4]) with mapi id 15.20.2008.014; Mon, 24 Jun 2019 15:09:24 +0000 From: Robert Richter To: Borislav Petkov , James Morse , "Mauro Carvalho Chehab" CC: "linux-edac@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Robert Richter Subject: [PATCH v2 14/24] EDAC, ghes: Rework memory hierarchy detection Thread-Topic: [PATCH v2 14/24] EDAC, ghes: Rework memory hierarchy detection Thread-Index: AQHVKp7OqLehG2JpFEKKkNY8azlMkA== Date: Mon, 24 Jun 2019 15:09:24 +0000 Message-ID: <20190624150758.6695-15-rrichter@marvell.com> References: <20190624150758.6695-1-rrichter@marvell.com> In-Reply-To: <20190624150758.6695-1-rrichter@marvell.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HE1P190CA0035.EURP190.PROD.OUTLOOK.COM (2603:10a6:7:52::24) 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: [92.254.182.202] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 33b5620a-03bc-4669-fbc2-08d6f8b5f10c x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600148)(711020)(4605104)(1401327)(2017052603328)(7193020); SRVR:MN2PR18MB3197; x-ms-traffictypediagnostic: MN2PR18MB3197: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:595; x-forefront-prvs: 007814487B x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(366004)(136003)(396003)(346002)(376002)(199004)(189003)(36756003)(110136005)(107886003)(54906003)(81156014)(81166006)(68736007)(8676002)(25786009)(5660300002)(8936002)(305945005)(7736002)(4326008)(1076003)(186003)(6116002)(14454004)(476003)(486006)(2616005)(11346002)(256004)(446003)(3846002)(50226002)(26005)(2906002)(52116002)(76176011)(71200400001)(71190400001)(99286004)(386003)(6506007)(102836004)(478600001)(316002)(86362001)(6512007)(66066001)(53936002)(6486002)(73956011)(66946007)(66476007)(66556008)(64756008)(66446008)(6436002); DIR:OUT; SFP:1101; SCL:1; SRVR:MN2PR18MB3197; H:MN2PR18MB3408.namprd18.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX: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: rzO0p7EwJrw7BOx7OMR/vQsF9Sa9GO43xtMhXl1mTrHnxTaxL9Krh6p/6NCCN4JFcYaXUEEb76rpDyLycNNTtlk19WUY6am/2OPTVm7i2U7SACskU6wHybKluqWRpFaF3HjN9liYdX/JrQhUCQghxj542KE6Zv9yzFFF9OwFd3WjoZ0wFduWM/xI6P637zuUv2GkyrzgX0hOKT5K4+mfNz9vVJLSp+dGzFAuS4O9Q5uizGJL3PZ35yw6vnQ94tVxQLbrBMCtTMCUEvXlb4dwyFVczADVYqqqUr6m9/rWr2ShezprOPkXSj+LoU8nqogOKwPshwMaNKK0JNo70EV2uO1lf+F0G6Nyh+Ah9KPFnvHhJ34RDJT2hOWdi2+9dxhHGLaYaBXLxcnV5uq/1zbHrX5MOR3scY32vix5dUO7jc8= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 33b5620a-03bc-4669-fbc2-08d6f8b5f10c X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Jun 2019 15:09:24.0630 (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: MN2PR18MB3197 X-OriginatorOrg: marvell.com X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-06-24_10:, , 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 to 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); mem_info_prepare_mci(mci); edac_mc_add_mc(mci); }; This patch introduces mem_info_setup() and mem_info_prepare_mci(). 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, 127 insertions(+), 39 deletions(-) -- 2.20.1 diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 8063996a311d..44bfb499b147 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -65,17 +65,53 @@ 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; }; +static 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; + int *num = arg; if (dh->type == DMI_ENTRY_MEM_DEVICE) - (*num_dimm)++; + (*num)++; +} + +static int ghes_dimm_info_init(int num) +{ + struct ghes_dimm_info *dimm; + int idx = 0; + + memset(&mem_info, 0, sizeof(mem_info)); + + if (num <= 0) + return -EINVAL; + + mem_info.dimms = kcalloc(num, sizeof(*mem_info.dimms), GFP_KERNEL); + if (!mem_info.dimms) + return -ENOMEM; + + mem_info.num_dimm = num; + + for_each_dimm(dimm) { + dimm->idx = idx; + idx++; + } + + return 0; } static int get_dimm_smbios_index(u16 handle) @@ -92,18 +128,15 @@ 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); 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); @@ -177,7 +210,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", @@ -187,10 +220,74 @@ 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 num = 0; + int idx = 0; + int ret; + + /* Get the number of DIMMs */ + dmi_walk(ghes_edac_count_dimms, &num); + + ret = ghes_dimm_info_init(num); + if (ret) + return ret; + + dmi_walk(ghes_edac_dmidecode, &idx); + + return 0; +} + +static int mem_info_setup_fake(void) +{ + struct dimm_info *dimm; + int ret; + + ret = ghes_dimm_info_init(1); + if (ret) + return ret; + + dimm = &mem_info.dimms->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 mem_info_prepare_mci(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) { struct dimm_info *dimm_info; @@ -450,10 +547,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)) { @@ -471,22 +567,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; } @@ -512,26 +610,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; - } + mem_info_prepare_mci(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; } @@ -548,4 +634,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); }