[PATCH] 1/5 VM changes: zone-pressure.patch

From: Nikita Danilov (Nikita@Namesys.COM)
Date: Wed Jul 09 2003 - 03:46:31 EST


Add zone->pressure field. It estimates scanning intensity for this zone and
is calculated as exponentially decaying average of the scanning priority
required to free enough pages in this zone (mm/vmscan.c:zone_adj_pressure()).

zone->pressure is supposed to be used in stead of scanning priority by
vmscan.c. This is used by later patches in a series.

diff -puN include/linux/mmzone.h~zone-pressure include/linux/mmzone.h
--- i386/include/linux/mmzone.h~zone-pressure Wed Jul 9 12:24:50 2003
+++ i386-god/include/linux/mmzone.h Wed Jul 9 12:24:50 2003
@@ -84,11 +84,23 @@ struct zone {
         atomic_t refill_counter;
         unsigned long nr_active;
         unsigned long nr_inactive;
- int all_unreclaimable; /* All pages pinned */
+ int all_unreclaimable:1; /* All pages pinned */
         unsigned long pages_scanned; /* since last reclaim */
 
         ZONE_PADDING(_pad2_)
 
+ /*
+ * measure of scanning intensity for this zone. It is calculated
+ * as exponentially decaying average of the scanning priority
+ * required to free enough pages in this zone
+ * (zone_adj_pressure()).
+ *
+ * 0 --- low pressure
+ *
+ * (DEF_PRIORITY << 10) --- high pressure
+ */
+ int pressure;
+
         /*
          * free areas of different sizes
          */
diff -puN mm/vmscan.c~zone-pressure mm/vmscan.c
--- i386/mm/vmscan.c~zone-pressure Wed Jul 9 12:24:50 2003
+++ i386-god/mm/vmscan.c Wed Jul 9 12:24:50 2003
@@ -80,6 +80,22 @@ static long total_memory;
 #endif
 
 /*
+ * exponentially decaying average
+ */
+static inline int expavg(int avg, int val, int order)
+{
+ return ((val - avg) >> order) + avg;
+}
+
+static void zone_adj_pressure(struct zone * zone, int priority)
+{
+ int pass;
+
+ pass = DEF_PRIORITY - priority;
+ zone->pressure = expavg(zone->pressure, pass << 10, 1);
+}
+
+/*
  * The list of shrinker callbacks used by to apply pressure to
  * ageable caches.
  */
@@ -794,8 +810,10 @@ shrink_caches(struct zone *classzone, in
                 ret += shrink_zone(zone, max_scan, gfp_mask,
                                 to_reclaim, &nr_mapped, ps, priority);
                 *total_scanned += max_scan + nr_mapped;
- if (ret >= nr_pages)
+ if (ret >= nr_pages) {
+ zone_adj_pressure(zone, priority);
                         break;
+ }
         }
         return ret;
 }
@@ -824,6 +842,7 @@ int try_to_free_pages(struct zone *cz,
         int ret = 0;
         const int nr_pages = SWAP_CLUSTER_MAX;
         int nr_reclaimed = 0;
+ struct zone *zone;
         struct reclaim_state *reclaim_state = current->reclaim_state;
 
         inc_page_state(allocstall);
@@ -860,6 +879,8 @@ int try_to_free_pages(struct zone *cz,
         }
         if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY))
                 out_of_memory();
+ for (zone = cz; zone >= cz->zone_pgdat->node_zones; -- zone)
+ zone_adj_pressure(zone, -1);
 out:
         return ret;
 }
@@ -907,8 +928,10 @@ static int balance_pgdat(pg_data_t *pgda
                                 to_reclaim = min(to_free, SWAP_CLUSTER_MAX*8);
                         } else { /* Zone balancing */
                                 to_reclaim = zone->pages_high-zone->free_pages;
- if (to_reclaim <= 0)
+ if (to_reclaim <= 0) {
+ zone_adj_pressure(zone, priority);
                                         continue;
+ }
                         }
                         all_zones_ok = 0;
                         max_scan = zone->nr_inactive >> priority;
@@ -932,6 +955,14 @@ static int balance_pgdat(pg_data_t *pgda
                         break;
                 blk_congestion_wait(WRITE, HZ/10);
         }
+ if (priority < 0) {
+ for (i = 0; i < pgdat->nr_zones; i++) {
+ struct zone *zone = pgdat->node_zones + i;
+
+ if (zone->free_pages < zone->pages_high)
+ zone_adj_pressure(zone, -1);
+ }
+ }
         return nr_pages - to_free;
 }
 

_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jul 15 2003 - 22:00:30 EST