[experimental][PATCH] mm,vmstat: per cpu stat flush too when per cpu page cache flushed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When memory shortage, we are using drain_pages() for flushing per cpu
page cache. In this case, per cpu stat should be flushed too. because
now we are under memory shortage and we need to know exact free pages.

Otherwise get_page_from_freelist() may fail even though pcp was flushed.


Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx>
---
 include/linux/vmstat.h |    5 +++++
 mm/page_alloc.c        |    1 +
 mm/vmstat.c            |   12 ++++++++++++
 3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 1997988..df777f4 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -253,6 +253,8 @@ extern void __inc_zone_state(struct zone *, enum zone_stat_item);
 extern void dec_zone_state(struct zone *, enum zone_stat_item);
 extern void __dec_zone_state(struct zone *, enum zone_stat_item);
 
+void __flush_zone_state(struct zone *zone, enum zone_stat_item item);
+
 void refresh_cpu_vm_stats(int);
 void refresh_zone_stat_thresholds(void);
 #else /* CONFIG_SMP */
@@ -299,6 +301,9 @@ static inline void __dec_zone_page_state(struct page *page,
 #define dec_zone_page_state __dec_zone_page_state
 #define mod_zone_page_state __mod_zone_page_state
 
+static inline void
+__flush_zone_state(struct zone *zone, enum zone_stat_item item) { }
+
 static inline void refresh_cpu_vm_stats(int cpu) { }
 static inline void refresh_zone_stat_thresholds(void) { }
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 194bdaa..8b50e52 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1093,6 +1093,7 @@ static void drain_pages(unsigned int cpu)
 		pcp = &pset->pcp;
 		free_pcppages_bulk(zone, pcp->count, pcp);
 		pcp->count = 0;
+		__flush_zone_state(zone, NR_FREE_PAGES);
 		local_irq_restore(flags);
 	}
 }
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 48b0463..1ca04ec 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -233,6 +233,18 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
 	}
 }
 
+void __flush_zone_state(struct zone *zone, enum zone_stat_item item)
+{
+	struct per_cpu_pageset *pcp = this_cpu_ptr(zone->pageset);
+	s8 *diff = pcp->vm_stat_diff + item;
+
+	if (!*diff)
+		return;
+
+	zone_page_state_add(*diff, zone, item);
+	*diff = 0;
+}
+
 void __inc_zone_page_state(struct page *page, enum zone_stat_item item)
 {
 	__inc_zone_state(page_zone(page), item);
-- 
1.6.5.2



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]