Index: linux-2.6-git/kernel/sysctl.c =================================================================== --- linux-2.6-git.orig/kernel/sysctl.c 2010-02-16 11:06:29.000000000 +0100 +++ linux-2.6-git/kernel/sysctl.c 2010-02-16 13:38:48.000000000 +0100 @@ -264,9 +264,64 @@ extern unsigned long perf_count_failed_pages_direct_reclaim_but_progress; extern unsigned long perf_count_call_congestion_wait_from_alloc_pages_high_priority; extern unsigned long perf_count_call_congestion_wait_from_alloc_pages_slowpath; + +extern unsigned long long perf_count_direct_reclaim_slow_dursum_pre_ttf_2_post_ttf; +extern unsigned long long perf_count_direct_reclaim_slow_dursum_post_ttf_2_pre_get_page; +extern unsigned long long perf_count_direct_reclaim_slow_dursum_pre_get_page_2_post_ttf; +extern unsigned long long perf_count_direct_reclaim_fast_dursum_pre_ttf_2_post_ttf; +extern unsigned long long perf_count_direct_reclaim_fast_dursum_post_ttf_2_pre_get_page; +extern unsigned long long perf_count_direct_reclaim_fast_dursum_pre_get_page_2_post_ttf; static struct ctl_table perf_table[] = { { .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_slow_dursum_pre_ttf_2_post_ttf", + .data = &perf_count_direct_reclaim_slow_dursum_pre_ttf_2_post_ttf, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_slow_dursum_post_ttf_2_pre_get_page", + .data = &perf_count_direct_reclaim_slow_dursum_post_ttf_2_pre_get_page, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_slow_dursum_pre_get_page_2_post_get_page", + .data = &perf_count_direct_reclaim_slow_dursum_pre_get_page_2_post_get_page, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_fast_dursum_pre_ttf_2_post_ttf", + .data = &perf_count_direct_reclaim_fast_dursum_pre_ttf_2_post_ttf, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_fast_dursum_post_ttf_2_pre_get_page", + .data = &perf_count_direct_reclaim_fast_dursum_post_ttf_2_pre_get_page, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_count_direct_reclaim_fast_dursum_pre_get_page_2_post_get_page", + .data = &perf_count_direct_reclaim_fast_dursum_pre_get_page_2_post_get_page, + .mode = 0666, + .maxlen = sizeof(unsigned long long), + .proc_handler = &proc_doulongvec_minmax, + }, + { + .ctl_name = CTL_UNNUMBERED, .procname = "perf_count_congestion_wait", .data = &perf_count_congestion_wait, .mode = 0666, Index: linux-2.6-git/mm/page_alloc.c =================================================================== --- linux-2.6-git.orig/mm/page_alloc.c 2010-02-16 11:06:29.000000000 +0100 +++ linux-2.6-git/mm/page_alloc.c 2010-02-16 13:38:24.000000000 +0100 @@ -51,6 +51,7 @@ #include #include +#include #include #include "internal.h" @@ -1655,6 +1656,17 @@ unsigned long perf_count_failed_pages_direct_reclaim = 0; unsigned long perf_count_failed_pages_direct_reclaim_but_progress = 0; +unsigned long long perf_count_direct_reclaim_slow_dursum_pre_ttf_2_post_ttf = 0; +unsigned long long perf_count_direct_reclaim_slow_dursum_post_ttf_2_pre_get_page = 0; +unsigned long long perf_count_direct_reclaim_slow_dursum_pre_get_page_2_post_get_page = 0; +unsigned long long perf_count_direct_reclaim_fast_dursum_pre_ttf_2_post_ttf = 0; +unsigned long long perf_count_direct_reclaim_fast_dursum_post_ttf_2_pre_get_page = 0; +unsigned long long perf_count_direct_reclaim_fast_dursum_pre_get_page_2_post_get_page = 0; + +static inline unsigned long long tod_duration_ns(unsigned long long from, unsigned long long to) { + return ((to*125)>>9)-((from*125)>>9); +} + /* The really slow allocator path where we enter direct reclaim */ static inline struct page * __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, @@ -1665,6 +1677,7 @@ struct page *page = NULL; struct reclaim_state reclaim_state; struct task_struct *p = current; + unsigned long long t1,t2,t3,t4; cond_resched(); @@ -1675,8 +1688,12 @@ reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; + t1 = get_clock(); + *did_some_progress = try_to_free_pages(zonelist, order, gfp_mask, nodemask); + t2 = get_clock(); + p->reclaim_state = NULL; lockdep_clear_current_reclaim_state(); p->flags &= ~PF_MEMALLOC; @@ -1686,17 +1703,28 @@ if (order != 0) drain_all_pages(); + t3 = get_clock(); if (likely(*did_some_progress)) page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags, preferred_zone, migratetype); + t4 = get_clock(); perf_count_pages_direct_reclaim++; if (!page) perf_count_failed_pages_direct_reclaim++; - if (!page && (*did_some_progress)) + if (!page && (*did_some_progress)) { perf_count_failed_pages_direct_reclaim_but_progress++; + perf_count_direct_reclaim_slow_dursum_pre_ttf_2_post_ttf += tod_duration_ns(t1,t2); + perf_count_direct_reclaim_slow_dursum_post_ttf_2_pre_get_page += tod_duration_ns(t2,t3); + perf_count_direct_reclaim_slow_dursum_pre_get_page_2_post_get_page += tod_duration_ns(t3,t4); + } + else { + perf_count_direct_reclaim_fast_dursum_pre_ttf_2_post_ttf += tod_duration_ns(t1,t2); + perf_count_direct_reclaim_fast_dursum_post_ttf_2_pre_get_page += tod_duration_ns(t2,t3); + perf_count_direct_reclaim_fast_dursum_pre_get_page_2_post_get_page += tod_duration_ns(t3,t4); + } return page; }