diff mbox

[v7,4/6] fs/dcache: Print negative dentry warning every min until turned off by user

Message ID 1531413965-5401-5-git-send-email-longman@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Waiman Long July 12, 2018, 4:46 p.m. UTC
When there are too many negative dentries, printing a warning once may
not get the attention of the system administrator. So it is now change
to print a warning every minute until it is turned off by either writing
a 0 into fs/neg-dentry-limit or the limit is increased. After that the
system administrator can look into the reason why there are so many
negative dentries.

Note that the warning is printed when the global negative dentry free
pool is depleted even if there are space in other percpu negative dentry
counts for more.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 fs/dcache.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

Comments

kernel test robot July 17, 2018, 1:24 a.m. UTC | #1
Hi Waiman,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.18-rc4]
[cannot apply to next-20180713]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Waiman-Long/fs-dcache-Track-report-number-of-negative-dentries/20180714-161258
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 
:::::: branch date: 45 minutes ago
:::::: commit date: 45 minutes ago

Note: the linux-review/Waiman-Long/fs-dcache-Track-report-number-of-negative-dentries/20180714-161258 HEAD ca68ee513a450445b269248c2859302c8931a294 builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   fs/dcache.c: In function 'neg_dentry_inc_slowpath':
>> fs/dcache.c:355:8: error: implicit declaration of function 'get_nr_dentry_neg'; did you mean 'neg_dentry_dec'? [-Werror=implicit-function-declaration]
     cnt = get_nr_dentry_neg();
           ^~~~~~~~~~~~~~~~~
           neg_dentry_dec
   cc1: some warnings being treated as errors

# https://github.com/0day-ci/linux/commit/2aa8bf4658af0dbc07ae9ea07d04937a347e3ef4
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 2aa8bf4658af0dbc07ae9ea07d04937a347e3ef4
vim +355 fs/dcache.c

