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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to