Bug 9838

Summary: Weird behaviour for /proc/sys/vm/dirty_writeback_centisecs in 2.6.24
Product: Memory Management Reporter: Arvid Norlander (anmaster)
Component: OtherAssignee: Alexey Dobriyan (adobriyan)
Status: RESOLVED CODE_FIX    
Severity: normal CC: adobriyan, alan, bunk
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.27 Subsystem:
Regression: Yes Bisected commit-id:
Attachments: Kernel .config which fails.

Description Arvid Norlander 2008-01-28 13:20:12 UTC
Latest working kernel version: 2.6.23 (that I know of)
Earliest failing kernel version: Unknown, but 2.6.24-rc8 is known to have the problem.
Distribution: Gentoo Linux
Hardware Environment: Sempron 3300+ running in x86_64 mode
Software Environment: No idea what to put here.
Problem Description:
The value you echo to /proc/sys/vm/dirty_writeback_centisecs always get set to:
"the value you echo to it" - 1

This bug was first reported to the gentoo bug tracker at:
https://bugs.gentoo.org/show_bug.cgi?id=207902
but was found to affect mainline kernels too and therfore I report it to here now.

This is related to memory management only in the sense that the sysctl is in memory management section.

Steps to reproduce:
1. echo 6000 > /proc/sys/vm/dirty_writeback_centisecs
2. cat /proc/sys/vm/dirty_writeback_centisecs
3. echo 500 > /proc/sys/vm/dirty_writeback_centisecs
4. cat /proc/sys/vm/dirty_writeback_centisecs

Actual Results:  
# echo 6000 > /proc/sys/vm/dirty_writeback_centisecs
# cat /proc/sys/vm/dirty_writeback_centisecs
5999
# echo 500 > /proc/sys/vm/dirty_writeback_centisecs
# cat /proc/sys/vm/dirty_writeback_centisecs
499

Expected Results:  
The value should be the same as I set, and nothing in either kernel source or
/usr/src/linux/Documentation indicates that the value will get set to one
lower, so it doesn't look like this is intended. If it is intended it should be documented.
Comment 1 Alan 2008-09-24 06:25:00 UTC
Still present in 2.6.27-rc6
Comment 2 Alexey Dobriyan 2009-03-08 05:05:44 UTC
Attach .config (especially CONFIG_HZ).
Comment 3 Arvid Norlander 2009-03-08 06:19:46 UTC
I'm currently not on a vanilla kernel any more, so I don't know how useful this will be to you. However I did test on a 32-bit x86 Linux (running Arch Linux) with a vanilla 2.6.28.4 kernel, and it did not have the issue. My main computer (on a 2.6.27-gentoo-r8 kernel, x86_64) does have the issue.

Both system use CONFIG_NO_HZ=y.

The system with the issue:
$ zgrep CONFIG_HZ /proc/config.gz
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
The system without the issue:
$ zgrep CONFIG_HZ /proc/config.gz
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250

I could try a 1000 Hz kernel on the latter system later today, the system with the issue I may have time to test on within a few weeks. (Since I'm currently not at home I don't want to install a test a new kernel remotely if something goes wrong...)
Comment 4 Arvid Norlander 2009-03-08 07:18:48 UTC
Created attachment 20454 [details]
Kernel .config which fails.

I tested with the following config on vanilla 2.6.28.7 (x86) and reproduced the issue. The same config with CONFIG_HZ=250 does not exhibit the issue.
Comment 5 Alexey Dobriyan 2009-03-08 09:46:34 UTC
It's HZ=1000, reproduced.
Comment 6 Alexey Dobriyan 2009-03-30 23:06:42 UTC
Patch sent: "[PATCH] proc_dointvec_userhz_jiffies "breakage""
http://marc.info/?l=linux-kernel&m=123653898122373&w=2

Every sysctl using proc_dointvec_userhz_jiffies() should have it too.

The little problem is that for some sysctl variables converting each time
is not acceptable, so custom sysctl hook is required.

Other than that proc_dointvec_userhz_jiffies() can probably go.

mm itself doesn't misbehave, just shows off-by-one value on the output path.
Comment 7 Alexey Dobriyan 2009-10-14 02:13:31 UTC
704503d836042d4a4c7685b7036e7de0418fbc0f
mm: fix proc_dointvec_userhz_jiffies "breakage"

22ef37eed673587ac984965dc88ba94c68873291
page-writeback: fix the calculation of the oldest_jif in wb_kupdate()