NFS client regression, simple test program
From: Jakob Oestergaard
Date: Fri Mar 31 2006 - 06:20:44 EST
Attached is a small test program that exposes the regression.
Kernel LEADING_EMPTY_SPACE wall-clock time to run
2.6.15 0 0.2s
2.6.15 1 29.3s
2.6.14.7 0 0.2s
2.6.14.7 1 0.2s
So it seems that if a file is repeatedly read from and written to, it
matters a lot for later kernels whether or not the blocks that are
worked on, are offset a single byte or not...
Any ideas?
--
/ jakob
/*
* Tiny benchmark for Linux NFS client problem 2.6.14.7->2.6.15
*
* By Jakob Oestergaard, joe@xxxxxxxxxxxxx / joe@xxxxxxxxxxxx
*
* Compile as:
* gcc -o nfsbench -O3 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 nfsbench.c
*/
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdint.h>
#define MYBLOCKSIZE 32768
#define MYSUBSIZE 1024
/* Set this define to non-zero to expose the regression */
#define LEADING_EMPTY_SPACE 1
int main(int argc, char **argv)
{
int testfd = open("testfile", O_RDWR|O_CREAT|O_TRUNC, 0666);
off_t blockoff;
uint8_t garbage[MYBLOCKSIZE];
memset(garbage, 42, sizeof garbage);
for (blockoff = LEADING_EMPTY_SPACE;
blockoff < 10 * 1024 * 1024;
blockoff += MYBLOCKSIZE) {
off_t inblockoff;
lseek(testfd, blockoff, SEEK_SET);
write(testfd, garbage, MYBLOCKSIZE);
for (inblockoff = MYBLOCKSIZE / 4;
inblockoff < MYBLOCKSIZE * 3 / 4;
inblockoff += MYSUBSIZE * 2) {
uint8_t gdata[MYBLOCKSIZE];
lseek(testfd, blockoff, SEEK_SET);
read(testfd, gdata, MYBLOCKSIZE);
lseek(testfd, -inblockoff, SEEK_CUR);
write(testfd, gdata + inblockoff, MYSUBSIZE);
}
}
close(testfd);
}