Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp4643953yba; Mon, 20 May 2019 00:51:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqzUh+x5rlIkAh67uCUEhT21fllBnKPauY0L452o60scFRlt/Om7kpY97Z027IU53Ap4kTSg X-Received: by 2002:a17:902:690b:: with SMTP id j11mr19993208plk.149.1558338662702; Mon, 20 May 2019 00:51:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558338662; cv=none; d=google.com; s=arc-20160816; b=Q3jDOk/hePGz0GSLm2hk/Oc5bc4XGwiQDsXgvKCo0WonBEhG7FjKil0fcPw49IPcCM pALaNwpvWmR1wlozJYJolQZVASN61zUj6qd4xenRRRDcCRmWQwORrF8B49AkE23FaH37 ge2VfjAt0wIQ53z6955Y/ocljrfiEU4h4V7Aix5uVQZ0nSQfi+Ah1CDNwJ7UJ6kaKoi0 BZbz7zOp9Mb91z3an5Oz398P574Cgk885x548gEfqlCJX+Ftrk0GZffYBzOZ7yA/2+6O ODbiKsZArQQTQpw/Z6TOjx7ngXGvX+ATbdRd0gx0Bdi0o8MeclJCKGN91URqhHYuQQjX jApg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=saCxizw32Jq7dMTN5gwfHcfa+dy7EpZHGbTHKFMG+ho=; b=Z71jPqqA2YKoeDnZN0bata6tzGsb3SxuM+ULGczrKhk2rEeyerSJ4eGd6XtdQfPaRt pWpQVhDwjN9+xhLny+kqMnBTBhHeX8Cgld9Ku+hE5/oTT2xLIM4E7WLvDpL+h3gzuNkM MshMWbg4gRrZ9Ho9XyRnXtkOAuCniUzT1PdJIoLt2oRO3OegoRhiE9yFKQGB7bWpGs80 uXwCkkbXGfjrYhmasiBtCEhRkoSv17FQLXmM+P8OKAMr8FqSh/EVfDjkPRtWPylTrfrt 0TXLt0Fhi2Hh8VrI4TNwQG7R6b1nonnczN5lmtAy6omgPSf0HEbex8Ni1NEGJwQRIaus MFUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=gAlSX8TO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1si17499996pln.354.2019.05.20.00.50.48; Mon, 20 May 2019 00:51:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=gAlSX8TO; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730483AbfETFnB (ORCPT + 99 others); Mon, 20 May 2019 01:43:01 -0400 Received: from new4-smtp.messagingengine.com ([66.111.4.230]:41005 "EHLO new4-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729535AbfETFnA (ORCPT ); Mon, 20 May 2019 01:43:00 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id 3D25710E56; Mon, 20 May 2019 01:42:59 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Mon, 20 May 2019 01:42:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=saCxizw32Jq7dMTN5gwfHcfa+dy7EpZHGbTHKFMG+ho=; b=gAlSX8TO fcuek0YYCjnPtnRqtTcFPf18A3CjnScnL+unrhGzFdsGVFTur1RufeyGl9kcHIaL uh+hknblFftXo3OYtovnHQI2ovqIw3J2VlkVvKvL2XMGveghgWqujLvvqSY+MEoe E4fMy9EQy2zlr1MI5fcpEWgb9YE1vP/9Uql5R27Y98ZbHlNDeqFpIlf9d7j1De8p CK6f9780Qk7kRhUIHEU9zvE4Ugss5ENJOjjRl8UG/N8YxE2xrnBzHk9BvYQANfJN RHwzqYkX7doCeg+0YeDniqXxNMRyE+u8ftFvTnoIrEeAIoDQguHkwlYO5BE0GgMT zwwTNjFHjeRviw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddruddtjedguddtudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepfdfvohgs ihhnucevrdcujfgrrhguihhnghdfuceothhosghinheskhgvrhhnvghlrdhorhhgqeenuc fkphepuddvgedrudeiledrudehiedrvddtfeenucfrrghrrghmpehmrghilhhfrhhomhep thhosghinheskhgvrhhnvghlrdhorhhgnecuvehluhhsthgvrhfuihiivgepudeg X-ME-Proxy: Received: from eros.localdomain (124-169-156-203.dyn.iinet.net.au [124.169.156.203]) by mail.messagingengine.com (Postfix) with ESMTPA id 016CE8005B; Mon, 20 May 2019 01:42:51 -0400 (EDT) From: "Tobin C. Harding" To: Andrew Morton , Matthew Wilcox Cc: "Tobin C. Harding" , Roman Gushchin , Alexander Viro , Christoph Hellwig , Pekka Enberg , David Rientjes , Joonsoo Kim , Christopher Lameter , Miklos Szeredi , Andreas Dilger , Waiman Long , Tycho Andersen , Theodore Ts'o , Andi Kleen , David Chinner , Nick Piggin , Rik van Riel , Hugh Dickins , Jonathan Corbet , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v5 15/16] dcache: Implement partial shrink via Slab Movable Objects Date: Mon, 20 May 2019 15:40:16 +1000 Message-Id: <20190520054017.32299-16-tobin@kernel.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190520054017.32299-1-tobin@kernel.org> References: <20190520054017.32299-1-tobin@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The dentry slab cache is susceptible to internal fragmentation. Now that we have Slab Movable Objects we can attempt to defragment the dcache. Dentry objects are inherently _not_ relocatable however under some conditions they can be free'd. This is the same as shrinking the dcache but instead of shrinking the whole cache we only attempt to free those objects that are located in partially full slab pages. There is no guarantee that this will reduce the memory usage of the system, it is a compromise between fragmented memory and total cache shrinkage with the hope that some memory pressure can be alleviated. This is implemented using the newly added Slab Movable Objects infrastructure. The dcache 'migration' function is intentionally _not_ called 'd_migrate' because we only free, we do not migrate. Call it 'd_partial_shrink' to make explicit that no reallocation is done. Implement isolate and 'migrate' functions for the dentry slab cache. Signed-off-by: Tobin C. Harding --- fs/dcache.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index b7318615979d..0dfe580c2d42 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" @@ -3071,6 +3072,79 @@ void d_tmpfile(struct dentry *dentry, struct inode *inode) } EXPORT_SYMBOL(d_tmpfile); +/* + * d_isolate() - Dentry isolation callback function. + * @s: The dentry cache. + * @v: Vector of pointers to the objects to isolate. + * @nr: Number of objects in @v. + * + * The slab allocator is holding off frees. We can safely examine + * the object without the danger of it vanishing from under us. + */ +static void *d_isolate(struct kmem_cache *s, void **v, int nr) +{ + struct list_head *dispose; + struct dentry *dentry; + int i; + + dispose = kmalloc(sizeof(*dispose), GFP_KERNEL); + if (!dispose) + return NULL; + + INIT_LIST_HEAD(dispose); + + for (i = 0; i < nr; i++) { + dentry = v[i]; + spin_lock(&dentry->d_lock); + + if (dentry->d_lockref.count > 0 || + dentry->d_flags & DCACHE_SHRINK_LIST) { + spin_unlock(&dentry->d_lock); + continue; + } + + if (dentry->d_flags & DCACHE_LRU_LIST) + d_lru_del(dentry); + + d_shrink_add(dentry, dispose); + spin_unlock(&dentry->d_lock); + } + + return dispose; +} + +/* + * d_partial_shrink() - Dentry migration callback function. + * @s: The dentry cache. + * @_unused: We do not access the vector. + * @__unused: No need for length of vector. + * @___unused: We do not do any allocation. + * @private: list_head pointer representing the shrink list. + * + * Dispose of the shrink list created during isolation function. + * + * Dentry objects can _not_ be relocated and shrinking the whole dcache + * can be expensive. This is an effort to free dentry objects that are + * stopping slab pages from being free'd without clearing the whole dcache. + * + * This callback is called from the SLUB allocator object migration + * infrastructure in attempt to free up slab pages by freeing dentry + * objects from partially full slabs. + */ +static void d_partial_shrink(struct kmem_cache *s, void **_unused, int __unused, + int ___unused, void *private) +{ + struct list_head *dispose = private; + + if (!private) /* kmalloc error during isolate. */ + return; + + if (!list_empty(dispose)) + shrink_dentry_list(dispose); + + kfree(private); +} + static __initdata unsigned long dhash_entries; static int __init set_dhash_entries(char *str) { @@ -3116,6 +3190,8 @@ static void __init dcache_init(void) sizeof_field(struct dentry, d_iname), dcache_ctor); + kmem_cache_setup_mobility(dentry_cache, d_isolate, d_partial_shrink); + /* Hash may have been set up in dcache_init_early */ if (!hashdist) return; -- 2.21.0