Re: [patch 08/21] (NEW) add some sanity checks to get_scan_ratio

minchan Kim
2008-03-04T10:53:24Z

@@ -1182,9 +1194,8 @@ static unsigned long shrink_list(enum lr
static void get_scan_ratio(struct zone *zone, struct scan_control * sc,
unsigned long *percent)
{
- unsigned long anon, file;
+ unsigned long anon, file, free;
unsigned long anon_prio, file_prio;
- unsigned long rotate_sum;
unsigned long ap, fp;

anon = zone_page_state(zone, NR_ACTIVE_ANON) +
@@ -1192,15 +1203,19 @@ static void get_scan_ratio(struct zone *
file = zone_page_state(zone, NR_ACTIVE_FILE) +
zone_page_state(zone, NR_INACTIVE_FILE);

- rotate_sum = zone->recent_rotated_file + zone->recent_rotated_anon;
-
/* Keep a floating average of RECENT references. */
- if (unlikely(rotate_sum > min(anon, file))) {
+ if (unlikely(zone->recent_scanned_anon > anon / zone->inactive_ratio)) {
spin_lock_irq(&zone->lru_lock);
- zone->recent_rotated_file /= 2;
+ zone->recent_scanned_anon /= 2;
zone->recent_rotated_anon /= 2;
spin_unlock_irq(&zone->lru_lock);
- rotate_sum /= 2;
+ }
+
+ if (unlikely(zone->recent_scanned_file > file / 4)) {
+ spin_lock_irq(&zone->lru_lock);
+ zone->recent_scanned_file /= 2;
+ zone->recent_rotated_file /= 2;
+ spin_unlock_irq(&zone->lru_lock);
}

/*
@@ -1213,23 +1228,33 @@ static void get_scan_ratio(struct zone *
/*
* anon recent_rotated_anon
* %anon = 100 * ----------- / ------------------- * IO cost
- * anon + file rotate_sum
+ * anon + file recent_scanned_anon
*/
- ap = (anon_prio * anon) / (anon + file + 1);
- ap *= rotate_sum / (zone->recent_rotated_anon + 1);
- if (ap == 0)
- ap = 1;
- else if (ap > 100)
- ap = 100;
- percent[0] = ap;
-
- fp = (file_prio * file) / (anon + file + 1);
- fp *= rotate_sum / (zone->recent_rotated_file + 1);
- if (fp == 0)
- fp = 1;
- else if (fp > 100)
- fp = 100;
- percent[1] = fp;
+ ap = (anon_prio + 1) * (zone->recent_scanned_anon + 1);
+ ap /= zone->recent_rotated_anon + 1;
+
+ fp = (file_prio + 1) * (zone->recent_scanned_file + 1);
+ fp /= zone->recent_rotated_file + 1;
+
+ /* Normalize to percentages */
+ percent[0] = 100 * ap / (ap + fp + 1);
+ percent[1] = 100 - percent[0];
+
+ free = zone_page_state(zone, NR_FREE_PAGES);
+
+ /*
+ * If we have no swap space, do not bother scanning anon pages.
+ */
+ if (nr_swap_pages <= 0) {
+ percent[0] = 0;
+ percent[1] = 100;
+ }
+ /*
+ * If we already freed most file pages, scan the anon pages
+ * regardless of the page access ratios or swappiness setting.
+ */
+ else if (file + free <= zone->pages_high)
+ percent[0] = 100;
}

I think we don't need to calculate ratio percent if it don't have any
swap device.

we can get a little bit performance gain.

diff --git a/mm/vmscan.c b/mm/vmscan.c
index e6cb98b..e578c62 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1313,6 +1313,15 @@ static void get_scan_ratio(struct zone *zone,
struct scan_control * sc,
unsigned long anon_prio, file_prio;
unsigned long ap, fp;

+ /*
+ * If we have no swap space, do not bother scanning anon pages and
unnessary calculation.
+ */
+ if (nr_swap_pages <= 0) {
+ percent[0] = 0;
+ percent[1] = 100;
+ return;
+ }
+
anon = zone_page_state(zone, NR_ACTIVE_ANON) +
zone_page_state(zone, NR_INACTIVE_ANON);
file = zone_page_state(zone, NR_ACTIVE_FILE) +
@@ -1357,18 +1366,12 @@ static void get_scan_ratio(struct zone *zone,
struct scan_control * sc,

free = zone_page_state(zone, NR_FREE_PAGES);

- /*
- * If we have no swap space, do not bother scanning anon pages.
- */
- if (nr_swap_pages <= 0) {
- percent[0] = 0;
- percent[1] = 100;
- }
+
/*
* If we already freed most file pages, scan the anon pages
* regardless of the page access ratios or swappiness setting.
*/
- else if (file + free <= zone->pages_high)
+ if (file + free <= zone->pages_high)
percent[0] = 100;
}

Thanks,
barrios