Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1976993yba; Tue, 2 Apr 2019 21:33:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqzs9IJpExYL1Crx+4WB7k30fYwI8cK3WrvW/25zVPDsmby+fzcWCl8r5WZCywsQB9XRaB1q X-Received: by 2002:a63:4819:: with SMTP id v25mr675815pga.412.1554266022635; Tue, 02 Apr 2019 21:33:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554266022; cv=none; d=google.com; s=arc-20160816; b=NoUQhvJUr268IYUT7hGgbmjwoZtspjJ4I6H84fQCa855JxWWd9DK1OoZ5ITgbjTpci qozDf1LK0e012VmD/5LzcUjah0xuwBE9wB25oihyKri3vRO+ufs3fxI9bhpB0FGcB1Mc dEOvwkcsOvqUSWvwdLJ1JDw0gnvSlVLRW2AcZNKJfI3ToUJUvIB18lZtxWBCexmhRahX K1oY/CDukPJv3TyUXMuYMo3hZKw9Zv3JEk5njFX77/qED+Y1K1GMqhPHUINqr2uqwL5O tduNe1Fs8Fq/sBpYJIHR45Q2LdlltjEjhRZZbue17erwnv/nOaYwdOe5bCVN7NNeygpK bPXQ== 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=3CgZchYLd16ww3/LiD/mAfG7GXA+RJSG10+pHsLIDks=; b=vkcgf6kh+txG3w4z4GVVwV14W6ZEt55d61qwoHwYnz5xDE/+c1l3aW/Vl9J60zuy7h CRuiSuxNddTs1R/q1DdouAg6JjMf8UYR19WnEQIa0bqKVGyvqFKdAK0OBozBizNYsxEm fLgMoBsaMssdDo+vexsenNnyRfn/SS7S9qoNnDrDmEV5H1iN1SrkHp2iTTM3kOHEaaDn OzBZnEIPDaQIL4NV8Q2aC/skWqXKycJOUfUrLXK8TbddjJOnP/mrgwV9dN+f4p9cEgfz 3hj2qUQ0Lo3KF3p9FbSxkYa0YVaNQ4q6fjyqlScdK7ot+YY/EU2Eq5vfZCFMzr+BkPUU T4wg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=wY4kIaUF; 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 d132si12608722pgc.482.2019.04.02.21.33.27; Tue, 02 Apr 2019 21:33:42 -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=wY4kIaUF; 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 S1728775AbfDCEbQ (ORCPT + 99 others); Wed, 3 Apr 2019 00:31:16 -0400 Received: from out4-smtp.messagingengine.com ([66.111.4.28]:38161 "EHLO out4-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728655AbfDCEbL (ORCPT ); Wed, 3 Apr 2019 00:31:11 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id E23B621FAE; Wed, 3 Apr 2019 00:24:29 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Wed, 03 Apr 2019 00:24:29 -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=3CgZchYLd16ww3/LiD/mAfG7GXA+RJSG10+pHsLIDks=; b=wY4kIaUF bKeyoZ1pX1nCWrBGHGHId2HQJ7fpODFRyw9W9hbVgEBM2F+znekZY9/Ya6bpkQLx g4bxXkC0jILJxfUFw+Xp/nP9yTQgozkM4b4uJR7dSeJn7Du55PXTCh12806jtLbw ZZtzaSMa5mrjyPZji51A8vd+/ku4ZVL5Qd4QTYWu6LVgY3XDelhAATeQIwGLJEeb QLOnXlctXLmYy9UVB2VQXXHy3Vce14hsYi8KLRqRXNOdpfUzNHOb/opiGiwyMH4x NkPSYl8X0PHNA6n6iOzmg96i85YHVOD3FW9jf9WsUSTJx9TKvaAriKhZyw0pb5db fRyyTYkfF5tEDg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrtddugdektdculddtuddrgedutddrtddtmd cutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefhvffufffkofgjfhgggfestdekredtredttden ucfhrhhomhepfdfvohgsihhnucevrdcujfgrrhguihhnghdfuceothhosghinheskhgvrh hnvghlrdhorhhgqeenucfkphepuddvgedrudeiledrvdejrddvtdeknecurfgrrhgrmhep mhgrihhlfhhrohhmpehtohgsihhnsehkvghrnhgvlhdrohhrghenucevlhhushhtvghruf hiiigvpedufe X-ME-Proxy: Received: from eros.localdomain (124-169-27-208.dyn.iinet.net.au [124.169.27.208]) by mail.messagingengine.com (Postfix) with ESMTPA id 0A2BB10319; Wed, 3 Apr 2019 00:24:22 -0400 (EDT) From: "Tobin C. Harding" To: Andrew Morton Cc: "Tobin C. Harding" , Roman Gushchin , Alexander Viro , Christoph Hellwig , Pekka Enberg , David Rientjes , Joonsoo Kim , Christopher Lameter , Matthew Wilcox , Miklos Szeredi , Andreas Dilger , Waiman Long , Tycho Andersen , "Theodore Ts'o" , Andi Kleen , David Chinner , Nick Piggin , Rik van Riel , Hugh Dickins , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2 14/14] dcache: Implement object migration Date: Wed, 3 Apr 2019 15:21:27 +1100 Message-Id: <20190403042127.18755-15-tobin@kernel.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190403042127.18755-1-tobin@kernel.org> References: <20190403042127.18755-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 defragment the dcache. Object migration is only possible for dentry objects that are not currently referenced by anyone, i.e. we are using the object migration infrastructure to free unused dentries. Implement isolate and migrate functions for the dentry slab cache. Signed-off-by: Tobin C. Harding --- fs/dcache.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/fs/dcache.c b/fs/dcache.c index 606844ad5171..4387715b7ebb 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "internal.h" #include "mount.h" @@ -3074,6 +3075,90 @@ 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 migrate. + * @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 dentry *dentry; + int i; + + for (i = 0; i < nr; i++) { + dentry = v[i]; + spin_lock(&dentry->d_lock); + /* + * Three sorts of dentries cannot be reclaimed: + * + * 1. dentries that are in the process of being allocated + * or being freed. In that case the dentry is neither + * on the LRU nor hashed. + * + * 2. Fake hashed entries as used for anonymous dentries + * and pipe I/O. The fake hashed entries have d_flags + * set to indicate a hashed entry. However, the + * d_hash field indicates that the entry is not hashed. + * + * 3. dentries that have a backing store that is not + * writable. This is true for tmpsfs and other in + * memory filesystems. Removing dentries from them + * would loose dentries for good. + */ + if ((d_unhashed(dentry) && list_empty(&dentry->d_lru)) || + (!d_unhashed(dentry) && hlist_bl_unhashed(&dentry->d_hash)) || + (dentry->d_inode && + !mapping_cap_writeback_dirty(dentry->d_inode->i_mapping))) { + /* Ignore this dentry */ + v[i] = NULL; + } else { + __dget_dlock(dentry); + } + spin_unlock(&dentry->d_lock); + } + return NULL; /* No need for private data */ +} + +/* + * d_migrate() - Dentry migration callback function. + * @s: The dentry cache. + * @v: Vector of pointers to the objects to migrate. + * @nr: Number of objects in @v. + * @node: The NUMA node where new object should be allocated. + * @private: Returned by d_isolate() (currently %NULL). + * + * Slab has dropped all the locks. Get rid of the refcount obtained + * earlier and also free the object. + */ +static void d_migrate(struct kmem_cache *s, void **v, int nr, + int node, void *_unused) +{ + struct dentry *dentry; + int i; + + for (i = 0; i < nr; i++) { + dentry = v[i]; + if (dentry) + d_invalidate(dentry); + } + + for (i = 0; i < nr; i++) { + dentry = v[i]; + if (dentry) + dput(dentry); + } + + /* + * dentries are freed using RCU so we need to wait until RCU + * operations are complete. + */ + synchronize_rcu(); +} + static __initdata unsigned long dhash_entries; static int __init set_dhash_entries(char *str) { @@ -3119,6 +3204,8 @@ static void __init dcache_init(void) sizeof_field(struct dentry, d_iname), dcache_ctor); + kmem_cache_setup_mobility(dentry_cache, d_isolate, d_migrate); + /* Hash may have been set up in dcache_init_early */ if (!hashdist) return; -- 2.21.0