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 953ECC77B76 for ; Fri, 14 Apr 2023 02:18:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 69C48900002; Thu, 13 Apr 2023 22:18:37 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 64A4D6B007D; Thu, 13 Apr 2023 22:18:37 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 51524900002; Thu, 13 Apr 2023 22:18:37 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 3F07A6B007B for ; Thu, 13 Apr 2023 22:18:37 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 14A671404F6 for ; Fri, 14 Apr 2023 02:18:37 +0000 (UTC) X-FDA: 80678387874.26.AEB5365 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by imf30.hostedemail.com (Postfix) with ESMTP id 952C18000B for ; Fri, 14 Apr 2023 02:18:33 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=none; spf=pass (imf30.hostedemail.com: domain of xialonglong1@huawei.com designates 45.249.212.255 as permitted sender) smtp.mailfrom=xialonglong1@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1681438714; a=rsa-sha256; cv=none; b=4DKXyW5QtEPjv2IlrNIk2U1fVj1wPhVQ7TEBm+bGafEZVu0Js2rXiV9P3sY+EXtcAYlfpF iXkg4v2PY6rL8ZIa6/L3c3rp2fp1IGS7+O0R63xiR7A2g1EZ/8u5XGv1iwo7CVjL8zSnac ALXZ7vVlptcpnFGQNJIREbopHehaOQk= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=none; spf=pass (imf30.hostedemail.com: domain of xialonglong1@huawei.com designates 45.249.212.255 as permitted sender) smtp.mailfrom=xialonglong1@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1681438714; 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; bh=ixXgyMfIwsGfhRqi+NWO9W7O2UBLdkRkicRUz917zA0=; b=hxvpKwN6cI/hM40N7ylYnWdQLqMxOy91WNN+WpX7iHjP89wpu89XZOqNEZlJWMus4BrjTl Y58HNYQli5RjiMb0hCJ1qpLW/xVDZWtaEN0LCh2VtIqIJ5mPF8W36tbpduc8sXVKrPrbiE IuoJurmUdgqDVfuJB9bhdts7dKeCXMs= Received: from kwepemm600003.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4PyKld0Nf2z17SXm; Fri, 14 Apr 2023 10:14:53 +0800 (CST) Received: from localhost.localdomain (10.175.112.125) by kwepemm600003.china.huawei.com (7.193.23.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.23; Fri, 14 Apr 2023 10:18:28 +0800 From: Longlong Xia To: , CC: , , , , , Longlong Xia Subject: [PATCH v2 2/2] mm: ksm: Support hwpoison for ksm page Date: Fri, 14 Apr 2023 10:17:41 +0800 Message-ID: <20230414021741.2597273-3-xialonglong1@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230414021741.2597273-1-xialonglong1@huawei.com> References: <20230414021741.2597273-1-xialonglong1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.175.112.125] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemm600003.china.huawei.com (7.193.23.202) X-CFilter-Loop: Reflected X-Rspam-User: X-Rspamd-Queue-Id: 952C18000B X-Rspamd-Server: rspam01 X-Stat-Signature: q1bf3jurmydpo3hiwfcdqbs7h1gte69i X-HE-Tag: 1681438713-259828 X-HE-Meta: U2FsdGVkX1+HXjoIStgg6+ibm2zKY+riew7+tC2FaSIeXakNJLfv7sNZrHyDYRsDSojMsjhSfJNi7vdq47Op98WO2xu+1CSRx1L6arLDpXkK4m7bwoXPUo9iJjE7wcttSUDlaQhCXwGJ0sxuET9NOQXhvsSzGAV+awoM9ykFPLssVLjh4uX8EUyAiH/3KXtESVcJFCTVpCuKSCWPQeIPrnLQ4kCsYd5D8wvNqVH12d0ATIyRue3Ov7KmB5xrprXyV+belQRBm5Q4w1ELbVek0NpLRMW6c16o4k6oA6aozpuh/uWxmU2Q3SjlcO/SQkhVnU3ZHa9D9mSd/mAPVL9d9dDeoVwo7XdrgBIMMgfU89vmx1jJ3Tzb13MP4idZPP/C7xWl6y2sQKYGMCXvEPUQLYUky/PxmsDXeO4Xo965j2fB04BrWd1vKgIPAakKT0eDwRgs7Okp0ekrilZpFTMurWqhHaUqjwoPbdCLYM/78lckBBtHG/jN8Rh2xNWyKZRAUqL768thxyxcJfO90UhASQyq4azVUaMsO9KDybF9tMXmxYxIcdi9qBRKvNBwO5o9MADwwYO2aGbE9bUHJmEitjlb90ztuQloLHFtU215M50wc4KiyqHUmLm3CM57HRM8II3RGdWZdCIKYakK/JGhy8ShNjLeZC8hL98CU8Td+vZPj/FNdPBtpmUuhYeyZG4U4HFRDmcCW9xBz4AjsVINzwauFg6iJo9/RtaKI2vmnV5eMFfIzD2Vyl9YK18vMypu7o1NkaiBCcc1WuSjxG2o0okCITph67rGAlxuvjYzsMvSDMkLIKzRTyBIF9k24SzdKZ8qHL5Eq4r+ow4Q76bVmmgsqFMn+0dbUyl5ywppc2aLYf0DKl7BQRBYLH6grb+rLZ206qxEY4OUBx86oreZMcy7/ncWlfNDuceBXBpbobphooi6zUcnCs2hrYOvcMJumu3J/BQXc10vyfZO3Wu RdYiiULL UTneEZCzdFETxMEeJXrQGcp85rD2p7o83+wv7L63NwMBhdXQR4NxtS+6j2Rlxm2mJvvEUSFnWEduqJ4dEaQaXBmHf89F78J5L34zwq8II7d5RgHgmT6koefjqZG/I1B7UV1/b4zeD91QuZKGj+eOxSd1BPeYwAQe6znXoDN8q5xZdY8mydu50jbjBPA== 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: hwpoison_user_mappings() is updated to support ksm pages, and add collect_procs_ksm() to collect processes when the error hit an ksm page. The difference from collect_procs_anon() is that it also needs to traverse the rmap-item list on the stable node of the ksm page. At the same time, add_to_kill_ksm() is added to handle ksm pages. And task_in_to_kill_list() is added to avoid duplicate addition of tsk to the to_kill list. This is because when scanning the list, if the pages that make up the ksm page all come from the same process, they may be added repeatedly. Signed-off-by: Longlong Xia Tested-by: Naoya Horiguchi Reviewed-by: Kefeng Wang --- include/linux/ksm.h | 11 +++++++++++ include/linux/mm.h | 7 +++++++ mm/ksm.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ mm/memory-failure.c | 34 +++++++++++++++++++++++++--------- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/include/linux/ksm.h b/include/linux/ksm.h index 7e232ba59b865..d9e701326a882 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h @@ -51,6 +51,10 @@ struct page *ksm_might_need_to_copy(struct page *page, void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc); void folio_migrate_ksm(struct folio *newfolio, struct folio *folio); +#ifdef CONFIG_MEMORY_FAILURE +void collect_procs_ksm(struct page *page, struct list_head *to_kill, + int force_early); +#endif #else /* !CONFIG_KSM */ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm) @@ -62,6 +66,13 @@ static inline void ksm_exit(struct mm_struct *mm) { } +#ifdef CONFIG_MEMORY_FAILURE +static inline void collect_procs_ksm(struct page *page, + struct list_head *to_kill, int force_early) +{ +} +#endif + #ifdef CONFIG_MMU static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, unsigned long end, int advice, unsigned long *vm_flags) diff --git a/include/linux/mm.h b/include/linux/mm.h index 1f79667824eb6..342c0d1c31f92 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3453,6 +3453,7 @@ extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags, bool *migratable_cleared); void num_poisoned_pages_inc(unsigned long pfn); void num_poisoned_pages_sub(unsigned long pfn, long i); +struct task_struct *task_early_kill(struct task_struct *tsk, int force_early); #else static inline void memory_failure_queue(unsigned long pfn, int flags) { @@ -3473,6 +3474,12 @@ static inline void num_poisoned_pages_sub(unsigned long pfn, long i) } #endif +#if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_KSM) +void add_to_kill_ksm(struct task_struct *tsk, struct page *p, + struct vm_area_struct *vma, struct list_head *to_kill, + unsigned long ksm_addr); +#endif + #if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_MEMORY_HOTPLUG) extern void memblk_nr_poison_inc(unsigned long pfn); extern void memblk_nr_poison_sub(unsigned long pfn, long i); diff --git a/mm/ksm.c b/mm/ksm.c index 2b8d30068cbbd..29e4be80b6c57 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -2721,6 +2721,51 @@ void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc) goto again; } +#ifdef CONFIG_MEMORY_FAILURE +/* + * Collect processes when the error hit an ksm page. + */ +void collect_procs_ksm(struct page *page, struct list_head *to_kill, + int force_early) +{ + struct ksm_stable_node *stable_node; + struct ksm_rmap_item *rmap_item; + struct folio *folio = page_folio(page); + struct vm_area_struct *vma; + struct task_struct *tsk; + + stable_node = folio_stable_node(folio); + if (!stable_node) + return; + hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) { + struct anon_vma *av = rmap_item->anon_vma; + + anon_vma_lock_read(av); + read_lock(&tasklist_lock); + for_each_process(tsk) { + struct anon_vma_chain *vmac; + unsigned long addr; + struct task_struct *t = + task_early_kill(tsk, force_early); + if (!t) + continue; + anon_vma_interval_tree_foreach(vmac, &av->rb_root, 0, + ULONG_MAX) + { + vma = vmac->vma; + if (vma->vm_mm == t->mm) { + addr = rmap_item->address & PAGE_MASK; + add_to_kill_ksm(t, page, vma, to_kill, + addr); + } + } + } + read_unlock(&tasklist_lock); + anon_vma_unlock_read(av); + } +} +#endif + #ifdef CONFIG_MIGRATION void folio_migrate_ksm(struct folio *newfolio, struct folio *folio) { diff --git a/mm/memory-failure.c b/mm/memory-failure.c index f5e1d80a82738..6ed97e78b5b8a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -455,6 +455,27 @@ static void add_to_kill_anon_file(struct task_struct *tsk, struct page *p, __add_to_kill(tsk, p, vma, to_kill, 0, FSDAX_INVALID_PGOFF); } +#ifdef CONFIG_KSM +static bool task_in_to_kill_list(struct list_head *to_kill, + struct task_struct *tsk) +{ + struct to_kill *tk, *next; + + list_for_each_entry_safe(tk, next, to_kill, nd) { + if (tk->tsk == tsk) + return true; + } + + return false; +} +void add_to_kill_ksm(struct task_struct *tsk, struct page *p, + struct vm_area_struct *vma, struct list_head *to_kill, + unsigned long ksm_addr) +{ + if (!task_in_to_kill_list(to_kill, tsk)) + __add_to_kill(tsk, p, vma, to_kill, ksm_addr, FSDAX_INVALID_PGOFF); +} +#endif /* * Kill the processes that have been collected earlier. * @@ -534,8 +555,7 @@ static struct task_struct *find_early_kill_thread(struct task_struct *tsk) * processes sharing the same error page,if the process is "early kill", the * task_struct of the dedicated thread will also be returned. */ -static struct task_struct *task_early_kill(struct task_struct *tsk, - int force_early) +struct task_struct *task_early_kill(struct task_struct *tsk, int force_early) { if (!tsk->mm) return NULL; @@ -666,8 +686,9 @@ static void collect_procs(struct page *page, struct list_head *tokill, { if (!page->mapping) return; - - if (PageAnon(page)) + if (unlikely(PageKsm(page))) + collect_procs_ksm(page, tokill, force_early); + else if (PageAnon(page)) collect_procs_anon(page, tokill, force_early); else collect_procs_file(page, tokill, force_early); @@ -1522,11 +1543,6 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, if (!page_mapped(hpage)) return true; - if (PageKsm(p)) { - pr_err("%#lx: can't handle KSM pages.\n", pfn); - return false; - } - if (PageSwapCache(p)) { pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); ttu &= ~TTU_HWPOISON; -- 2.25.1