mmzone.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _LINUX_MMZONE_H
  2. #define _LINUX_MMZONE_H
  3. #ifdef __KERNEL__
  4. #ifndef __ASSEMBLY__
  5. #include <linux/config.h>
  6. #include <linux/spinlock.h>
  7. #include <linux/list.h>
  8. #include <linux/wait.h>
  9. /*
  10.  * Free memory management - zoned buddy allocator.
  11.  */
  12. #ifndef CONFIG_FORCE_MAX_ZONEORDER
  13. #define MAX_ORDER 10
  14. #else
  15. #define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
  16. #endif
  17. typedef struct free_area_struct {
  18. struct list_head free_list;
  19. unsigned long *map;
  20. } free_area_t;
  21. struct pglist_data;
  22. /*
  23.  * On machines where it is needed (eg PCs) we divide physical memory
  24.  * into multiple physical zones. On a PC we have 3 zones:
  25.  *
  26.  * ZONE_DMA   < 16 MB ISA DMA capable memory
  27.  * ZONE_NORMAL 16-896 MB direct mapped by the kernel
  28.  * ZONE_HIGHMEM  > 896 MB only page cache and user processes
  29.  */
  30. typedef struct zone_struct {
  31. /*
  32.  * Commonly accessed fields:
  33.  */
  34. spinlock_t lock;
  35. unsigned long free_pages;
  36. unsigned long pages_min, pages_low, pages_high;
  37. int need_balance;
  38. /*
  39.  * free areas of different sizes
  40.  */
  41. free_area_t free_area[MAX_ORDER];
  42. /*
  43.  * wait_table -- the array holding the hash table
  44.  * wait_table_size -- the size of the hash table array
  45.  * wait_table_shift -- wait_table_size
  46.  *  == BITS_PER_LONG (1 << wait_table_bits)
  47.  *
  48.  * The purpose of all these is to keep track of the people
  49.  * waiting for a page to become available and make them
  50.  * runnable again when possible. The trouble is that this
  51.  * consumes a lot of space, especially when so few things
  52.  * wait on pages at a given time. So instead of using
  53.  * per-page waitqueues, we use a waitqueue hash table.
  54.  *
  55.  * The bucket discipline is to sleep on the same queue when
  56.  * colliding and wake all in that wait queue when removing.
  57.  * When something wakes, it must check to be sure its page is
  58.  * truly available, a la thundering herd. The cost of a
  59.  * collision is great, but given the expected load of the
  60.  * table, they should be so rare as to be outweighed by the
  61.  * benefits from the saved space.
  62.  *
  63.  * __wait_on_page() and unlock_page() in mm/filemap.c, are the
  64.  * primary users of these fields, and in mm/page_alloc.c
  65.  * free_area_init_core() performs the initialization of them.
  66.  */
  67. wait_queue_head_t * wait_table;
  68. unsigned long wait_table_size;
  69. unsigned long wait_table_shift;
  70. /*
  71.  * Discontig memory support fields.
  72.  */
  73. struct pglist_data *zone_pgdat;
  74. struct page *zone_mem_map;
  75. unsigned long zone_start_paddr;
  76. unsigned long zone_start_mapnr;
  77. /*
  78.  * rarely used fields:
  79.  */
  80. char *name;
  81. unsigned long size;
  82. } zone_t;
  83. #define ZONE_DMA 0
  84. #define ZONE_NORMAL 1
  85. #define ZONE_HIGHMEM 2
  86. #define MAX_NR_ZONES 3
  87. /*
  88.  * One allocation request operates on a zonelist. A zonelist
  89.  * is a list of zones, the first one is the 'goal' of the
  90.  * allocation, the other zones are fallback zones, in decreasing
  91.  * priority.
  92.  *
  93.  * Right now a zonelist takes up less than a cacheline. We never
  94.  * modify it apart from boot-up, and only a few indices are used,
  95.  * so despite the zonelist table being relatively big, the cache
  96.  * footprint of this construct is very small.
  97.  */
  98. typedef struct zonelist_struct {
  99. zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
  100. } zonelist_t;
  101. #define GFP_ZONEMASK 0x0f
  102. /*
  103.  * The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
  104.  * (mostly NUMA machines?) to denote a higher-level memory zone than the
  105.  * zone_struct denotes.
  106.  *
  107.  * On NUMA machines, each NUMA node would have a pg_data_t to describe
  108.  * it's memory layout.
  109.  *
  110.  * XXX: we need to move the global memory statistics (active_list, ...)
  111.  *      into the pg_data_t to properly support NUMA.
  112.  */
  113. struct bootmem_data;
  114. typedef struct pglist_data {
  115. zone_t node_zones[MAX_NR_ZONES];
  116. zonelist_t node_zonelists[GFP_ZONEMASK+1];
  117. int nr_zones;
  118. struct page *node_mem_map;
  119. unsigned long *valid_addr_bitmap;
  120. struct bootmem_data *bdata;
  121. unsigned long node_start_paddr;
  122. unsigned long node_start_mapnr;
  123. unsigned long node_size;
  124. int node_id;
  125. struct pglist_data *node_next;
  126. } pg_data_t;
  127. extern int numnodes;
  128. extern pg_data_t *pgdat_list;
  129. #define memclass(pgzone, classzone) (((pgzone)->zone_pgdat == (classzone)->zone_pgdat) 
  130. && ((pgzone) <= (classzone)))
  131. /*
  132.  * The following two are not meant for general usage. They are here as
  133.  * prototypes for the discontig memory code.
  134.  */
  135. struct page;
  136. extern void show_free_areas_core(pg_data_t *pgdat);
  137. extern void free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
  138.   unsigned long *zones_size, unsigned long paddr, unsigned long *zholes_size,
  139.   struct page *pmap);
  140. extern pg_data_t contig_page_data;
  141. /**
  142.  * for_each_pgdat - helper macro to iterate over all nodes
  143.  * @pgdat - pg_data_t * variable
  144.  *
  145.  * Meant to help with common loops of the form
  146.  * pgdat = pgdat_list;
  147.  * while(pgdat) {
  148.  *  ...
  149.  *  pgdat = pgdat->node_next;
  150.  * }
  151.  */
  152. #define for_each_pgdat(pgdat) 
  153. for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
  154. /*
  155.  * next_zone - helper magic for for_each_zone()
  156.  * Thanks to William Lee Irwin III for this piece of ingenuity.
  157.  */
  158. static inline zone_t *next_zone(zone_t *zone)
  159. {
  160. pg_data_t *pgdat = zone->zone_pgdat;
  161. if (zone - pgdat->node_zones < MAX_NR_ZONES - 1)
  162. zone++;
  163. else if (pgdat->node_next) {
  164. pgdat = pgdat->node_next;
  165. zone = pgdat->node_zones;
  166. } else
  167. zone = NULL;
  168. return zone;
  169. }
  170. /**
  171.  * for_each_zone - helper macro to iterate over all memory zones
  172.  * @zone - zone_t * variable
  173.  *
  174.  * The user only needs to declare the zone variable, for_each_zone
  175.  * fills it in. This basically means for_each_zone() is an
  176.  * easier to read version of this piece of code:
  177.  *
  178.  * for(pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
  179.  *  for(i = 0; i < MAX_NR_ZONES; ++i) {
  180.  *  zone_t * z = pgdat->node_zones + i;
  181.  *  ...
  182.  *  }
  183.  * }
  184.  */
  185. #define for_each_zone(zone) 
  186. for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
  187. #ifndef CONFIG_DISCONTIGMEM
  188. #define NODE_DATA(nid) (&contig_page_data)
  189. #define NODE_MEM_MAP(nid) mem_map
  190. #define MAX_NR_NODES 1
  191. #else /* !CONFIG_DISCONTIGMEM */
  192. #include <asm/mmzone.h>
  193. /* page->zone is currently 8 bits ... */
  194. #ifndef MAX_NR_NODES
  195. #define MAX_NR_NODES (255 / MAX_NR_ZONES)
  196. #endif
  197. #endif /* !CONFIG_DISCONTIGMEM */
  198. #define MAP_ALIGN(x) ((((x) % sizeof(mem_map_t)) == 0) ? (x) : ((x) + 
  199. sizeof(mem_map_t) - ((x) % sizeof(mem_map_t))))
  200. #endif /* !__ASSEMBLY__ */
  201. #endif /* __KERNEL__ */
  202. #endif /* _LINUX_MMZONE_H */