]> git.openfabrics.org - ~shefty/rdma-dev.git/blobdiff - include/linux/mmzone.h
mm: introduce new field "managed_pages" to struct zone
[~shefty/rdma-dev.git] / include / linux / mmzone.h
index 0c0b1d608a6936b85cabad0372ffa63fd69b1673..cd55dad56aac087b138ea79acd57261e8355e91f 100644 (file)
@@ -460,17 +460,44 @@ struct zone {
        unsigned long           zone_start_pfn;
 
        /*
        unsigned long           zone_start_pfn;
 
        /*
-        * zone_start_pfn, spanned_pages and present_pages are all
-        * protected by span_seqlock.  It is a seqlock because it has
-        * to be read outside of zone->lock, and it is done in the main
-        * allocator path.  But, it is written quite infrequently.
+        * spanned_pages is the total pages spanned by the zone, including
+        * holes, which is calculated as:
+        *      spanned_pages = zone_end_pfn - zone_start_pfn;
         *
         *
-        * The lock is declared along with zone->lock because it is
+        * present_pages is physical pages existing within the zone, which
+        * is calculated as:
+        *      present_pages = spanned_pages - absent_pages(pags in holes);
+        *
+        * managed_pages is present pages managed by the buddy system, which
+        * is calculated as (reserved_pages includes pages allocated by the
+        * bootmem allocator):
+        *      managed_pages = present_pages - reserved_pages;
+        *
+        * So present_pages may be used by memory hotplug or memory power
+        * management logic to figure out unmanaged pages by checking
+        * (present_pages - managed_pages). And managed_pages should be used
+        * by page allocator and vm scanner to calculate all kinds of watermarks
+        * and thresholds.
+        *
+        * Locking rules:
+        *
+        * zone_start_pfn and spanned_pages are protected by span_seqlock.
+        * It is a seqlock because it has to be read outside of zone->lock,
+        * and it is done in the main allocator path.  But, it is written
+        * quite infrequently.
+        *
+        * The span_seq lock is declared along with zone->lock because it is
         * frequently read in proximity to zone->lock.  It's good to
         * give them a chance of being in the same cacheline.
         * frequently read in proximity to zone->lock.  It's good to
         * give them a chance of being in the same cacheline.
+        *
+        * Write access to present_pages and managed_pages at runtime should
+        * be protected by lock_memory_hotplug()/unlock_memory_hotplug().
+        * Any reader who can't tolerant drift of present_pages and
+        * managed_pages should hold memory hotplug lock to get a stable value.
         */
         */
-       unsigned long           spanned_pages;  /* total size, including holes */
-       unsigned long           present_pages;  /* amount of memory (excluding holes) */
+       unsigned long           spanned_pages;
+       unsigned long           present_pages;
+       unsigned long           managed_pages;
 
        /*
         * rarely used fields:
 
        /*
         * rarely used fields: