From nobody Sun Nov 24 10:50:08 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@fujitsu.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1723130047; cv=none; d=zohomail.com; s=zohoarc; b=AjsGrJH1T43hE/h289GdC6zYG6ieWgAKZfY7GlS/jEvIpTx9DVxuevGGMf6dIh8qy7DZ1Hj9AQwsPyP0XsvAsKmdp9iYs09up/ChCI3Xq0jv5sylJAYla4ctuOaAdGwGeRNlFjKUuLYcWRQo8/1O+vYRYb5vYSin6mmxbZ046zI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1723130047; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=a41YnmUzqDovxtesQJciAICS9pMJSCtzJTIOnmdLE1s=; b=keSKrvs1tLtTrQ7Mgn/vPWGhoHTKGTfInA6mXgXQIkkpV1YP52YhsLD11BrtCCGIgpfooFAYxNoKH/wVcDMy10V+Ag8b+nlHB+6j+daOXwCq2aIxVMt5IKbRuZMxkpiNYUuYi9bGT70z7jvD2zipchoQUV1yDLDh2GBFNVDo/YM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@fujitsu.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1723130047213196.47935176120518; Thu, 8 Aug 2024 08:14:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sc4pl-0007Up-M5; Thu, 08 Aug 2024 11:13:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sc4ph-0007Rr-8f for qemu-devel@nongnu.org; Thu, 08 Aug 2024 11:13:41 -0400 Received: from esa8.hc1455-7.c3s2.iphmx.com ([139.138.61.253]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sc4pe-0003aE-SV for qemu-devel@nongnu.org; Thu, 08 Aug 2024 11:13:41 -0400 Received: from unknown (HELO yto-r1.gw.nic.fujitsu.com) ([218.44.52.217]) by esa8.hc1455-7.c3s2.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Aug 2024 00:13:34 +0900 Received: from yto-m4.gw.nic.fujitsu.com (yto-nat-yto-m4.gw.nic.fujitsu.com [192.168.83.67]) by yto-r1.gw.nic.fujitsu.com (Postfix) with ESMTP id B5DB2D5A46 for ; Fri, 9 Aug 2024 00:13:32 +0900 (JST) Received: from kws-ab4.gw.nic.fujitsu.com (kws-ab4.gw.nic.fujitsu.com [192.51.206.22]) by yto-m4.gw.nic.fujitsu.com (Postfix) with ESMTP id F3394D3F20 for ; Fri, 9 Aug 2024 00:13:31 +0900 (JST) Received: from edo.cn.fujitsu.com (edo.cn.fujitsu.com [10.167.33.5]) by kws-ab4.gw.nic.fujitsu.com (Postfix) with ESMTP id 6F33C2289DA for ; Fri, 9 Aug 2024 00:13:31 +0900 (JST) Received: from irides.g08.fujitsu.local (unknown [10.167.226.114]) by edo.cn.fujitsu.com (Postfix) with ESMTP id 8C5951A000C; Thu, 8 Aug 2024 23:13:30 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=fujitsu.com; i=@fujitsu.com; q=dns/txt; s=fj2; t=1723130018; x=1754666018; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KgIqmjD+KlW1kjDaEXej5x0fZ6oZID/cY1gsTrU8Dv4=; b=QqhsuvQdaFcqxKbI1PIXAaSOIEjr1nw2VbY0INvDmxRF5+aC0cTxGd4W jLXUPfLFy7mAeY4+wvR6AkY+HMdNq6iOvcL40S+U2RcrTLnEpOx1K8hjh aGGFr2U26X7+H1FdgE3tFswtOvMraUWhBBcmJwD9Q1k9S6SlFIHz25oEy 4iFMH5vNOG60DKQlNc1DiBzw9Oi9qQvgDx7duYQSU1nQWzO8a4V4lE+05 vDEjoOF9RowQYaOZixrLul9JMSUeCk9qwbSaTUNFbdCPiLNl2joWbRgcB KlSV9LgkLrNDLzmn8PlNK4IORvX88XbnvvCIKaoJSq8WXqRXtP7PGwMq5 Q==; X-CSE-ConnectionGUID: PT6NJYJVSF6qGHp4sEnH4Q== X-CSE-MsgGUID: Ktoe5StSRgS7qdKTpskvUA== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="158186002" X-IronPort-AV: E=Sophos;i="6.09,273,1716217200"; d="scan'208";a="158186002" To: qemu-devel@nongnu.org, linux-cxl@vger.kernel.org, linux-edac@vger.kernel.org, linux-mm@kvack.org, dan.j.williams@intel.com, vishal.l.verma@intel.com, Jonathan.Cameron@huawei.com, alison.schofield@intel.com Cc: bp@alien8.de, dave.jiang@intel.com, dave@stgolabs.net, ira.weiny@intel.com, james.morse@arm.com, linmiaohe@huawei.com, mchehab@kernel.org, nao.horiguchi@gmail.com, rric@kernel.org, tony.luck@intel.com, ruansy.fnst@fujitsu.com Subject: [PATCH v4 1/2] cxl/core: introduce device reporting poison hanlding Date: Thu, 8 Aug 2024 23:13:27 +0800 Message-Id: <20240808151328.707869-2-ruansy.fnst@fujitsu.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240808151328.707869-1-ruansy.fnst@fujitsu.com> References: <20240808151328.707869-1-ruansy.fnst@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-TM-AS-Product-Ver: IMSS-9.1.0.1417-9.0.0.1002-28584.000 X-TM-AS-User-Approved-Sender: Yes X-TMASE-Version: IMSS-9.1.0.1417-9.0.1002-28584.000 X-TMASE-Result: 10--14.315400-10.000000 X-TMASE-MatchedRID: xXA8JSLb31sZHQl0dvECsQ0QY5VnQyAN9LMB0hXFSeinw6VQ+/MY/aJf gPmvd/XOfBnw4TEwb3JFUO4Lwe1qd/mi+iQw41eA/sUSFaCjTLw7x+Tuf7McDOjMOEZ5AL0SmRD Sh3pCEkOqbnUbIrDbhZdYXl3VkvoTqUUaBCb+VbHEOJqSsn5KmRYHLuVbwKXA33Nl3elSfsqyEH XzDCqxQcYS7GmsALUGD+giDHW5zvvQ9t8zINQJxDe9MF4SNA1+eF6MevMVZUDWeQtrcncLfegoS vaKsl/kIvrftAIhWmLy9zcRSkKatcOJmY4XRXkVyRfzRkrgkUH5UnqVnIHSzyxMw0FMkBlZLy7E GpbOGkod28lWFjU6v6bDnpxC0iz1mtdd6hGWj/x1e7Xbb6Im2resiCwR1MqZemnPKw9dcAo7/6w m+1WoGTE7bCG779IoSUJkKHLyNuXlFpsfMgM6DNyBRU/cKn690VvRkjCHhK6bKItl61J/yZ+inT K0bC9eKrauXd3MZDX+2MfnmxupmrdgHidVdLaElLjCcbrd1WCkN9kx8PZr3bjg6uqJ6r4l X-TMASE-SNAP-Result: 1.821001.0001-0-1-22:0,33:0,34:0-0 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=139.138.61.253; envelope-from=ruansy.fnst@fujitsu.com; helo=esa8.hc1455-7.c3s2.iphmx.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Shiyang Ruan From: Shiyang Ruan via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1723130047909116600 Content-Type: text/plain; charset="utf-8" CXL device can find&report memory problems, even before MCE is detected by CPU. AFAIK, the current kernel only traces POISON error event from FW-First/OS-First path, but it doesn't handle them, neither notify processes who are using the POISON page like MCE does. Thus, user have to read logs from trace and find out which device reported the error and which applications are affected. That is not an easy work and cannot be handled in time. Thus, it is needed to add the feature to make the work done automatically and quickly. Once CXL device reports the POISON error (via FW-First/OS-First), kernel handles it immediately, similar to the flow when a MCE is triggered. The current call trace of error reporting&handling looks like this: ``` 1. MCE (interrupt #18, while CPU consuming POISON) -> do_machine_check() -> mce_log() -> notify chain (x86_mce_decoder_chain) -> memory_failure() 2.a FW-First (optional, CXL device proactively find&report) -> CXL device -> Firmware -> OS: ACPI->APEI->GHES->CPER -> CXL driver -> trace \-> memory_failure() ^----- ADD 2.b OS-First (optional, CXL device proactively find&report) -> CXL device -> MSI -> OS: CXL driver -> trace \-> memory_failure() ^------------------------------- ADD ``` This patch adds calling memory_failure() while CXL device reporting error is received, marked as "ADD" in figure above. Signed-off-by: Shiyang Ruan --- drivers/cxl/core/mbox.c | 75 ++++++++++++++++++++++++++++++++------- drivers/cxl/cxlmem.h | 8 ++--- drivers/cxl/pci.c | 4 +-- include/linux/cxl-event.h | 16 ++++++++- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index e5cdeafdf76e..0cb6ef2e6600 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -849,10 +849,55 @@ int cxl_enumerate_cmds(struct cxl_memdev_state *mds) } EXPORT_SYMBOL_NS_GPL(cxl_enumerate_cmds, CXL); =20 -void cxl_event_trace_record(const struct cxl_memdev *cxlmd, - enum cxl_event_log_type type, - enum cxl_event_type event_type, - const uuid_t *uuid, union cxl_event *evt) +static void cxl_report_poison(struct cxl_memdev *cxlmd, u64 hpa) +{ + unsigned long pfn =3D PHYS_PFN(hpa); + + memory_failure_queue(pfn, 0); +} + +static void cxl_event_handle_general_media(struct cxl_memdev *cxlmd, + enum cxl_event_log_type type, + u64 hpa, + struct cxl_event_gen_media *rec) +{ + if (type =3D=3D CXL_EVENT_TYPE_FAIL) { + switch (rec->media_hdr.transaction_type) { + case CXL_EVENT_TRANSACTION_READ: + case CXL_EVENT_TRANSACTION_WRITE: + case CXL_EVENT_TRANSACTION_SCAN_MEDIA: + case CXL_EVENT_TRANSACTION_INJECT_POISON: + cxl_report_poison(cxlmd, hpa); + break; + default: + break; + } + } +} + +static void cxl_event_handle_dram(struct cxl_memdev *cxlmd, + enum cxl_event_log_type type, + u64 hpa, + struct cxl_event_dram *rec) +{ + if (type =3D=3D CXL_EVENT_TYPE_FAIL) { + switch (rec->media_hdr.transaction_type) { + case CXL_EVENT_TRANSACTION_READ: + case CXL_EVENT_TRANSACTION_WRITE: + case CXL_EVENT_TRANSACTION_SCAN_MEDIA: + case CXL_EVENT_TRANSACTION_INJECT_POISON: + cxl_report_poison(cxlmd, hpa); + break; + default: + break; + } + } +} + +void cxl_event_handle_record(struct cxl_memdev *cxlmd, + enum cxl_event_log_type type, + enum cxl_event_type event_type, + const uuid_t *uuid, union cxl_event *evt) { if (event_type =3D=3D CXL_CPER_EVENT_MEM_MODULE) { trace_cxl_memory_module(cxlmd, type, &evt->mem_module); @@ -880,18 +925,22 @@ void cxl_event_trace_record(const struct cxl_memdev *= cxlmd, if (cxlr) hpa =3D cxl_dpa_to_hpa(cxlr, cxlmd, dpa); =20 - if (event_type =3D=3D CXL_CPER_EVENT_GEN_MEDIA) + if (event_type =3D=3D CXL_CPER_EVENT_GEN_MEDIA) { trace_cxl_general_media(cxlmd, type, cxlr, hpa, &evt->gen_media); - else if (event_type =3D=3D CXL_CPER_EVENT_DRAM) + cxl_event_handle_general_media(cxlmd, type, hpa, + &evt->gen_media); + } else if (event_type =3D=3D CXL_CPER_EVENT_DRAM) { trace_cxl_dram(cxlmd, type, cxlr, hpa, &evt->dram); + cxl_event_handle_dram(cxlmd, type, hpa, &evt->dram); + } } } -EXPORT_SYMBOL_NS_GPL(cxl_event_trace_record, CXL); +EXPORT_SYMBOL_NS_GPL(cxl_event_handle_record, CXL); =20 -static void __cxl_event_trace_record(const struct cxl_memdev *cxlmd, - enum cxl_event_log_type type, - struct cxl_event_record_raw *record) +static void __cxl_event_handle_record(struct cxl_memdev *cxlmd, + enum cxl_event_log_type type, + struct cxl_event_record_raw *record) { enum cxl_event_type ev_type =3D CXL_CPER_EVENT_GENERIC; const uuid_t *uuid =3D &record->id; @@ -903,7 +952,7 @@ static void __cxl_event_trace_record(const struct cxl_m= emdev *cxlmd, else if (uuid_equal(uuid, &CXL_EVENT_MEM_MODULE_UUID)) ev_type =3D CXL_CPER_EVENT_MEM_MODULE; =20 - cxl_event_trace_record(cxlmd, type, ev_type, uuid, &record->event); + cxl_event_handle_record(cxlmd, type, ev_type, uuid, &record->event); } =20 static int cxl_clear_event_record(struct cxl_memdev_state *mds, @@ -1012,8 +1061,8 @@ static void cxl_mem_get_records_log(struct cxl_memdev= _state *mds, break; =20 for (i =3D 0; i < nr_rec; i++) - __cxl_event_trace_record(cxlmd, type, - &payload->records[i]); + __cxl_event_handle_record(cxlmd, type, + &payload->records[i]); =20 if (payload->flags & CXL_GET_EVENT_FLAG_OVERFLOW) trace_cxl_overflow(cxlmd, type, payload); diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index afb53d058d62..5c4810dcbdeb 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -826,10 +826,10 @@ void set_exclusive_cxl_commands(struct cxl_memdev_sta= te *mds, void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds); void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status); -void cxl_event_trace_record(const struct cxl_memdev *cxlmd, - enum cxl_event_log_type type, - enum cxl_event_type event_type, - const uuid_t *uuid, union cxl_event *evt); +void cxl_event_handle_record(struct cxl_memdev *cxlmd, + enum cxl_event_log_type type, + enum cxl_event_type event_type, + const uuid_t *uuid, union cxl_event *evt); int cxl_set_timestamp(struct cxl_memdev_state *mds); int cxl_poison_state_init(struct cxl_memdev_state *mds); int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len, diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 4be35dc22202..6e65ca89f666 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1029,8 +1029,8 @@ static void cxl_handle_cper_event(enum cxl_event_type= ev_type, hdr_flags =3D get_unaligned_le24(rec->event.generic.hdr.flags); log_type =3D FIELD_GET(CXL_EVENT_HDR_FLAGS_REC_SEVERITY, hdr_flags); =20 - cxl_event_trace_record(cxlds->cxlmd, log_type, ev_type, - &uuid_null, &rec->event); + cxl_event_handle_record(cxlds->cxlmd, log_type, ev_type, + &uuid_null, &rec->event); } =20 static void cxl_cper_work_fn(struct work_struct *work) diff --git a/include/linux/cxl-event.h b/include/linux/cxl-event.h index 0bea1afbd747..be4342a2b597 100644 --- a/include/linux/cxl-event.h +++ b/include/linux/cxl-event.h @@ -7,6 +7,20 @@ #include #include =20 +/* + * Event transaction type + * CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43 + */ +enum cxl_event_transaction_type { + CXL_EVENT_TRANSACTION_UNKNOWN =3D 0X00, + CXL_EVENT_TRANSACTION_READ, + CXL_EVENT_TRANSACTION_WRITE, + CXL_EVENT_TRANSACTION_SCAN_MEDIA, + CXL_EVENT_TRANSACTION_INJECT_POISON, + CXL_EVENT_TRANSACTION_MEDIA_SCRUB, + CXL_EVENT_TRANSACTION_MEDIA_MANAGEMENT, +}; + /* * Common Event Record Format * CXL rev 3.0 section 8.2.9.2.1; Table 8-42 @@ -26,7 +40,7 @@ struct cxl_event_media_hdr { __le64 phys_addr; u8 descriptor; u8 type; - u8 transaction_type; + u8 transaction_type; /* enum cxl_event_transaction_type */ /* * The meaning of Validity Flags from bit 2 is * different across DRAM and General Media records --=20 2.34.1 From nobody Sun Nov 24 10:50:08 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@fujitsu.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1723130067; cv=none; d=zohomail.com; s=zohoarc; b=Og42ITmBh0OYoh6LwMzdCt+WqevT8zsqIlgDqnLH8cDXYZRjufVvJviRQAUoxEkwjrvx6WbNVO9ey0R5/kmlMhPulJSdG0QH7m+o1sSjrhLYS1S+cWMMJb8txqP/e7XBP0P+oyPVUgD/8bmDgXdzGAFuqSSXuVMJTJegN9f8GJQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1723130067; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=v14/iHD72wpMklXcfm9tv3/7i6uAtVHzhlpwqpzLSD4=; b=HaaesUDkSzqY1bzX8pcFHmNqx0Vph5yyvx1zTvy5brUSW59jcTbEyq4cNgzHDORwgYa+hgofCrNxOfG/CCKLSxkdTs8OBErAZLduqFeer2CrfYEo4hoRzgfE0CyCfVUONYUiPHx4BmMKUr+xrS7dWm6RbltKtWV1zBQ5qkpATYc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@fujitsu.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1723130067162292.42653455552977; Thu, 8 Aug 2024 08:14:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sc4pm-0007Wu-Ei; Thu, 08 Aug 2024 11:13:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sc4pj-0007SA-Fy for qemu-devel@nongnu.org; Thu, 08 Aug 2024 11:13:44 -0400 Received: from esa7.hc1455-7.c3s2.iphmx.com ([139.138.61.252]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sc4ph-0003aC-Ec for qemu-devel@nongnu.org; Thu, 08 Aug 2024 11:13:43 -0400 Received: from unknown (HELO yto-r1.gw.nic.fujitsu.com) ([218.44.52.217]) by esa7.hc1455-7.c3s2.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Aug 2024 00:13:35 +0900 Received: from yto-m4.gw.nic.fujitsu.com (yto-nat-yto-m4.gw.nic.fujitsu.com [192.168.83.67]) by yto-r1.gw.nic.fujitsu.com (Postfix) with ESMTP id 79834D9041 for ; Fri, 9 Aug 2024 00:13:33 +0900 (JST) Received: from kws-ab4.gw.nic.fujitsu.com (kws-ab4.gw.nic.fujitsu.com [192.51.206.22]) by yto-m4.gw.nic.fujitsu.com (Postfix) with ESMTP id BA6F3D3F20 for ; Fri, 9 Aug 2024 00:13:32 +0900 (JST) Received: from edo.cn.fujitsu.com (edo.cn.fujitsu.com [10.167.33.5]) by kws-ab4.gw.nic.fujitsu.com (Postfix) with ESMTP id 2C81F229368 for ; Fri, 9 Aug 2024 00:13:32 +0900 (JST) Received: from irides.g08.fujitsu.local (unknown [10.167.226.114]) by edo.cn.fujitsu.com (Postfix) with ESMTP id 4D8B81A000A; Thu, 8 Aug 2024 23:13:31 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=fujitsu.com; i=@fujitsu.com; q=dns/txt; s=fj2; t=1723130021; x=1754666021; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V+txiutig01/lSTX5GU2xXQ/Ecok4xMPvtbSdLTFmbo=; b=VX6cGIvwEM+/7r3I4woMezNTdLGCLlr956v/q0fYgXB6Tw0yOaRgZEdg keywRUx7OwhsqfrV93eL1Xk1X3JXXbWkqJriIHWvUEqEYpgZ2QJuvRXpl DWzRwQuL7vpCORN6xpQmN9f5gtfjvIrq2n+rc5+lcIccz3CRUf7NhX3B0 CAs1O/USddcqNUCYzkkVfpn7bMtopWIdfUy0SGnZECQzp49Z8rZtuWxhD HPt0PmLr/KMrhoZPF7w9rbz27ErnNtSj6ZnR2U6dT0qmqz/S+E/QSSQ+o jelotvRPXS2mKbnDKqxv4adwTMxKVUTk8aFv29hDXcWrUl0cXUfftzbDm A==; X-CSE-ConnectionGUID: ilYVxy5FRACsZ9iQlYsFbg== X-CSE-MsgGUID: im06xqi4SACZSi97ETaLnQ== X-IronPort-AV: E=McAfee;i="6700,10204,11158"; a="149069156" X-IronPort-AV: E=Sophos;i="6.09,273,1716217200"; d="scan'208";a="149069156" To: qemu-devel@nongnu.org, linux-cxl@vger.kernel.org, linux-edac@vger.kernel.org, linux-mm@kvack.org, dan.j.williams@intel.com, vishal.l.verma@intel.com, Jonathan.Cameron@huawei.com, alison.schofield@intel.com Cc: bp@alien8.de, dave.jiang@intel.com, dave@stgolabs.net, ira.weiny@intel.com, james.morse@arm.com, linmiaohe@huawei.com, mchehab@kernel.org, nao.horiguchi@gmail.com, rric@kernel.org, tony.luck@intel.com, ruansy.fnst@fujitsu.com Subject: [PATCH v4 2/2] cxl: avoid duplicated report from MCE & device Date: Thu, 8 Aug 2024 23:13:28 +0800 Message-Id: <20240808151328.707869-3-ruansy.fnst@fujitsu.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240808151328.707869-1-ruansy.fnst@fujitsu.com> References: <20240808151328.707869-1-ruansy.fnst@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-TM-AS-Product-Ver: IMSS-9.1.0.1417-9.0.0.1002-28584.000 X-TM-AS-User-Approved-Sender: Yes X-TMASE-Version: IMSS-9.1.0.1417-9.0.1002-28584.000 X-TMASE-Result: 10--16.139300-10.000000 X-TMASE-MatchedRID: mBR/8PU27l8ZHQl0dvECsazGfgakLdjaKQNhMboqZlpqrsOvUFEKy3kY O/9k4Xg2bn+bq+W8j6XQJxNDXN5QxO4rOj+PdZuMVnzlQiaE21qxXA8wqNmbVrwYtb0g7Ywtu0m nSBAOWht+3E64qYVhyfoS5B31PW6f3tF9vYxzQ43wgrvJFY9E0Vvh1cEykiSGLX3qyf3ewG+qbv 7m/AcFJSbOYzaQt2Phra3G1NjT5m2njNSDi/vkV02xVQmDwU6mCZa9cSpBObnAuQ0xDMaXkH4qt YI9sRE/4K9FmervsqWylFSPywhifTBF72xzhJLNyRfzRkrgkUHzWEMQjooUzbs3Yh2IOCYz/svd Vly7w9ldRSgb+5TWboftADTYJ316uybvDkIalGDHyCtnYFmFhoIw3bnTjwR6icvz9DxarMGk86u MB98iNvBn25uFP/vzYcMGA+vBhspccQ8eam5EfRRFJJyf5BJe3QfwsVk0UbslCGssfkpInQ== X-TMASE-SNAP-Result: 1.821001.0001-0-1-22:0,33:0,34:0-0 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=139.138.61.252; envelope-from=ruansy.fnst@fujitsu.com; helo=esa7.hc1455-7.c3s2.iphmx.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Shiyang Ruan From: Shiyang Ruan via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1723130067964116600 Content-Type: text/plain; charset="utf-8" Since CXL device is a memory device, while CPU is consuming a poison page of CXL device, it always triggers a MCE (via interrupt #18) and calls memory_failure() to handle POISON page, no matter which-First path is configured. CXL device could also find and report the POISON, kernel now not only traces but also calls memory_failure() to handle it, which is marked as "NEW" in the figure blow. ``` 1. MCE (interrupt #18, while CPU consuming POISON) -> do_machine_check() -> mce_log() -> notify chain (x86_mce_decoder_chain) -> memory_failure() <---------------------------- EXISTS 2.a FW-First (optional, CXL device proactively find&report) -> CXL device -> Firmware -> OS: ACPI->APEI->GHES->CPER -> CXL driver -> trace \-> memory_failure() ^----- NEW 2.b OS-First (optional, CXL device proactively find&report) -> CXL device -> MSI -> OS: CXL driver -> trace \-> memory_failure() ^------------------------------- NEW ``` But in this way, the memory_failure() could be called twice or even at same time, as is shown in the figure above: (1.) and (2.a or 2.b), before the POISON page is cleared. memory_failure() has it own mutex lock so it actually won't be called at same time and the later call could be avoided because HWPoison bit has been set. However, assume such a scenario, "CXL device reports POISON error" triggers 1st call, user see it from log and want to clear the poison by executing `cxl clear-poison` command, and at the same time, a process tries to access this POISON page, which triggers MCE (it's the 2nd call). Since there is no lock between the 2nd call with clearing poison operation, race condition may happen, which may cause HWPoison bit of the page in an unknown state. Thus, we have to avoid the 2nd call. This patch[2] introduces a new notifier_block into `x86_mce_decoder_chain` and a POISON cache list, to stop the 2nd call of memory_failure(). It checks whether the current poison page has been reported (if yes, stop the notifier chain, don't call the following memory_failure() to report again). Signed-off-by: Shiyang Ruan --- arch/x86/include/asm/mce.h | 1 + drivers/cxl/core/mbox.c | 115 +++++++++++++++++++++++++++++++++++++ drivers/cxl/core/memdev.c | 6 +- drivers/cxl/cxlmem.h | 3 + 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 3ad29b128943..5da45e870858 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -182,6 +182,7 @@ enum mce_notifier_prios { MCE_PRIO_NFIT, MCE_PRIO_EXTLOG, MCE_PRIO_UC, + MCE_PRIO_CXL, MCE_PRIO_EARLY, MCE_PRIO_CEC, MCE_PRIO_HIGHEST =3D MCE_PRIO_CEC diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index 0cb6ef2e6600..b21700428c35 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -925,6 +927,9 @@ void cxl_event_handle_record(struct cxl_memdev *cxlmd, if (cxlr) hpa =3D cxl_dpa_to_hpa(cxlr, cxlmd, dpa); =20 + if (hpa !=3D ULLONG_MAX && cxl_mce_recorded(hpa)) + return; + if (event_type =3D=3D CXL_CPER_EVENT_GEN_MEDIA) { trace_cxl_general_media(cxlmd, type, cxlr, hpa, &evt->gen_media); @@ -1457,6 +1462,112 @@ int cxl_poison_state_init(struct cxl_memdev_state *= mds) } EXPORT_SYMBOL_NS_GPL(cxl_poison_state_init, CXL); =20 +DEFINE_XARRAY(cxl_mce_records); + +bool cxl_mce_recorded(u64 hpa) +{ + XA_STATE(xas, &cxl_mce_records, hpa); + void *entry; + + xas_lock_irq(&xas); + entry =3D xas_load(&xas); + if (entry) { + xas_unlock_irq(&xas); + return true; + } + entry =3D xa_mk_value(hpa); + xas_store(&xas, entry); + xas_unlock_irq(&xas); + + return false; +} +EXPORT_SYMBOL_NS_GPL(cxl_mce_recorded, CXL); + +void cxl_mce_clear(u64 hpa) +{ + XA_STATE(xas, &cxl_mce_records, hpa); + void *entry; + + xas_lock_irq(&xas); + entry =3D xas_load(&xas); + if (entry) { + xas_store(&xas, NULL); + } + xas_unlock_irq(&xas); +} +EXPORT_SYMBOL_NS_GPL(cxl_mce_clear, CXL); + +struct cxl_contains_hpa_context { + bool contains; + u64 hpa; +}; + +static int __cxl_contains_hpa(struct device *dev, void *arg) +{ + struct cxl_contains_hpa_context *ctx =3D arg; + struct cxl_endpoint_decoder *cxled; + struct range *range; + u64 hpa =3D ctx->hpa; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxled =3D to_cxl_endpoint_decoder(dev); + range =3D &cxled->cxld.hpa_range; + + if (range->start <=3D hpa && hpa <=3D range->end) { + ctx->contains =3D true; + return 1; + } + + return 0; +} + +static bool cxl_contains_hpa(const struct cxl_memdev *cxlmd, u64 hpa) +{ + struct cxl_contains_hpa_context ctx =3D { + .contains =3D false, + .hpa =3D hpa, + }; + struct cxl_port *port; + + port =3D cxlmd->endpoint; + guard(rwsem_write)(&cxl_region_rwsem); + if (port && cxl_num_decoders_committed(port)) + device_for_each_child(&port->dev, &ctx, __cxl_contains_hpa); + + return ctx.contains; +} + +static int cxl_handle_mce(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct mce *mce =3D (struct mce *)data; + struct cxl_memdev_state *mds =3D container_of(nb, struct cxl_memdev_state, + mce_notifier); + u64 hpa; + + if (!mce || !mce_usable_address(mce)) + return NOTIFY_DONE; + + hpa =3D mce->addr & MCI_ADDR_PHYSADDR; + + /* Check if the PFN is located on this CXL device */ + if (!pfn_valid(hpa >> PAGE_SHIFT) && + !cxl_contains_hpa(mds->cxlds.cxlmd, hpa)) + return NOTIFY_DONE; + + /* + * Search PFN in the cxl_mce_records, if already exists, don't continue + * to do memory_failure() to avoid a poison address being reported + * more than once. + */ + if (cxl_mce_recorded(hpa)) + return NOTIFY_STOP; + else + return NOTIFY_OK; +} + struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev) { struct cxl_memdev_state *mds; @@ -1476,6 +1587,10 @@ struct cxl_memdev_state *cxl_memdev_state_create(str= uct device *dev) mds->ram_perf.qos_class =3D CXL_QOS_CLASS_INVALID; mds->pmem_perf.qos_class =3D CXL_QOS_CLASS_INVALID; =20 + mds->mce_notifier.notifier_call =3D cxl_handle_mce; + mds->mce_notifier.priority =3D MCE_PRIO_CXL; + mce_register_decode_chain(&mds->mce_notifier); + return mds; } EXPORT_SYMBOL_NS_GPL(cxl_memdev_state_create, CXL); diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 0277726afd04..9d4ed4dc4d51 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -376,10 +376,14 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dp= a) goto out; =20 cxlr =3D cxl_dpa_to_region(cxlmd, dpa); - if (cxlr) + if (cxlr) { + u64 hpa =3D cxl_dpa_to_hpa(cxlr, cxlmd, dpa); + + cxl_mce_clear(hpa); dev_warn_once(mds->cxlds.dev, "poison clear dpa:%#llx region: %s\n", dpa, dev_name(&cxlr->dev)); + } =20 record =3D (struct cxl_poison_record) { .address =3D cpu_to_le64(dpa), diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 5c4810dcbdeb..d2d906c26755 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -502,6 +502,7 @@ struct cxl_memdev_state { struct cxl_fw_state fw; =20 struct rcuwait mbox_wait; + struct notifier_block mce_notifier; int (*mbox_send)(struct cxl_memdev_state *mds, struct cxl_mbox_cmd *cmd); }; @@ -837,6 +838,8 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 of= fset, u64 len, int cxl_trigger_poison_list(struct cxl_memdev *cxlmd); int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa); int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa); +bool cxl_mce_recorded(u64 pfn); +void cxl_mce_clear(u64 pfn); =20 #ifdef CONFIG_CXL_SUSPEND void cxl_mem_active_inc(void); --=20 2.34.1