Message ID | 1531413965-5401-7-git-send-email-longman@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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: h8300-h8300h-sim_defconfig (attached as .config)
compiler: h8300-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=h8300
:::::: branch date: 65 minutes ago
:::::: commit date: 65 minutes ago
All errors (new ones prefixed by >>):
fs/dcache.c: In function 'neg_dentry_inc_slowpath':
>> fs/dcache.c:374:8: error: implicit declaration of function 'get_nr_dentry_neg'; did you mean 'get_nr_dirty_inodes'? [-Werror=implicit-function-declaration]
cnt = get_nr_dentry_neg();
^~~~~~~~~~~~~~~~~
get_nr_dirty_inodes
cc1: some warnings being treated as errors
# https://github.com/0day-ci/linux/commit/ca68ee513a450445b269248c2859302c8931a294
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout ca68ee513a450445b269248c2859302c8931a294
vim +374 fs/dcache.c
bcc9ba8b Waiman Long 2018-07-12 311
2ccdd02c Waiman Long 2018-07-12 312 static noinline int neg_dentry_inc_slowpath(struct dentry *dentry)
bcc9ba8b Waiman Long 2018-07-12 313 {
bcc9ba8b Waiman Long 2018-07-12 314 long cnt = 0, *pcnt;
2aa8bf46 Waiman Long 2018-07-12 315 unsigned long current_time;
bcc9ba8b Waiman Long 2018-07-12 316
bcc9ba8b Waiman Long 2018-07-12 317 /*
bcc9ba8b Waiman Long 2018-07-12 318 * Try to move some negative dentry quota from the global free
bcc9ba8b Waiman Long 2018-07-12 319 * pool to the percpu count to allow more negative dentries to
bcc9ba8b Waiman Long 2018-07-12 320 * be added to the LRU.
bcc9ba8b Waiman Long 2018-07-12 321 */
bcc9ba8b Waiman Long 2018-07-12 322 pcnt = get_cpu_ptr(&nr_dentry_neg);
bcc9ba8b Waiman Long 2018-07-12 323 if ((READ_ONCE(ndblk.nfree) > 0) &&
bcc9ba8b Waiman Long 2018-07-12 324 (*pcnt > neg_dentry_percpu_limit)) {
bcc9ba8b Waiman Long 2018-07-12 325 cnt = __neg_dentry_nfree_dec(*pcnt - neg_dentry_percpu_limit);
bcc9ba8b Waiman Long 2018-07-12 326 *pcnt -= cnt;
bcc9ba8b Waiman Long 2018-07-12 327 }
bcc9ba8b Waiman Long 2018-07-12 328 put_cpu_ptr(&nr_dentry_neg);
bcc9ba8b Waiman Long 2018-07-12 329
2aa8bf46 Waiman Long 2018-07-12 330 if (cnt)
2aa8bf46 Waiman Long 2018-07-12 331 goto out;
2aa8bf46 Waiman Long 2018-07-12 332
bcc9ba8b Waiman Long 2018-07-12 333 /*
2ccdd02c Waiman Long 2018-07-12 334 * Kill the dentry by setting the DCACHE_KILL_NEGATIVE flag and
2ccdd02c Waiman Long 2018-07-12 335 * dec the negative dentry count if the enforcing option is on.
2ccdd02c Waiman Long 2018-07-12 336 */
2ccdd02c Waiman Long 2018-07-12 337 if (neg_dentry_enforce) {
2ccdd02c Waiman Long 2018-07-12 338 dentry->d_flags |= DCACHE_KILL_NEGATIVE;
2ccdd02c Waiman Long 2018-07-12 339 this_cpu_dec(nr_dentry_neg);
2ccdd02c Waiman Long 2018-07-12 340
2ccdd02c Waiman Long 2018-07-12 341 /*
2ccdd02c Waiman Long 2018-07-12 342 * When the dentry is not put into the LRU, we
2ccdd02c Waiman Long 2018-07-12 343 * need to keep the reference count to 1 to
2ccdd02c Waiman Long 2018-07-12 344 * avoid problem when killing it.
2ccdd02c Waiman Long 2018-07-12 345 */
2ccdd02c Waiman Long 2018-07-12 346 WARN_ON_ONCE(dentry->d_lockref.count);
2ccdd02c Waiman Long 2018-07-12 347 dentry->d_lockref.count = 1;
2ccdd02c Waiman Long 2018-07-12 348 return -1; /* Kill the dentry now */
2ccdd02c Waiman Long 2018-07-12 349 }
2ccdd02c Waiman Long 2018-07-12 350
2ccdd02c Waiman Long 2018-07-12 351 /*
2aa8bf46 Waiman Long 2018-07-12 352 * Put out a warning every minute or so if there are just too many
2aa8bf46 Waiman Long 2018-07-12 353 * negative dentries.
bcc9ba8b Waiman Long 2018-07-12 354 */
2aa8bf46 Waiman Long 2018-07-12 355 current_time = jiffies;
bcc9ba8b Waiman Long 2018-07-12 356
2aa8bf46 Waiman Long 2018-07-12 357 if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD)
2aa8bf46 Waiman Long 2018-07-12 358 goto out;
2aa8bf46 Waiman Long 2018-07-12 359 /*
2aa8bf46 Waiman Long 2018-07-12 360 * Update the time in ndblk.warn_jiffies and print a warning
2aa8bf46 Waiman Long 2018-07-12 361 * if time update is successful.
2aa8bf46 Waiman Long 2018-07-12 362 */
2aa8bf46 Waiman Long 2018-07-12 363 raw_spin_lock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12 364 if (current_time < ndblk.warn_jiffies + NEG_WARN_PERIOD) {
2aa8bf46 Waiman Long 2018-07-12 365 raw_spin_unlock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12 366 goto out;
2aa8bf46 Waiman Long 2018-07-12 367 }
2aa8bf46 Waiman Long 2018-07-12 368 ndblk.warn_jiffies = current_time;
2aa8bf46 Waiman Long 2018-07-12 369 raw_spin_unlock(&ndblk.nfree_lock);
2aa8bf46 Waiman Long 2018-07-12 370
2aa8bf46 Waiman Long 2018-07-12 371 /*
2aa8bf46 Waiman Long 2018-07-12 372 * Get the current negative dentry count & print a warning.
2aa8bf46 Waiman Long 2018-07-12 373 */
2aa8bf46 Waiman Long 2018-07-12 @374 cnt = get_nr_dentry_neg();
2aa8bf46 Waiman Long 2018-07-12 375 pr_warn("Warning: Too many negative dentries (%ld). "
2ccdd02c Waiman Long 2018-07-12 376 "This warning can be disabled by writing 0 to \"fs/neg-dentry-limit\", increasing the limit or writing 1 to \"fs/neg-dentry-enforce\".\n",
2aa8bf46 Waiman Long 2018-07-12 377 cnt);
2aa8bf46 Waiman Long 2018-07-12 378 out:
2ccdd02c Waiman Long 2018-07-12 379 return 0;
bcc9ba8b Waiman Long 2018-07-12 380 }
bcc9ba8b Waiman Long 2018-07-12 381
:::::: The code at line 374 was first introduced by commit
:::::: 2aa8bf4658af0dbc07ae9ea07d04937a347e3ef4 fs/dcache: Print negative dentry warning every min until turned off by user
:::::: TO: Waiman Long <longman@redhat.com>
:::::: CC: 0day robot <lkp@intel.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/fs/Kconfig b/fs/Kconfig index ac474a6..b521941 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -113,6 +113,16 @@ source "fs/autofs/Kconfig" source "fs/fuse/Kconfig" source "fs/overlayfs/Kconfig" +# +# Track and limit the number of negative dentries allowed in the system. +# +config DCACHE_LIMIT_NEG_ENTRY + bool "Track & limit negative dcache entries" + default y + help + This option enables the tracking and limiting of the total + number of negative dcache entries allowable in the filesystem. + menu "Caches" source "fs/fscache/Kconfig" diff --git a/fs/dcache.c b/fs/dcache.c index 843c8be..dccfe39 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -141,6 +141,7 @@ struct dentry_stat_t dentry_stat = { #define NEG_DENTRY_BATCH (1 << 8) #define NEG_WARN_PERIOD (60 * HZ) /* Print a warning every min */ +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY static struct static_key limit_neg_key = STATIC_KEY_INIT_FALSE; static int neg_dentry_limit_old; int neg_dentry_limit; @@ -156,6 +157,7 @@ struct dentry_stat_t dentry_stat = { unsigned long warn_jiffies; /* Time when last warning is printed */ } ndblk ____cacheline_aligned_in_smp; proc_handler proc_neg_dentry_limit; +#endif /* CONFIG_DCACHE_LIMIT_NEG_ENTRY */ static DEFINE_PER_CPU(long, nr_dentry); static DEFINE_PER_CPU(long, nr_dentry_unused); @@ -200,7 +202,9 @@ static long get_nr_dentry_neg(void) for_each_possible_cpu(i) sum += per_cpu(nr_dentry_neg, i); +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY sum += neg_dentry_nfree_init - ndblk.nfree; +#endif return sum < 0 ? 0 : sum; } @@ -267,6 +271,7 @@ static inline int dentry_string_cmp(const unsigned char *cs, const unsigned char #endif +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY /* * Decrement negative dentry count if applicable. */ @@ -289,12 +294,6 @@ static void __neg_dentry_dec(struct dentry *dentry) } } -static inline void neg_dentry_dec(struct dentry *dentry) -{ - if (unlikely(d_is_negative(dentry))) - __neg_dentry_dec(dentry); -} - /* * Try to decrement the negative dentry free pool by NEG_DENTRY_BATCH. * The actual decrement returned by the function may be smaller. @@ -454,6 +453,20 @@ int proc_neg_dentry_limit(struct ctl_table *ctl, int write, return 0; } EXPORT_SYMBOL_GPL(proc_neg_dentry_limit); +#else /* CONFIG_DCACHE_LIMIT_NEG_ENTRY */ + +static inline void __neg_dentry_dec(struct dentry *dentry) +{ + this_cpu_dec(nr_dentry_neg); +} + +#endif /* CONFIG_DCACHE_LIMIT_NEG_ENTRY */ + +static inline void neg_dentry_dec(struct dentry *dentry) +{ + if (unlikely(d_is_negative(dentry))) + __neg_dentry_dec(dentry); +} static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount) { @@ -642,6 +655,7 @@ static void d_lru_add(struct dentry *dentry) dentry->d_flags |= DCACHE_LRU_LIST; this_cpu_inc(nr_dentry_unused); if (d_is_negative(dentry)) { +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY if (dentry->d_flags & DCACHE_NEW_NEGATIVE) { dentry->d_flags &= ~DCACHE_NEW_NEGATIVE; if (unlikely(neg_dentry_inc(dentry) < 0)) { @@ -658,6 +672,7 @@ static void d_lru_add(struct dentry *dentry) &dentry->d_sb->s_dentry_lru, &dentry->d_lru)); return; } +#endif /* * We don't do limit check for existing negative * dentries. @@ -3431,7 +3446,9 @@ static void __init dcache_init(void) SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD|SLAB_ACCOUNT, d_iname); +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY raw_spin_lock_init(&ndblk.nfree_lock); +#endif /* Hash may have been set up in dcache_init_early */ if (!hashdist) diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 934a6d9..11729a1 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -612,10 +612,12 @@ struct name_snapshot { void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *); void release_dentry_name_snapshot(struct name_snapshot *); +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY /* * Negative dentry related declarations. */ extern int neg_dentry_limit; extern int neg_dentry_enforce; +#endif #endif /* __LINUX_DCACHE_H */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index a24101e..732c624 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1851,6 +1851,7 @@ static int sysrq_sysctl_handler(struct ctl_table *table, int write, .proc_handler = proc_dointvec_minmax, .extra1 = &one, }, +#ifdef CONFIG_DCACHE_LIMIT_NEG_ENTRY { .procname = "neg-dentry-limit", .data = &neg_dentry_limit, @@ -1869,6 +1870,7 @@ static int sysrq_sysctl_handler(struct ctl_table *table, int write, .extra1 = &zero, .extra2 = &one, }, +#endif { } };
The tracking and limit of negative dentries in a filesystem is a useful addition. However, for users who want to reduce the kernel size as much as possible, this feature will probably be on the chopping block. To suit those users, a default-y config option DCACHE_LIMIT_NEG_ENTRY is added so that the negative dentry limiting code can be configured out, if necessary. Signed-off-by: Waiman Long <longman@redhat.com> --- fs/Kconfig | 10 ++++++++++ fs/dcache.c | 29 +++++++++++++++++++++++------ include/linux/dcache.h | 2 ++ kernel/sysctl.c | 2 ++ 4 files changed, 37 insertions(+), 6 deletions(-)