bcc9ba8b Waiman Long 2018-07-12  310  
bcc9ba8b Waiman Long 2018-07-12  311  static noinline void neg_dentry_inc_slowpath(struct dentry *dentry)
bcc9ba8b Waiman Long 2018-07-12  312  {
bcc9ba8b Waiman Long 2018-07-12  313  	long cnt = 0, *pcnt;
2aa8bf46 Waiman Long 2018-07-12  314  	unsigned long current_time;
bcc9ba8b Waiman Long 2018-07-12  315  
bcc9ba8b Waiman Long 2018-07-12  316  	/*
bcc9ba8b Waiman Long 2018-07-12  317  	 * Try to move some negative dentry quota from the global free
bcc9ba8b Waiman Long 2018-07-12  318  	 * pool to the percpu count to allow more negative dentries to
bcc9ba8b Waiman Long 2018-07-12  319  	 * be added to the LRU.
bcc9ba8b Waiman Long 2018-07-12  320  	 */
bcc9ba8b Waiman Long 2018-07-12  321  	pcnt = get_cpu_ptr(&nr_dentry_neg);
bcc9ba8b Waiman Long 2018-07-12  322  	if ((READ_ONCE(ndblk.nfree) > 0) &&
bcc9ba8b Waiman Long 2018-07-12  323  	    (*pcnt > neg_dentry_percpu_limit)) {
bcc9ba8b Waiman Long 2018-07-12  324  		cnt = __neg_dentry_nfree_dec(*pcnt - neg_dentry_percpu_limit);
bcc9ba8b Waiman Long 2018-07-12  325  		*pcnt -= cnt;
bcc9ba8b Waiman Long 2018-07-12  326  	}
bcc9ba8b Waiman Long 2018-07-12  327  	put_cpu_ptr(&nr_dentry_neg);
bcc9ba8b Waiman Long 2018-07-12  328  
2aa8bf46 Waiman Long 2018-07-12  329  	if (cnt)
2aa8bf46 Waiman Long 2018-07-12  330  		goto out;
2aa8bf46 Waiman Long 2018-07-12  331  
bcc9ba8b Waiman Long 2018-07-12  332  	/*
2aa8bf46 Waiman Long 2018-07-12  333  	 * Put out a warning every minute or so if there are just too many
2aa8bf46 Waiman Long 2018-07-12  334  	 * negative dentries.
bcc9ba8b Waiman Long 2018-07-12  335  	 */
2aa8bf46 Waiman Long 2018-07-12  336  	current_time = jiffies;
bcc9ba8b Waiman Long 2018-07-12  337  
2aa8bf46 Waiman Long 2018-07-12  338  	if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD)
2aa8bf46 Waiman Long 2018-07-12  339  		goto out;
2aa8bf46 Waiman Long 2018-07-12  340  	/*
2aa8bf46 Waiman Long 2018-07-12  341  	 * Update the time in ndblk.warn_jiffies and print a warning
2aa8bf46 Waiman Long 2018-07-12  342  	 * if time update is successful.
2aa8bf46 Waiman Long 2018-07-12  343  	 */
2aa8bf46 Waiman Long 2018-07-12  344  	raw_spin_lock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12  345  	if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD) {
2aa8bf46 Waiman Long 2018-07-12  346  		raw_spin_unlock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12  347  		goto out;
2aa8bf46 Waiman Long 2018-07-12  348  	}
2aa8bf46 Waiman Long 2018-07-12  349  	ndblk.warn_jiffies = current_time;
2aa8bf46 Waiman Long 2018-07-12  350  	raw_spin_unlock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12  351  
2aa8bf46 Waiman Long 2018-07-12  352  	/*
2aa8bf46 Waiman Long 2018-07-12  353  	 * Get the current negative dentry count & print a warning.
2aa8bf46 Waiman Long 2018-07-12  354  	 */
2aa8bf46 Waiman Long 2018-07-12 @355  	cnt = get_nr_dentry_neg();
2aa8bf46 Waiman Long 2018-07-12  356  	pr_warn("Warning: Too many negative dentries (%ld). "
2aa8bf46 Waiman Long 2018-07-12  357  		"This warning can be disabled by writing 0 to \"fs/neg-dentry-limit\" or increasing the limit.\n",
2aa8bf46 Waiman Long 2018-07-12  358  		cnt);
2aa8bf46 Waiman Long 2018-07-12  359  out:
2aa8bf46 Waiman Long 2018-07-12  360  	return;
bcc9ba8b Waiman Long 2018-07-12  361  }
bcc9ba8b Waiman Long 2018-07-12  362  

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/fs/dcache.c b/fs/dcache.c
index 1fad368..b2c1585 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -139,6 +139,7 @@  struct dentry_stat_t dentry_stat = {
  * the extra ones will be returned back to the global pool.
  */
 #define NEG_DENTRY_BATCH	(1 << 8)
+#define NEG_WARN_PERIOD 	(60 * HZ)	/* Print a warning every min */
 
 static struct static_key limit_neg_key = STATIC_KEY_INIT_FALSE;
 static int neg_dentry_limit_old;
@@ -150,6 +151,7 @@  struct dentry_stat_t dentry_stat = {
 static struct {
 	raw_spinlock_t nfree_lock;
 	long nfree;			/* Negative dentry free pool */
+	unsigned long warn_jiffies;	/* Time when last warning is printed */
 } ndblk ____cacheline_aligned_in_smp;
 proc_handler proc_neg_dentry_limit;
 
@@ -309,6 +311,7 @@  static long __neg_dentry_nfree_dec(long cnt)
 static noinline void neg_dentry_inc_slowpath(struct dentry *dentry)
 {
 	long cnt = 0, *pcnt;
+	unsigned long current_time;
 
 	/*
 	 * Try to move some negative dentry quota from the global free
@@ -323,12 +326,38 @@  static noinline void neg_dentry_inc_slowpath(struct dentry *dentry)
 	}
 	put_cpu_ptr(&nr_dentry_neg);
 
+	if (cnt)
+		goto out;
+
 	/*
-	 * Put out a warning if there are too many negative dentries.
+	 * Put out a warning every minute or so if there are just too many
+	 * negative dentries.
 	 */
-	if (!cnt)
-		pr_warn_once("There are too many negative dentries.");
+	current_time = jiffies;
+
+	if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD)
+		goto out;
+	/*
+	 * Update the time in ndblk.warn_jiffies and print a warning
+	 * if time update is successful.
+	 */
+	raw_spin_lock(&ndblk.nfree_lock);
+	if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD) {
+		raw_spin_unlock(&ndblk.nfree_lock);
+		goto out;
+	}
+	ndblk.warn_jiffies = current_time;
+	raw_spin_unlock(&ndblk.nfree_lock);
 
+	/*
+	 * Get the current negative dentry count & print a warning.
+	 */
+	cnt = get_nr_dentry_neg();
+	pr_warn("Warning: Too many negative dentries (%ld). "
+		"This warning can be disabled by writing 0 to \"fs/neg-dentry-limit\" or increasing the limit.\n",
+		cnt);
+out:
+	return;
 }
 
 /*