From 6de338a2d9904ef5a67552b024491700523074a3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 4 May 2012 00:13:20 +0200 Subject: readhead: temporarily lower the kernel's read_ahead_kb setting while collecting While collecting readahead data we want to know exactly what userspace accesses unblurred by the kernel's read_ahead_kb. Hence lower this during collection, and raise it afterwards. This is mostly based on ideas and code by Auke Kok. --- src/readahead/readahead-common.c | 82 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) (limited to 'src/readahead/readahead-common.c') diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c index 4e8e636975..99dbac2525 100644 --- a/src/readahead/readahead-common.c +++ b/src/readahead/readahead-common.c @@ -210,7 +210,7 @@ finish: #define BUMP_REQUEST_NR (16*1024) -int bump_request_nr(const char *p) { +int block_bump_request_nr(const char *p) { struct stat st; uint64_t u; char *ap = NULL, *line = NULL; @@ -267,3 +267,83 @@ finish: return r; } + +int block_get_readahead(const char *p, uint64_t *bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + uint64_t u; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + r = read_one_line_file(ap, &line); + if (r < 0) + goto finish; + + r = safe_atou64(line, &u); + if (r < 0) + goto finish; + + *bytes = u * 1024ULL; + +finish: + free(ap); + free(line); + + return r; +} + +int block_set_readahead(const char *p, uint64_t bytes) { + struct stat st; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + + assert(p); + assert(bytes); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) { + r = -ENOMEM; + goto finish; + } + + if (asprintf(&line, "%llu", (unsigned long long) bytes / 1024ULL) < 0) { + r = -ENOMEM; + goto finish; + } + + r = write_one_line_file(ap, line); + if (r < 0) + goto finish; + +finish: + free(ap); + free(line); + + return r; +} -- cgit v1.2.3-54-g00ecf