delayacct: track delays from thrashing cache pages
[muen/linux.git] / mm / filemap.c
index 7997adce5a29a2a515107c06d1ecadefd2151472..01a841f17bf4af7d762297302d8534a3a30460cc 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/cleancache.h>
 #include <linux/shmem_fs.h>
 #include <linux/rmap.h>
+#include <linux/delayacct.h>
 #include "internal.h"
 
 #define CREATE_TRACE_POINTS
@@ -1073,8 +1074,15 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q,
 {
        struct wait_page_queue wait_page;
        wait_queue_entry_t *wait = &wait_page.wait;
+       bool thrashing = false;
        int ret = 0;
 
+       if (bit_nr == PG_locked && !PageSwapBacked(page) &&
+           !PageUptodate(page) && PageWorkingset(page)) {
+               delayacct_thrashing_start();
+               thrashing = true;
+       }
+
        init_wait(wait);
        wait->flags = lock ? WQ_FLAG_EXCLUSIVE : 0;
        wait->func = wake_page_function;
@@ -1113,6 +1121,9 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q,
 
        finish_wait(q, wait);
 
+       if (thrashing)
+               delayacct_thrashing_end();
+
        /*
         * A signal could leave PageWaiters set. Clearing it here if
         * !waitqueue_active would be possible (by open-coding finish_wait),