From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62121C4332F for ; Thu, 20 Oct 2022 20:05:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7B0CE8E0002; Thu, 20 Oct 2022 16:05:55 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 73A428E0001; Thu, 20 Oct 2022 16:05:55 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 601E68E0002; Thu, 20 Oct 2022 16:05:55 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 4CDE88E0001 for ; Thu, 20 Oct 2022 16:05:55 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id E39DC811A2 for ; Thu, 20 Oct 2022 20:05:54 +0000 (UTC) X-FDA: 80042408628.08.D14945B Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by imf22.hostedemail.com (Postfix) with ESMTP id 5BB50C0032 for ; Thu, 20 Oct 2022 20:05:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666296353; x=1697832353; h=date:from:to:cc:subject:message-id:references: mime-version:content-transfer-encoding:in-reply-to; bh=Df31rUtnrw/F7hIheI4Cx6bl73pYnzh4BvNXaOx9ZRU=; b=H54px6pPI3uKO8gq3lror4UPEIM7//uNpNSN9vHXL94Y65YhZWB52Jn1 JJVpVbJY7L/M65CBtuqXuq0TOQaKN/Xipt47ocdofgkAhz/S44OA4YzpV QFSDiDzikTnBYUFS+lgHgR0Uqla1mRJFyBRvLPpLam7sY9E51R57AYwJq VfF+EaJH6gRMzh926vSE+WlW86wfPtRzTkB3HS1XpJDP7D6mG7wYnf8jE wzzWR/MFD78yT8l5Ze0r4p3A4CGCqhCDKSXKCdo67TVgNCytoSN+dq1lo ZC/iOhoxmDZoW0n2I2KIaYFZxl+0PQtOI4SX66Gygcb+PjZQsx84DiCJI w==; X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="371039168" X-IronPort-AV: E=Sophos;i="5.95,199,1661842800"; d="scan'208";a="371039168" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Oct 2022 13:05:47 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10506"; a="632471154" X-IronPort-AV: E=Sophos;i="5.95,199,1661842800"; d="scan'208";a="632471154" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Oct 2022 13:05:46 -0700 Date: Thu, 20 Oct 2022 13:05:45 -0700 From: Tony Luck To: Shuai Xue Cc: Naoya Horiguchi , Andrew Morton , Miaohe Lin , Matthew Wilcox , Dan Williams , Michael Ellerman , Nicholas Piggin , Christophe Leroy , linux-mm@kvack.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: Re: [PATCH v2] mm, hwpoison: Try to recover from copy-on write faults Message-ID: References: <20221019170835.155381-1-tony.luck@intel.com> <893b681b-726e-94e3-441e-4d68c767778a@linux.alibaba.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <893b681b-726e-94e3-441e-4d68c767778a@linux.alibaba.com> ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1666296353; a=rsa-sha256; cv=none; b=yjnKwwEuQ5DDGLctnm7l9AWCj/DxYkMAXmWFutw2b4QPUSEtHWMYRHelbvqw/2/vXhPBhk OsUDp0OsBXGinS+fgaimJWDyFYGrQCajDBzchrghM8YGcFQNfdzfkYVAjA1+UQjem4UCBP vMRJYZlY2wxUNSRAUeD/RrUypYROcS4= ARC-Authentication-Results: i=1; imf22.hostedemail.com; dkim=none ("invalid DKIM record") header.d=intel.com header.s=Intel header.b=H54px6pP; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf22.hostedemail.com: domain of tony.luck@intel.com designates 134.134.136.100 as permitted sender) smtp.mailfrom=tony.luck@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1666296353; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=uwOsBt/Cv/On632715Liw0i7JvhM7EVPJY6xwmA5grA=; b=s5C9xK/QAPgt01p2m7qnUsyqIZN9v7iLFK/q8riaKBLF3NFynN2cDLdmY9QnHAF4htSIud 8HesuJ5uFmWrz4cAonVSh0+DHsiJMgvkS3OuKoLpZid1Ky6+y24MFIqxv2VAnn42HseVCM xvc0Waf3PtRelHoxRxVkOxHcoVRV7iU= Authentication-Results: imf22.hostedemail.com; dkim=none ("invalid DKIM record") header.d=intel.com header.s=Intel header.b=H54px6pP; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf22.hostedemail.com: domain of tony.luck@intel.com designates 134.134.136.100 as permitted sender) smtp.mailfrom=tony.luck@intel.com X-Rspamd-Server: rspam04 X-Rspam-User: X-Stat-Signature: j5kdbqyhwnaimniai3zqaear9cgnnshx X-Rspamd-Queue-Id: 5BB50C0032 X-HE-Tag: 1666296353-438432 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Thu, Oct 20, 2022 at 09:57:04AM +0800, Shuai Xue wrote: > > > 在 2022/10/20 AM1:08, Tony Luck 写道: > > If the kernel is copying a page as the result of a copy-on-write > > fault and runs into an uncorrectable error, Linux will crash because > > it does not have recovery code for this case where poison is consumed > > by the kernel. > > > > It is easy to set up a test case. Just inject an error into a private > > page, fork(2), and have the child process write to the page. > > > > I wrapped that neatly into a test at: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/aegl/ras-tools.git > > > > just enable ACPI error injection and run: > > > > # ./einj_mem-uc -f copy-on-write > > > > Add a new copy_user_highpage_mc() function that uses copy_mc_to_kernel() > > on architectures where that is available (currently x86 and powerpc). > > When an error is detected during the page copy, return VM_FAULT_HWPOISON > > to caller of wp_page_copy(). This propagates up the call stack. Both x86 > > and powerpc have code in their fault handler to deal with this code by > > sending a SIGBUS to the application. > > Does it send SIGBUS to only child process or both parent and child process? This only sends a SIGBUS to the process that wrote the page (typically the child, but also possible that the parent is the one that does the write that causes the COW). > > > > Note that this patch avoids a system crash and signals the process that > > triggered the copy-on-write action. It does not take any action for the > > memory error that is still in the shared page. To handle that a call to > > memory_failure() is needed. > > If the error page is not poisoned, should the return value of wp_page_copy > be VM_FAULT_HWPOISON or VM_FAULT_SIGBUS? When is_hwpoison_entry(entry) or > PageHWPoison(page) is true, do_swap_page return VM_FAULT_HWPOISON to caller. > And when is_swapin_error_entry is true, do_swap_page return VM_FAULT_SIGBUS. The page has uncorrected data in it, but this patch doesn't mark it as poisoned. Returning VM_FAULT_SIGBUS would send an "ordinary" SIGBUS that doesn't include the BUS_MCEERR_AR and "lsb" information. It would also skip the: "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n" console message. So might result in confusion and attepmts to debug a s/w problem with the application instead of blaming the death on a bad DIMM. > > But this cannot be done from wp_page_copy() > > because it holds mmap_lock(). Perhaps the architecture fault handlers > > can deal with this loose end in a subsequent patch? I started looking at this for x86 ... but I have changed my mind about this being a good place for a fix. When control returns back to the architecture fault handler it no longer has easy access to the physical page frame number. It has the virtual address, so it could descend back into somee new mm/memory.c function to get the physical address ... but that seems silly. I'm experimenting with using sched_work() to handle the call to memory_failure() (echoing what the machine check handler does using task_work)_add() to avoid the same problem of not being able to directly call memory_failure()). So far it seems to be working. Patch below (goes on top of original patch ... well on top of the internal version with mods based on feedback from Dan Williams ... but should show the general idea) With this patch applied the page does get unmapped from all users. Other tasks that shared the page will get a SIGBUS if they attempt to access it later (from the page fault handler because of is_hwpoison_entry() as you mention above. -Tony >From d3879e83bf91cd6c61e12d32d3e15eb6ef069204 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 20 Oct 2022 09:57:28 -0700 Subject: [PATCH] mm, hwpoison: Call memory_failure() for source page of COW failure Cannot call memory_failure() directly from the fault handler because mmap_lock (and others) are held. It is important, but not urgent, to mark the source page as h/w poisoned and unmap it from other tasks. Use schedule_work() to queue a request to call memory_failure() for the page with the error. Signed-off-by: Tony Luck --- mm/memory.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index b6056eef2f72..4a1304cf1f4e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2848,6 +2848,37 @@ static inline int pte_unmap_same(struct vm_fault *vmf) return same; } +#ifdef CONFIG_MEMORY_FAILURE +struct pfn_work { + struct work_struct work; + unsigned long pfn; +}; + +static void do_sched_memory_failure(struct work_struct *w) +{ + struct pfn_work *p = container_of(w, struct pfn_work, work); + + memory_failure(p->pfn, 0); + kfree(p); +} + +static void sched_memory_failure(unsigned long pfn) +{ + struct pfn_work *p; + + p = kmalloc(sizeof *p, GFP_KERNEL); + if (!p) + return; + INIT_WORK(&p->work, do_sched_memory_failure); + p->pfn = pfn; + schedule_work(&p->work); +} +#else +static void sched_memory_failure(unsigned long pfn) +{ +} +#endif + /* * Return: * 0: copied succeeded @@ -2866,8 +2897,10 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src, unsigned long addr = vmf->address; if (likely(src)) { - if (copy_mc_user_highpage(dst, src, addr, vma)) + if (copy_mc_user_highpage(dst, src, addr, vma)) { + sched_memory_failure(page_to_pfn(src)); return -EHWPOISON; + } return 0; } -- 2.37.3