Misunderstanding about Page Cache and dirty_background_bytes
Solution 1:
This can be a side-effect of your dd
command unlinking and creating a new disk_test at each iteration.
Try to first create a target file with a single dd if=/dev/zero of=/data/disk_test bs=1M count=2000
command, then run your loop with dd if=/dev/zero of=/data/disk_test bs=1M count=2000 conv=notrunc,nocreat
command.
Explanation: notrunc
make a difference because in the past some heuristic was added to prevent applications doing replace-via-rename and replace-via-truncate and crashing just afterwards to corrupt their data. This heuristic basically force-flushes data belonging to open->written->truncated files.
From mount man page:
auto_da_alloc|noauto_da_alloc
Many broken applications don't use fsync() when noauto_da_alloc replacing existing files via patterns such as
fd = open("foo.new")/write(fd,..)/close(fd)/ rename("foo.new", "foo")
or worse yet
fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
If auto_da_alloc is enabled, ext4 will detect the replace-via-rename and replace-via-truncate patterns and force that any delayed allocation blocks are allocated such that at the next journal commit, in the default data=ordered mode, the data blocks of the new file are forced to disk before the rename() operation is commited. This provides roughly the same level of guarantees as ext3, and avoids the "zero-length" problem that can happen when a system crashes before the delayed allocation blocks are forced to disk.
Give also a loot at XFS FAQ