lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 18 Sep 2017 14:20:34 -0400
From:   Waiman Long <longman@...hat.com>
To:     Alexander Viro <viro@...iv.linux.org.uk>
Cc:     linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Jan Kara <jack@...e.cz>,
        "Paul E. McKenney" <paulmck@...ux.vnet.ibm.com>,
        Andrew Morton <akpm@...ux-foundation.org>,
        Ingo Molnar <mingo@...nel.org>,
        Miklos Szeredi <mszeredi@...hat.com>,
        Matthew Wilcox <willy@...radead.org>,
        Larry Woodman <lwoodman@...hat.com>,
        James Bottomley <James.Bottomley@...senPartnership.com>,
        "Wangkai (Kevin C)" <wangkai86@...wei.com>,
        Waiman Long <longman@...hat.com>
Subject: [PATCH v4 6/6] fs/dcache: Autotuning of negative dentry limit

To have a proper balance of positive and negative dentries, the free
pool negative dentry limit can be dynamically tuned up to no more than
the number of positive dentries that have ever been used. The total
positive dentry count is computed at a frequency of no more than once
every 5 minutes.

Signed-off-by: Waiman Long <longman@...hat.com>
---
 fs/dcache.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/fs/dcache.c b/fs/dcache.c
index f46603e..ac68fbd 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -143,12 +143,19 @@ struct dentry_stat_t dentry_stat = {
  * If a per-cpu counter runs out of negative dentries, it can borrow extra
  * ones from the global free pool. If it has more than its percpu limit,
  * the extra ones will be returned back to the global pool.
+ *
+ * In order to have a proper balance between negative and positive dentries,
+ * the free pool negative dentry limit can be tuned up dynamically at run
+ * time to no more than the highest number of positive dentries that were
+ * ever used. Total positive dentry count is checked no more than once
+ * every 5 mins to reduce performance impact.
  */
 #define NEG_DENTRY_PC		2
 #define NEG_DENTRY_BATCH	(1 << 8)
 #define NEG_PRUNING_SIZE	(1 << 6)
 #define NEG_PRUNING_SLOW_RATE	(HZ/10)
 #define NEG_PRUNING_FAST_RATE	(HZ/50)
+#define NEG_COUNT_CHECK_PERIOD	(HZ*5*60)
 #define NEG_IS_SB_UMOUNTING(sb)	\
 	unlikely(!(sb)->s_root || !((sb)->s_flags & MS_ACTIVE))
 
@@ -163,6 +170,7 @@ struct dentry_stat_t dentry_stat = {
 	long nfree;			/* Negative dentry free pool */
 	struct super_block *prune_sb;	/* Super_block for pruning */
 	atomic_long_t nr_neg_killed;	/* # of negative entries killed */
+	unsigned long last_jiffies;	/* Last time +ve count is checked */
 } ndblk ____cacheline_aligned_in_smp;
 
 static void prune_negative_dentry(struct work_struct *work);
@@ -1469,6 +1477,36 @@ static void prune_negative_dentry(struct work_struct *work)
 	ndblk.n_pos += freed - (ndblk.n_neg - last_n_neg);
 
 	/*
+	 * Also check the total negative & positive dentries count to see
+	 * if we can increase the free pool negative dentry limit.
+	 */
+	if (time_after(jiffies, ndblk.last_jiffies + NEG_COUNT_CHECK_PERIOD)) {
+		unsigned long pos = 0, neg = 0;
+		int i;
+
+		/*
+		 * The positive count may include a small number of
+		 * negative dentries in transit, but that should be
+		 * negligible.
+		 */
+		for_each_possible_cpu(i) {
+			pos += per_cpu(nr_dentry, i);
+			neg += per_cpu(nr_dentry_neg, i);
+		}
+		pos -= neg;
+
+		if (unlikely(pos > neg_dentry_nfree_init)) {
+			unsigned long inc = pos - neg_dentry_nfree_init;
+
+			raw_spin_lock(&ndblk.nfree_lock);
+			ndblk.nfree += inc;
+			raw_spin_unlock(&ndblk.nfree_lock);
+			WRITE_ONCE(neg_dentry_nfree_init, pos);
+		}
+		ndblk.last_jiffies = jiffies;
+	}
+
+	/*
 	 * Continue delayed pruning until negative dentry free pool is at
 	 * least 1/2 of the initial value, the super_block has no more
 	 * negative dentries left at the front, or unmounting is in
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