Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp64001pxb; Thu, 27 Jan 2022 15:10:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJw+AzZFVArlxWwZSyyMd91UNkwK1r7wSKEb31qKwqb3QLQiVXqdHF3gGXwJxmWThaEyTYqL X-Received: by 2002:a50:ff04:: with SMTP id a4mr5686859edu.102.1643325024804; Thu, 27 Jan 2022 15:10:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643325024; cv=none; d=google.com; s=arc-20160816; b=T+dioplc3C4Ks8x1oJgU0qHfG2LNB+01RwHP/Ew0qRk1q2DbarF0KNJZ6nzBeKD5k4 20tWVKgtDYvtsalqpVR90shHHjyqoTM6wqSvpy42l9OLC1Tb31M2XWZxKZAbMAohz4Vg 7+GzXkQb4rq2ZtwQ1F6aVyMgWM+RPCYuyVELZcEMUaZXXvp7oCoYb/JDXTxaKKQ32BMs JkCJYKAqWRbFn/yOWKemlb0Mc5BuySkcZm04UD/N2hiUOaOxU8VqaVd28Y0FWSx+ix/f eatno2nDVhRDbcm0HX36NHhEY9vG3KEmbPO3CEvrOvRy24kU0DyeVPgZxLO25/4WwWrU Dutg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-hdrordr:ironport-data; bh=nYJtEtluwzJIZ80QrkLGHtCeBA4NVOWPhT1EjwH3zTQ=; b=IIEPFBfXM2ZT4uJ3u+b1gReIlRcOYhr7a8U/vg/hlxbbtYm8cjeGIlFetrX9f4qN2p +mqqd2yIaHNWIbkA+7glYkONH1kfAf+gDqxSvAIWc6gpV2ILsEUX6Yai1rUjQtpevrvC NmwW2kNJMLlPRzJs+lR4dDi1+ZJMLwqerRVYi4p0stlrTXcvpIIuj7MhRtb6DhbuNRmW XhfYhDnzE1G3Q1XGEQSYPk5ec3a71KVMB69sEEUkW3Kw20eSWLZ4/PJEg4gXJBmZChde iWze/r0Og4yZCm2+WoX263Scjwy0EX82FoUnQEXLt9tLbjlS3XvKCvRx4CqMone0n1cH HfNQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=fujitsu.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hq3si2244482ejc.417.2022.01.27.15.10.00; Thu, 27 Jan 2022 15:10:24 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=fujitsu.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241468AbiA0Mlh (ORCPT + 99 others); Thu, 27 Jan 2022 07:41:37 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:35635 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S241274AbiA0MlS (ORCPT ); Thu, 27 Jan 2022 07:41:18 -0500 IronPort-Data: =?us-ascii?q?A9a23=3A/WvDiqL/SFmKHzANFE+RupQlxSXFcZb7ZxGrkP8?= =?us-ascii?q?bfHC50jx3gjMEmGBNDGDVbPeDN2D2fN5waI60/RkDupLUxoNqS1BcGVNFFSwT8?= =?us-ascii?q?ZWfbTi6wuYcBwvLd4ubChsPA/w2MrEsF+hpCC+MzvuRGuK59yMkjPvXHuOU5NP?= =?us-ascii?q?sYUideyc1EU/Ntjozw4bVsqYw6TSIK1vlVeHa+qUzC3f5s9JACV/43orYwP9ZU?= =?us-ascii?q?FsejxtD1rA2TagjUFYzDBD5BrpHTU26ByOQroW5goeHq+j/ILGRpgs1/j8mDJW?= =?us-ascii?q?rj7T6blYXBLXVOGBiiFIPA+773EcE/Xd0j87XN9JFAatToy+UltZq2ZNDs4esY?= =?us-ascii?q?Qk0PKzQg/lbWB5de817FfQcoO6eeiLg66R/yGWDKRMA2c5GAEgoPIEw9PxwBGZ?= =?us-ascii?q?U//0EbjsKa3irh+m26LO9RPNliskqII/sJox3kn1py3fbS+knRZTCSqDRzd5ew?= =?us-ascii?q?Do0wMtJGJ72a8gGbjxgRBfNeRtCPhEQEp1WtOOpgGTvNjhdgFGLrKE0pW/Jw2R?= =?us-ascii?q?Z1qbhMd/QUtiLXtlO2EKZoH/WuWj0HHkyNtWZxHyO8m+EgfXGlif2HokVEdWQ8?= =?us-ascii?q?v9snU3WyHcfBQMbUXOlrvSjzE2zQdRSLwoT4CVGhawz8lG7C9rwRRu1pFaasRM?= =?us-ascii?q?GHdldCes37EeK0KW8ywKYAHUUCy5Pc/Q4u8IsAz8nzFmEm5XuHzMHjVE/YRpx7?= =?us-ascii?q?Z/N9XXrZ3dTdjREOEc5ocI+y4GLiOkOYtjnEL6PyJKIs+A=3D?= IronPort-HdrOrdr: =?us-ascii?q?A9a23=3AGomAYKGaa8sbqW/kpLqE1MeALOsnbusQ8zAX?= =?us-ascii?q?PiFKOHhom6mj+vxG88506faKslwssR0b+OxoW5PwJE80l6QFgrX5VI3KNGbbUQ?= =?us-ascii?q?CTXeNfBOXZowHIKmnX8+5x8eNaebFiNduYNzNHpPe/zA6mM9tI+rW6zJw=3D?= X-IronPort-AV: E=Sophos;i="5.88,320,1635177600"; d="scan'208";a="120913272" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 27 Jan 2022 20:41:07 +0800 Received: from G08CNEXMBPEKD04.g08.fujitsu.local (unknown [10.167.33.201]) by cn.fujitsu.com (Postfix) with ESMTP id 948364D169CA; Thu, 27 Jan 2022 20:41:04 +0800 (CST) Received: from G08CNEXCHPEKD09.g08.fujitsu.local (10.167.33.85) by G08CNEXMBPEKD04.g08.fujitsu.local (10.167.33.201) with Microsoft SMTP Server (TLS) id 15.0.1497.23; Thu, 27 Jan 2022 20:41:05 +0800 Received: from irides.mr.mr (10.167.225.141) by G08CNEXCHPEKD09.g08.fujitsu.local (10.167.33.209) with Microsoft SMTP Server id 15.0.1497.23 via Frontend Transport; Thu, 27 Jan 2022 20:41:02 +0800 From: Shiyang Ruan To: , , , , CC: , , , , Subject: [PATCH v10 7/9] mm: Introduce mf_dax_kill_procs() for fsdax case Date: Thu, 27 Jan 2022 20:40:56 +0800 Message-ID: <20220127124058.1172422-8-ruansy.fnst@fujitsu.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127124058.1172422-1-ruansy.fnst@fujitsu.com> References: <20220127124058.1172422-1-ruansy.fnst@fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-yoursite-MailScanner-ID: 948364D169CA.A1211 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: ruansy.fnst@fujitsu.com X-Spam-Status: No Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This function is called at the end of RMAP routine, i.e. filesystem recovery function, to collect and kill processes using a shared page of DAX file. The difference with mf_generic_kill_procs() is, it accepts file's (mapping,offset) instead of struct page because different files' mappings and offsets may share the same page in fsdax mode. It will be called when filesystem's RMAP results are found. Signed-off-by: Shiyang Ruan --- include/linux/mm.h | 4 ++ mm/memory-failure.c | 91 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 11 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 9b1d56c5c224..0420189e4788 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3195,6 +3195,10 @@ enum mf_flags { MF_SOFT_OFFLINE = 1 << 3, MF_UNPOISON = 1 << 4, }; +#if IS_ENABLED(CONFIG_FS_DAX) +int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index, + unsigned long count, int mf_flags); +#endif /* CONFIG_FS_DAX */ extern int memory_failure(unsigned long pfn, int flags); extern void memory_failure_queue(unsigned long pfn, int flags); extern void memory_failure_queue_kick(int cpu); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index b2d13eba1071..8d123cc4102e 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -304,10 +304,9 @@ void shake_page(struct page *p) } EXPORT_SYMBOL_GPL(shake_page); -static unsigned long dev_pagemap_mapping_shift(struct page *page, - struct vm_area_struct *vma) +static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma, + unsigned long address) { - unsigned long address = vma_address(page, vma); unsigned long ret = 0; pgd_t *pgd; p4d_t *p4d; @@ -347,9 +346,8 @@ static unsigned long dev_pagemap_mapping_shift(struct page *page, * Schedule a process for later kill. * Uses GFP_ATOMIC allocations to avoid potential recursions in the VM. */ -static void add_to_kill(struct task_struct *tsk, struct page *p, - struct vm_area_struct *vma, - struct list_head *to_kill) +static void add_to_kill(struct task_struct *tsk, struct page *p, pgoff_t pgoff, + struct vm_area_struct *vma, struct list_head *to_kill) { struct to_kill *tk; @@ -360,9 +358,15 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, } tk->addr = page_address_in_vma(p, vma); - if (is_zone_device_page(p)) - tk->size_shift = dev_pagemap_mapping_shift(p, vma); - else + if (is_zone_device_page(p)) { + /* + * Since page->mapping is not used for fsdax, we need + * calculate the address based on the vma. + */ + if (p->pgmap->type == MEMORY_DEVICE_FS_DAX) + tk->addr = vma_pgoff_address(vma, pgoff); + tk->size_shift = dev_pagemap_mapping_shift(vma, tk->addr); + } else tk->size_shift = page_shift(compound_head(p)); /* @@ -510,7 +514,7 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, if (!page_mapped_in_vma(page, vma)) continue; if (vma->vm_mm == t->mm) - add_to_kill(t, page, vma, to_kill); + add_to_kill(t, page, 0, vma, to_kill); } } read_unlock(&tasklist_lock); @@ -546,12 +550,40 @@ static void collect_procs_file(struct page *page, struct list_head *to_kill, * to be informed of all such data corruptions. */ if (vma->vm_mm == t->mm) - add_to_kill(t, page, vma, to_kill); + add_to_kill(t, page, 0, vma, to_kill); + } + } + read_unlock(&tasklist_lock); + i_mmap_unlock_read(mapping); +} + +#if IS_ENABLED(CONFIG_FS_DAX) +/* + * Collect processes when the error hit a fsdax page. + */ +static void collect_procs_fsdax(struct page *page, + struct address_space *mapping, pgoff_t pgoff, + struct list_head *to_kill) +{ + struct vm_area_struct *vma; + struct task_struct *tsk; + + i_mmap_lock_read(mapping); + read_lock(&tasklist_lock); + for_each_process(tsk) { + struct task_struct *t = task_early_kill(tsk, true); + + if (!t) + continue; + vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { + if (vma->vm_mm == t->mm) + add_to_kill(t, page, pgoff, vma, to_kill); } } read_unlock(&tasklist_lock); i_mmap_unlock_read(mapping); } +#endif /* CONFIG_FS_DAX */ /* * Collect the processes who have the corrupted page mapped to kill. @@ -1574,6 +1606,43 @@ static int mf_generic_kill_procs(unsigned long long pfn, int flags, return 0; } +#if IS_ENABLED(CONFIG_FS_DAX) +/** + * mf_dax_kill_procs - Collect and kill processes who are using this file range + * @mapping: the file in use + * @index: start pgoff of the range within the file + * @count: length of the range, in unit of PAGE_SIZE + * @mf_flags: memory failure flags + */ +int mf_dax_kill_procs(struct address_space *mapping, pgoff_t index, + unsigned long count, int mf_flags) +{ + LIST_HEAD(to_kill); + int rc; + struct page *page; + size_t end = index + count; + + mf_flags |= MF_ACTION_REQUIRED | MF_MUST_KILL; + + for (; index < end; index++) { + page = NULL; + rc = dax_load_page(mapping, index, &page); + if (rc) + return rc; + if (!page) + continue; + + SetPageHWPoison(page); + + collect_procs_fsdax(page, mapping, index, &to_kill); + unmap_and_kill(&to_kill, page_to_pfn(page), mapping, + index, mf_flags); + } + return 0; +} +EXPORT_SYMBOL_GPL(mf_dax_kill_procs); +#endif /* CONFIG_FS_DAX */ + static int memory_failure_hugetlb(unsigned long pfn, int flags) { struct page *p = pfn_to_page(pfn); -- 2.34.1