Messages in this thread Patch in this message |  | | Date | Sun, 10 Jun 2001 01:51:47 +1000 | | From | Andrew Morton <> | | Subject | [patch] truncate_inode_pages |
| |
The ftruncate() in this program:
#include <unistd.h> #include <fcntl.h> #include <sys/mman.h>
int clean = 64 * 1024 * 1024; int dirty = 64 * 1024 * 1024;
main() { int fd = open("foo", O_RDWR|O_TRUNC|O_CREAT, 0666); void *mem;
ftruncate(fd, clean + dirty); mem = mmap(0, clean + dirty, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); memset(mem, 0, clean + dirty); msync(mem, clean, MS_SYNC); ftruncate(fd, clean); }
takes 45 seconds CPU time due to the O(clean * dirty) algorithm in truncate_inode_pages(). The machine is locked up for the duration. The patch reduces this to 20 milliseconds via an O(clean + dirty) algorithm.
--- linux-2.4.5/mm/filemap.c Mon May 28 13:31:49 2001 +++ linux-akpm/mm/filemap.c Sun Jun 10 01:27:09 2001 @@ -273,15 +273,24 @@ { unsigned long start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; unsigned partial = lstart & (PAGE_CACHE_SIZE - 1); + int complete; -repeat: spin_lock(&pagecache_lock); - if (truncate_list_pages(&mapping->clean_pages, start, &partial)) - goto repeat; - if (truncate_list_pages(&mapping->dirty_pages, start, &partial)) - goto repeat; - if (truncate_list_pages(&mapping->locked_pages, start, &partial)) - goto repeat; + do { + complete = 1; + while (truncate_list_pages(&mapping->clean_pages, start, &partial)) { + spin_lock(&pagecache_lock); + complete = 0; + } + while (truncate_list_pages(&mapping->dirty_pages, start, &partial)) { + spin_lock(&pagecache_lock); + complete = 0; + } + while (truncate_list_pages(&mapping->locked_pages, start, &partial)) { + spin_lock(&pagecache_lock); + complete = 0; + } + } while (!complete); spin_unlock(&pagecache_lock); } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |