From patchwork Wed Apr 16 05:52:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 3998181 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 391279F2CC for ; Wed, 16 Apr 2014 05:52:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9038C2026C for ; Wed, 16 Apr 2014 05:52:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D67CD2025B for ; Wed, 16 Apr 2014 05:52:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752497AbaDPFwj (ORCPT ); Wed, 16 Apr 2014 01:52:39 -0400 Received: from cantor2.suse.de ([195.135.220.15]:39678 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752014AbaDPFwi (ORCPT ); Wed, 16 Apr 2014 01:52:38 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9CB26AC2B; Wed, 16 Apr 2014 05:52:37 +0000 (UTC) Date: Wed, 16 Apr 2014 15:52:30 +1000 From: NeilBrown To: Al Viro Cc: linux-mm@kvack.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 17/19] VFS: set PF_FSTRANS while namespace_sem is held. Message-ID: <20140416155230.4d02e4b9@notabene.brown> In-Reply-To: <20140416044618.GX18016@ZenIV.linux.org.uk> References: <20140416033623.10604.69237.stgit@notabene.brown> <20140416040337.10604.86740.stgit@notabene.brown> <20140416044618.GX18016@ZenIV.linux.org.uk> X-Mailer: Claws Mail 3.9.2 (GTK+ 2.24.22; x86_64-suse-linux-gnu) Mime-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_TVD_MIME_EPI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Wed, 16 Apr 2014 05:46:18 +0100 Al Viro wrote: > On Wed, Apr 16, 2014 at 02:03:37PM +1000, NeilBrown wrote: > > namespace_sem can be taken while various i_mutex locks are held, so we > > need to avoid reclaim from blocking on an FS (particularly loop-back > > NFS). > > I would really prefer to deal with that differently - by explicit change of > gfp_t arguments of allocators. > > The thing is, namespace_sem is held *only* over allocations, and not a lot > of them, at that - only mnt_alloc_id(), mnt_alloc_group_id(), alloc_vfsmnt() > and new_mountpoint(). That is all that is allowed. > > Again, actual work with filesystems (setup, shutdown, remount, pathname > resolution, etc.) is all done outside of namespace_sem; it's held only > for manipulations of fs/{namespace,pnode}.c data structures and the only > reason it isn't a spinlock is that we need to do some allocations. > > So I'd rather slap GFP_NOFS on those few allocations... So something like this? I put that in to my testing instead. Thanks, NeilBrown diff --git a/fs/namespace.c b/fs/namespace.c index 83dcd5083dbb..8e103b8c8323 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -103,7 +103,7 @@ static int mnt_alloc_id(struct mount *mnt) int res; retry: - ida_pre_get(&mnt_id_ida, GFP_KERNEL); + ida_pre_get(&mnt_id_ida, GFP_NOFS); spin_lock(&mnt_id_lock); res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id); if (!res) @@ -134,7 +134,7 @@ static int mnt_alloc_group_id(struct mount *mnt) { int res; - if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL)) + if (!ida_pre_get(&mnt_group_ida, GFP_NOFS)) return -ENOMEM; res = ida_get_new_above(&mnt_group_ida, @@ -193,7 +193,7 @@ unsigned int mnt_get_count(struct mount *mnt) static struct mount *alloc_vfsmnt(const char *name) { - struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); + struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_NOFS); if (mnt) { int err; @@ -202,7 +202,7 @@ static struct mount *alloc_vfsmnt(const char *name) goto out_free_cache; if (name) { - mnt->mnt_devname = kstrdup(name, GFP_KERNEL); + mnt->mnt_devname = kstrdup(name, GFP_NOFS); if (!mnt->mnt_devname) goto out_free_id; } @@ -682,7 +682,7 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry) } } - mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); + mp = kmalloc(sizeof(struct mountpoint), GFP_NOFS); if (!mp) return ERR_PTR(-ENOMEM);