From patchwork Wed Aug 19 02:24:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 11722383 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4D1A614F6 for ; Wed, 19 Aug 2020 02:25:18 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 0D2BC205CB for ; Wed, 19 Aug 2020 02:25:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="g6IVo8SN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0D2BC205CB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 5167B8D0008; Tue, 18 Aug 2020 22:25:17 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 4A0978D0007; Tue, 18 Aug 2020 22:25:17 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 341078D0008; Tue, 18 Aug 2020 22:25:17 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0238.hostedemail.com [216.40.44.238]) by kanga.kvack.org (Postfix) with ESMTP id 195778D0007 for ; Tue, 18 Aug 2020 22:25:17 -0400 (EDT) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id CB638824805A for ; Wed, 19 Aug 2020 02:25:16 +0000 (UTC) X-FDA: 77165726232.13.lake78_340e3ac27024 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin13.hostedemail.com (Postfix) with ESMTP id 9DDE518140B60 for ; Wed, 19 Aug 2020 02:25:16 +0000 (UTC) X-Spam-Summary: 1,0,0,bba58007faedea9a,d41d8cd98f00b204,laoar.shao@gmail.com,,RULES_HIT:41:69:355:379:541:800:960:966:973:981:988:989:1260:1345:1359:1437:1535:1544:1605:1711:1730:1747:1777:1792:2196:2198:2199:2200:2393:2553:2559:2562:2731:2901:2903:3138:3139:3140:3141:3142:3165:3865:3866:3867:3868:3870:3871:3872:3873:3874:4118:4250:4321:4385:4605:5007:6119:6261:6653:7514:7576:7875:9413:9592:10004:11026:11473:11658:11914:12043:12048:12291:12296:12297:12438:12517:12519:12555:12895:13869:14130:14181:14394:14687:14721:21080:21324:21433:21444:21451:21627:21666:21740:21990:30005:30012:30045:30054:30064:30069:30070:30090,0,RBL:209.85.219.68:@gmail.com:.lbl8.mailshell.net-66.100.201.100 62.50.0.100;04yfz45qif6ozatsd3hwhf5kwxeuhocstyojtjcswh1y1f8fihtxbkwkrepzz1q.7nzyq7kujqh4hw7uefzb96gkhq9yxdmgqyrumptw3i6453esrdz3u8pjnuj1ge7.c-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime :26,LUA_ X-HE-Tag: lake78_340e3ac27024 X-Filterd-Recvd-Size: 7479 Received: from mail-qv1-f68.google.com (mail-qv1-f68.google.com [209.85.219.68]) by imf14.hostedemail.com (Postfix) with ESMTP for ; Wed, 19 Aug 2020 02:25:16 +0000 (UTC) Received: by mail-qv1-f68.google.com with SMTP id o2so10584384qvk.6 for ; Tue, 18 Aug 2020 19:25:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NRcr1uR+jWrXWzQj4QCI0O5tOCY1uyw+iu2TAziMeTw=; b=g6IVo8SNkSoc13ObF7oUgd3Gzgh8q53F3K8BgSOlps6OhWtNQvqUcss/Mk7DyGZfEz HtWw2IuxUFN0sB1Rh3IkVT28nccCyK3Kgg1tdvz39hIf6SqKI2dVu5IY2nUZFDookii7 JfZ57jQZmunF9GVf9ezeTqLvNv8H6vxr/Z910Pidty32BYdKrhmXbxgkp1KfG+chdf/V 0r/jLVtedaMf86ZlvC+i2W+ctu0gOyOrTo999TaPg3tUmR6P1APbTKy4Dw9blV/kRWpZ ZPpUH8i2JCMN/rrs1PsDi1yypkfPESV5qMhOI6tqCTOX7MmTwlFDBfjlK1nAaKK8jAKK T1xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NRcr1uR+jWrXWzQj4QCI0O5tOCY1uyw+iu2TAziMeTw=; b=SFtIIsT/o3vqp9PjoG+AnSZV0QWc5wH0am2jL2dkv0N4bLnk82KE1nb9tHws7aexHg J9pCM4vjlPnLMNdDzFGUcWTxKvy+FjZWo7C8uBjAaCm3ntlgsorhRfPPd3MBo+0JxEFG J/yVeuz+apz4bsPKEvjprDfvrYVcAjLyyQQ5B6OqoF1t9q+SSvbWFYHIL+I0WQ8FpsYm jYJYJzR4kEUK/LotSSsndlGdmCTCf9PD13ybsnj0d9YvZv1AcjDZJU0Zo8W1dthzVWXL xOs9h01NL9a+sQKK+yD8ueNgJ1B8pTFJiC2w6DETXknIJwtBzCeFsK5lORmIbNuraJQW 9LZQ== X-Gm-Message-State: AOAM533kDQ+M956xaoykRQXr43Ee7vz47IMIhOWZmqKExMXooOMlCOtS 0Phfv/hCkO1XBaeBpm7PD8U= X-Google-Smtp-Source: ABdhPJx8Kw+IH+QeI3+5U/fnvkMljo7NN7EJojoUfStufzv8ixioHaLNelz+8ih/iIifgLjuJC7kbw== X-Received: by 2002:a0c:8b51:: with SMTP id d17mr22126354qvc.107.1597803915736; Tue, 18 Aug 2020 19:25:15 -0700 (PDT) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id t12sm21988275qkt.56.2020.08.18.19.25.10 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 19:25:15 -0700 (PDT) From: Yafang Shao To: david@fromorbit.com, hch@infradead.org, darrick.wong@oracle.com, willy@infradead.org, mhocko@kernel.org, akpm@linux-foundation.org Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, Yafang Shao Subject: [PATCH v5 1/2] mm: Add become_kswapd and restore_kswapd Date: Wed, 19 Aug 2020 10:24:24 +0800 Message-Id: <20200819022425.25188-2-laoar.shao@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200819022425.25188-1-laoar.shao@gmail.com> References: <20200819022425.25188-1-laoar.shao@gmail.com> X-Rspamd-Queue-Id: 9DDE518140B60 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam04 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: From: "Matthew Wilcox (Oracle)" Since XFS needs to pretend to be kswapd in some of its worker threads, create methods to save & restore kswapd state. Don't bother restoring kswapd state in kswapd -- the only time we reach this code is when we're exiting and the task_struct is about to be destroyed anyway. Cc: Dave Chinner Cc: Christoph Hellwig Cc: Michal Hocko Cc: Darrick J. Wong Cc: Matthew Wilcox Signed-off-by: Matthew Wilcox (Oracle) Signed-off-by: Yafang Shao Acked-by: Michal Hocko --- fs/xfs/libxfs/xfs_btree.c | 14 ++++++++------ include/linux/sched/mm.h | 28 ++++++++++++++++++++++++++++ mm/vmscan.c | 16 +--------------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 2d25bab68764..a04a44238aab 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -2813,8 +2813,9 @@ xfs_btree_split_worker( { struct xfs_btree_split_args *args = container_of(work, struct xfs_btree_split_args, work); + bool is_kswapd = args->kswapd; unsigned long pflags; - unsigned long new_pflags = PF_MEMALLOC_NOFS; + int memalloc_nofs; /* * we are in a transaction context here, but may also be doing work @@ -2822,16 +2823,17 @@ xfs_btree_split_worker( * temporarily to ensure that we don't block waiting for memory reclaim * in any way. */ - if (args->kswapd) - new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; - - current_set_flags_nested(&pflags, new_pflags); + if (is_kswapd) + pflags = become_kswapd(); + memalloc_nofs = memalloc_nofs_save(); args->result = __xfs_btree_split(args->cur, args->level, args->ptrp, args->key, args->curp, args->stat); complete(args->done); - current_restore_flags_nested(&pflags, new_pflags); + memalloc_nofs_restore(memalloc_nofs); + if (is_kswapd) + restore_kswapd(pflags); } /* diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index f889e332912f..80cc132f13a1 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -303,6 +303,34 @@ static inline void memalloc_nocma_restore(unsigned int flags) } #endif +/* + * Tell the memory management that we're a "memory allocator", + * and that if we need more memory we should get access to it + * regardless (see "__alloc_pages()"). "kswapd" should + * never get caught in the normal page freeing logic. + * + * (Kswapd normally doesn't need memory anyway, but sometimes + * you need a small amount of memory in order to be able to + * page out something else, and this flag essentially protects + * us from recursively trying to free more memory as we're + * trying to free the first piece of memory in the first place). + */ +#define KSWAPD_PF_FLAGS (PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD) + +static inline unsigned long become_kswapd(void) +{ + unsigned long flags = current->flags & KSWAPD_PF_FLAGS; + + current->flags |= KSWAPD_PF_FLAGS; + + return flags; +} + +static inline void restore_kswapd(unsigned long flags) +{ + current->flags &= ~(flags ^ KSWAPD_PF_FLAGS); +} + #ifdef CONFIG_MEMCG /** * memalloc_use_memcg - Starts the remote memcg charging scope. diff --git a/mm/vmscan.c b/mm/vmscan.c index 99e1796eb833..3a2615bfde35 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -3859,19 +3859,7 @@ static int kswapd(void *p) if (!cpumask_empty(cpumask)) set_cpus_allowed_ptr(tsk, cpumask); - /* - * Tell the memory management that we're a "memory allocator", - * and that if we need more memory we should get access to it - * regardless (see "__alloc_pages()"). "kswapd" should - * never get caught in the normal page freeing logic. - * - * (Kswapd normally doesn't need memory anyway, but sometimes - * you need a small amount of memory in order to be able to - * page out something else, and this flag essentially protects - * us from recursively trying to free more memory as we're - * trying to free the first piece of memory in the first place). - */ - tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; + become_kswapd(); set_freezable(); WRITE_ONCE(pgdat->kswapd_order, 0); @@ -3921,8 +3909,6 @@ static int kswapd(void *p) goto kswapd_try_sleep; } - tsk->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD); - return 0; } From patchwork Wed Aug 19 02:24:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 11722391 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5DF21913 for ; Wed, 19 Aug 2020 02:25:26 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 1D11820866 for ; Wed, 19 Aug 2020 02:25:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TlftgfRZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1D11820866 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 42BC28D000F; Tue, 18 Aug 2020 22:25:25 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 3B4FB8D0007; Tue, 18 Aug 2020 22:25:25 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 27E198D000F; Tue, 18 Aug 2020 22:25:25 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0191.hostedemail.com [216.40.44.191]) by kanga.kvack.org (Postfix) with ESMTP id 0C00D8D0007 for ; Tue, 18 Aug 2020 22:25:25 -0400 (EDT) Received: from smtpin15.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id C129A824805A for ; Wed, 19 Aug 2020 02:25:24 +0000 (UTC) X-FDA: 77165726568.15.knee33_140822527024 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin15.hostedemail.com (Postfix) with ESMTP id 843AA1814B0C8 for ; Wed, 19 Aug 2020 02:25:24 +0000 (UTC) X-Spam-Summary: 1,0,0,8112fb37a178e34b,d41d8cd98f00b204,laoar.shao@gmail.com,,RULES_HIT:1:2:41:69:355:379:541:800:960:966:973:981:988:989:1260:1345:1359:1437:1605:1730:1747:1777:1792:2196:2198:2199:2200:2393:2559:2562:2892:2895:2897:3138:3139:3140:3141:3142:3664:3865:3866:3867:3868:3870:3871:3872:3874:4051:4250:4321:4385:4605:5007:6117:6119:6261:6653:7514:7875:7903:8660:9010:9413:9592:10004:11026:11232:11233:11473:11658:11914:12043:12048:12291:12295:12296:12297:12438:12517:12519:12555:12895:12986:13148:13230:14096:14394:14687:21080:21433:21444:21451:21611:21627:21666:21809:21939:21990:30034:30054:30064:30069:30070:30075,0,RBL:209.85.222.193:@gmail.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100;04y8qatuimjxrjrm55th1etu8bc5kypb78tur1o9b8q6icjc9eew9yad6pt1sbd.rnm3urdwbqwpmwjewmernapf45rk7ax3siwyoc6s5m4ydnehsgbaiosmx5eawor.6-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0 ,LFtime: X-HE-Tag: knee33_140822527024 X-Filterd-Recvd-Size: 11223 Received: from mail-qk1-f193.google.com (mail-qk1-f193.google.com [209.85.222.193]) by imf11.hostedemail.com (Postfix) with ESMTP for ; Wed, 19 Aug 2020 02:25:24 +0000 (UTC) Received: by mail-qk1-f193.google.com with SMTP id b14so20344339qkn.4 for ; Tue, 18 Aug 2020 19:25:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=p/Aa+4/PAdW4UzIOLAlILdbf31440xpvhPKoHCUn5Lg=; b=TlftgfRZd9jclluLLwtB23XOZgY4YAn7k5FCF7asLHLqkP/TfTi5jMeFcTGESZOmz3 osNu0VihjhV1r0jYuu5JGBeYp0izbcuHqrwxGsp+uv8rxkVW0YZJJNZvJ/tJC8LtVr7N pQbZyGEh1OvtrvXq7bM22reLiUv+KMm4x7RIyM8/o3fscIyRVCFUhBCnwNzpgfFcBmX0 XH+jcvFBPuu0SHIh10V1Lfr9wVhm6OEUFK7PiZDRaJaNCDgDO/wZArpZsDY070J1y4AC Wt/VAPECwqhJueuI5etl5Walw0OgyC3hhy4sYEkR/gawdTDZVMFjH3mlG6pwNuoGjdyA c7Rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=p/Aa+4/PAdW4UzIOLAlILdbf31440xpvhPKoHCUn5Lg=; b=TQx+2dTV9bYTUPyW8WTjEr4XXVAI942EUsK2PxUKjBmH0/LWCgyVnywFk5JpR9Lot0 PkJj7ja+fAcU50wRjkELq0nPMvwWEYGy8+wVBuuAbALuMrWEEV36akZ2If3bws4WsReb 5rFPDcgfYlyFiT8SNZer2v+Yp5zYJhJLzVagnFOAcZaeE31/Y62ynOkGbXnig9yjSORV ruJoCTe5f9DvwbOYx6/snTDvFYF8zQ+i8PBp+UHY2S8Qsc5qwpK1o4BuJkSifd/o9N93 9bRU0FypXCL717truvsCtAzNP5vrUrHBJJQkH23fVGPkyS0uyGKMJS3DFnv+eal3jzh2 /qfQ== X-Gm-Message-State: AOAM531ZInYwG+IQnfUM49nO3FqTmc5UDrxXMTkRo/p/vUI/3xTUd9+q 8V3NSj2eCIRDT/ZJUcZPpJs= X-Google-Smtp-Source: ABdhPJwyCazFlXy8wLmBYB7+hmiq0UoYpzv/qmDDkM+kcdxkxEajM8uuVzoffyFPegDAyG/QGEEcFg== X-Received: by 2002:a05:620a:123c:: with SMTP id v28mr18282319qkj.366.1597803923403; Tue, 18 Aug 2020 19:25:23 -0700 (PDT) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id t12sm21988275qkt.56.2020.08.18.19.25.17 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 19:25:22 -0700 (PDT) From: Yafang Shao To: david@fromorbit.com, hch@infradead.org, darrick.wong@oracle.com, willy@infradead.org, mhocko@kernel.org, akpm@linux-foundation.org Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, Yafang Shao Subject: [PATCH v5 2/2] xfs: avoid transaction reservation recursion Date: Wed, 19 Aug 2020 10:24:25 +0800 Message-Id: <20200819022425.25188-3-laoar.shao@gmail.com> X-Mailer: git-send-email 2.17.2 (Apple Git-113) In-Reply-To: <20200819022425.25188-1-laoar.shao@gmail.com> References: <20200819022425.25188-1-laoar.shao@gmail.com> X-Rspamd-Queue-Id: 843AA1814B0C8 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam03 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: PF_FSTRANS which is used to avoid transaction reservation recursion, is dropped since commit 9070733b4efa ("xfs: abstract PF_FSTRANS to PF_MEMALLOC_NOFS") and commit 7dea19f9ee63 ("mm: introduce memalloc_nofs_{save,restore} API") and replaced by PF_MEMALLOC_NOFS which means to avoid filesystem reclaim recursion. That change is subtle. Let's take the exmple of the check of WARN_ON_ONCE(current->flags & PF_MEMALLOC_NOFS)) to explain why this abstraction from PF_FSTRANS to PF_MEMALLOC_NOFS is not proper. Below comment is quoted from Dave, > It wasn't for memory allocation recursion protection in XFS - it was for > transaction reservation recursion protection by something trying to flush > data pages while holding a transaction reservation. Doing > this could deadlock the journal because the existing reservation > could prevent the nested reservation for being able to reserve space > in the journal and that is a self-deadlock vector. > IOWs, this check is not protecting against memory reclaim recursion > bugs at all (that's the previous check [1]). This check is > protecting against the filesystem calling writepages directly from a > context where it can self-deadlock. > So what we are seeing here is that the PF_FSTRANS -> > PF_MEMALLOC_NOFS abstraction lost all the actual useful information > about what type of error this check was protecting against. As a result, we should reintroduce PF_FSTRANS. As current->journal_info isn't used in XFS, we can reuse it to indicate whehter the task is in fstrans or not, Per Willy. To achieve that, four new helpers are introduce in this patch, per Dave: - xfs_trans_context_set() Used in xfs_trans_alloc() - xfs_trans_context_clear() Used in xfs_trans_commit() and xfs_trans_cancel() - xfs_trans_context_update() Used in xfs_trans_roll() - fstrans_context_active() To check whehter current is in fs transcation or not [1]. Below check is to avoid memory reclaim recursion. if (WARN_ON_ONCE((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC)) goto redirty; Cc: Dave Chinner Cc: Christoph Hellwig Cc: Michal Hocko Cc: Darrick J. Wong Cc: Matthew Wilcox Signed-off-by: Yafang Shao --- fs/iomap/buffered-io.c | 4 ++-- fs/xfs/xfs_aops.c | 5 +++-- fs/xfs/xfs_linux.h | 4 ---- fs/xfs/xfs_trans.c | 19 +++++++++---------- fs/xfs/xfs_trans.h | 23 +++++++++++++++++++++++ include/linux/iomap.h | 7 +++++++ 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index bcfc288dba3f..8043224ec079 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1500,9 +1500,9 @@ iomap_do_writepage(struct page *page, struct writeback_control *wbc, void *data) /* * Given that we do not allow direct reclaim to call us, we should - * never be called in a recursive filesystem reclaim context. + * never be called while in a filesystem transaction. */ - if (WARN_ON_ONCE(current->flags & PF_MEMALLOC_NOFS)) + if (WARN_ON_ONCE(fstrans_context_active())) goto redirty; /* diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index b35611882ff9..83e0a1840221 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -62,7 +62,8 @@ xfs_setfilesize_trans_alloc( * We hand off the transaction to the completion thread now, so * clear the flag here. */ - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + xfs_trans_context_clear(tp); + return 0; } @@ -125,7 +126,7 @@ xfs_setfilesize_ioend( * thus we need to mark ourselves as being in a transaction manually. * Similarly for freeze protection. */ - current_set_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + xfs_trans_context_set(tp); __sb_writers_acquired(VFS_I(ip)->i_sb, SB_FREEZE_FS); /* we abort the update if there was an IO error */ diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index ab737fed7b12..8a4f6db77e33 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -102,10 +102,6 @@ typedef __u32 xfs_nlink_t; #define xfs_cowb_secs xfs_params.cowb_timer.val #define current_cpu() (raw_smp_processor_id()) -#define current_set_flags_nested(sp, f) \ - (*(sp) = current->flags, current->flags |= (f)) -#define current_restore_flags_nested(sp, f) \ - (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) #define NBBY 8 /* number of bits per byte */ diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index ed72867b1a19..5f3a4ff51b3c 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -153,8 +153,6 @@ xfs_trans_reserve( int error = 0; bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; - /* Mark this thread as being in a transaction */ - current_set_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); /* * Attempt to reserve the needed disk blocks by decrementing @@ -163,10 +161,8 @@ xfs_trans_reserve( */ if (blocks > 0) { error = xfs_mod_fdblocks(mp, -((int64_t)blocks), rsvd); - if (error != 0) { - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + if (error != 0) return -ENOSPC; - } tp->t_blk_res += blocks; } @@ -241,8 +237,6 @@ xfs_trans_reserve( tp->t_blk_res = 0; } - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); - return error; } @@ -284,6 +278,8 @@ xfs_trans_alloc( INIT_LIST_HEAD(&tp->t_dfops); tp->t_firstblock = NULLFSBLOCK; + /* Mark this thread as being in a transaction */ + xfs_trans_context_set(tp); error = xfs_trans_reserve(tp, resp, blocks, rtextents); if (error) { xfs_trans_cancel(tp); @@ -878,7 +874,8 @@ __xfs_trans_commit( xfs_log_commit_cil(mp, tp, &commit_lsn, regrant); - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + if (!regrant) + xfs_trans_context_clear(tp); xfs_trans_free(tp); /* @@ -910,7 +907,8 @@ __xfs_trans_commit( xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket); tp->t_ticket = NULL; } - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + + xfs_trans_context_clear(tp); xfs_trans_free_items(tp, !!error); xfs_trans_free(tp); @@ -971,7 +969,7 @@ xfs_trans_cancel( } /* mark this thread as no longer being in a transaction */ - current_restore_flags_nested(&tp->t_pflags, PF_MEMALLOC_NOFS); + xfs_trans_context_clear(tp); xfs_trans_free_items(tp, dirty); xfs_trans_free(tp); @@ -1013,6 +1011,7 @@ xfs_trans_roll( if (error) return error; + xfs_trans_context_update(trans, *tpp); /* * Reserve space in the log for the next transaction. * This also pushes items in the "AIL", the list of logged items, diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index b752501818d2..895f560229d6 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -243,4 +243,27 @@ void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp, extern kmem_zone_t *xfs_trans_zone; +static inline void +xfs_trans_context_set(struct xfs_trans *tp) +{ + ASSERT(!current->journal_info); + current->journal_info = tp; + tp->t_pflags = memalloc_nofs_save(); +} + +static inline void +xfs_trans_context_update(struct xfs_trans *old, struct xfs_trans *new) +{ + ASSERT(current->journal_info == old); + current->journal_info = new; +} + +static inline void +xfs_trans_context_clear(struct xfs_trans *tp) +{ + ASSERT(current->journal_info == tp); + current->journal_info = NULL; + memalloc_nofs_restore(tp->t_pflags); +} + #endif /* __XFS_TRANS_H__ */ diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 4d1d3c3469e9..54194dd6009d 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -271,4 +271,11 @@ int iomap_swapfile_activate(struct swap_info_struct *sis, # define iomap_swapfile_activate(sis, swapfile, pagespan, ops) (-EIO) #endif /* CONFIG_SWAP */ +/* Use the journal_info to indicate current is in a transaction */ +static inline bool +fstrans_context_active(void) +{ + return current->journal_info != NULL; +} + #endif /* LINUX_IOMAP_H */