File: /Users/paulross/dev/linux/linux-3.13/include/linux/memory_hotplug.h

Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.

       1: #ifndef __LINUX_MEMORY_HOTPLUG_H
       2: #define __LINUX_MEMORY_HOTPLUG_H
       3: 
       4: #include <linux/mmzone.h>
       5: #include <linux/spinlock.h>
       6: #include <linux/notifier.h>
       7: #include <linux/bug.h>
       8: 
       9: struct page;
      10: struct zone;
      11: struct pglist_data;
      12: struct mem_section;
      13: struct memory_block;
      14: 
      15: #ifdef CONFIG_MEMORY_HOTPLUG
      16: 
      17: /*
      18:  * Types for free bootmem stored in page->lru.next. These have to be in
      19:  * some random range in unsigned long space for debugging purposes.
      20:  */
      21: enum {
      22:     MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE = 12,
      23:     SECTION_INFO = MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE,
      24:     MIX_SECTION_INFO,
      25:     NODE_INFO,
      26:     MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO,
      27: };
      28: 
      29: /* Types for control the zone type of onlined memory */
      30: enum {
      31:     ONLINE_KEEP,
      32:     ONLINE_KERNEL,
      33:     ONLINE_MOVABLE,
      34: };
      35: 
      36: /*
      37:  * pgdat resizing functions
      38:  */
      39: static inline
      40: void pgdat_resize_lock(struct pglist_data *pgdat, unsigned long *flags)
      41: {
      42:     spin_lock_irqsave(&pgdat->node_size_lock, *flags);
      43: }
      44: static inline
      45: void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
      46: {
      47:     spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
      48: }
      49: static inline
      50: void pgdat_resize_init(struct pglist_data *pgdat)
      51: {
      52:     spin_lock_init(&pgdat->node_size_lock);
      53: }
      54: /*
      55:  * Zone resizing functions
      56:  *
      57:  * Note: any attempt to resize a zone should has pgdat_resize_lock()
      58:  * zone_span_writelock() both held. This ensure the size of a zone
      59:  * can't be changed while pgdat_resize_lock() held.
      60:  */
      61: static inline unsigned zone_span_seqbegin(struct zone *zone)
      62: {
      63:     return read_seqbegin(&zone->span_seqlock);
      64: }
      65: static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
      66: {
      67:     return read_seqretry(&zone->span_seqlock, iv);
      68: }
      69: static inline void zone_span_writelock(struct zone *zone)
      70: {
      71:     write_seqlock(&zone->span_seqlock);
      72: }
      73: static inline void zone_span_writeunlock(struct zone *zone)
      74: {
      75:     write_sequnlock(&zone->span_seqlock);
      76: }
      77: static inline void zone_seqlock_init(struct zone *zone)
      78: {
      79:     seqlock_init(&zone->span_seqlock);
      80: }
      81: extern int zone_grow_free_lists(struct zone *zone, unsigned long new_nr_pages);
      82: extern int zone_grow_waitqueues(struct zone *zone, unsigned long nr_pages);
      83: extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
      84: /* VM interface that may be used by firmware interface */
      85: extern int online_pages(unsigned long, unsigned long, int);
      86: extern void __offline_isolated_pages(unsigned long, unsigned long);
      87: 
      88: typedef void (*online_page_callback_t)(struct page *page);
      89: 
      90: extern int set_online_page_callback(online_page_callback_t callback);
      91: extern int restore_online_page_callback(online_page_callback_t callback);
      92: 
      93: extern void __online_page_set_limits(struct page *page);
      94: extern void __online_page_increment_counters(struct page *page);
      95: extern void __online_page_free(struct page *page);
      96: 
      97: extern int try_online_node(int nid);
      98: 
      99: #ifdef CONFIG_MEMORY_HOTREMOVE
     100: extern bool is_pageblock_removable_nolock(struct page *page);
     101: extern int arch_remove_memory(u64 start, u64 size);
     102: extern int __remove_pages(struct zone *zone, unsigned long start_pfn,
     103:     unsigned long nr_pages);
     104: #endif /* CONFIG_MEMORY_HOTREMOVE */
     105: 
     106: /* reasonably generic interface to expand the physical pages in a zone  */
     107: extern int __add_pages(int nid, struct zone *zone, unsigned long start_pfn,
     108:     unsigned long nr_pages);
     109: 
     110: #ifdef CONFIG_NUMA
     111: extern int memory_add_physaddr_to_nid(u64 start);
     112: #else
     113: static inline int memory_add_physaddr_to_nid(u64 start)
     114: {
     115:     return 0;
     116: }
     117: #endif
     118: 
     119: #ifdef CONFIG_HAVE_ARCH_NODEDATA_EXTENSION
     120: /*
     121:  * For supporting node-hotadd, we have to allocate a new pgdat.
     122:  *
     123:  * If an arch has generic style NODE_DATA(),
     124:  * node_data[nid] = kzalloc() works well. But it depends on the architecture.
     125:  *
     126:  * In general, generic_alloc_nodedata() is used.
     127:  * Now, arch_free_nodedata() is just defined for error path of node_hot_add.
     128:  *
     129:  */
     130: extern pg_data_t *arch_alloc_nodedata(int nid);
     131: extern void arch_free_nodedata(pg_data_t *pgdat);
     132: extern void arch_refresh_nodedata(int nid, pg_data_t *pgdat);
     133: 
     134: #else /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
     135: 
     136: #define arch_alloc_nodedata(nid)    generic_alloc_nodedata(nid)
     137: #define arch_free_nodedata(pgdat)    generic_free_nodedata(pgdat)
     138: 
     139: #ifdef CONFIG_NUMA
     140: /*
     141:  * If ARCH_HAS_NODEDATA_EXTENSION=n, this func is used to allocate pgdat.
     142:  * XXX: kmalloc_node() can't work well to get new node's memory at this time.
     143:  *    Because, pgdat for the new node is not allocated/initialized yet itself.
     144:  *    To use new node's memory, more consideration will be necessary.
     145:  */
     146: #define generic_alloc_nodedata(nid)                \
     147: ({                                \
     148:     kzalloc(sizeof(pg_data_t), GFP_KERNEL);            \
     149: })
     150: /*
     151:  * This definition is just for error path in node hotadd.
     152:  * For node hotremove, we have to replace this.
     153:  */
     154: #define generic_free_nodedata(pgdat)    kfree(pgdat)
     155: 
     156: extern pg_data_t *node_data[];
     157: static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
     158: {
     159:     node_data[nid] = pgdat;
     160: }
     161: 
     162: #else /* !CONFIG_NUMA */
     163: 
     164: /* never called */
     165: static inline pg_data_t *generic_alloc_nodedata(int nid)
     166: {
     167:     BUG();
     168:     return NULL;
     169: }
     170: static inline void generic_free_nodedata(pg_data_t *pgdat)
     171: {
     172: }
     173: static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
     174: {
     175: }
     176: #endif /* CONFIG_NUMA */
     177: #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
     178: 
     179: #ifdef CONFIG_HAVE_BOOTMEM_INFO_NODE
     180: extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
     181: #else
     182: static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
     183: {
     184: }
     185: #endif
     186: extern void put_page_bootmem(struct page *page);
     187: extern void get_page_bootmem(unsigned long ingo, struct page *page,
     188:                  unsigned long type);
     189: 
     190: /*
     191:  * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
     192:  * notifier will be called under this. 2) offline/online/add/remove memory
     193:  * will not run simultaneously.
     194:  */
     195: 
     196: void lock_memory_hotplug(void);
     197: void unlock_memory_hotplug(void);
     198: 
     199: #else /* ! CONFIG_MEMORY_HOTPLUG */
     200: /*
     201:  * Stub functions for when hotplug is off
     202:  */
     203: static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
     204: static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
     205: static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
     206: 
     207: static inline unsigned zone_span_seqbegin(struct zone *zone)
     208: {
     209:     return 0;
     210: }
     211: static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
     212: {
     213:     return 0;
     214: }
     215: static inline void zone_span_writelock(struct zone *zone) {}
     216: static inline void zone_span_writeunlock(struct zone *zone) {}
     217: static inline void zone_seqlock_init(struct zone *zone) {}
     218: 
     219: static inline int mhp_notimplemented(const char *func)
     220: {
     221:     printk(KERN_WARNING "%s() called, with CONFIG_MEMORY_HOTPLUG disabled\n", func);
     222:     dump_stack();
     223:     return -ENOSYS;
     224: }
     225: 
     226: static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
     227: {
     228: }
     229: 
     230: static inline int try_online_node(int nid)
     231: {
     232:     return 0;
     233: }
     234: 
     235: static inline void lock_memory_hotplug(void) {}
     236: static inline void unlock_memory_hotplug(void) {}
     237: 
     238: #endif /* ! CONFIG_MEMORY_HOTPLUG */
     239: 
     240: #ifdef CONFIG_MEMORY_HOTREMOVE
     241: 
     242: extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
     243: extern void try_offline_node(int nid);
     244: extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
     245: extern void remove_memory(int nid, u64 start, u64 size);
     246: 
     247: #else
     248: static inline int is_mem_section_removable(unsigned long pfn,
     249:                     unsigned long nr_pages)
     250: {
     251:     return 0;
     252: }
     253: 
     254: static inline void try_offline_node(int nid) {}
     255: 
     256: static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
     257: {
     258:     return -EINVAL;
     259: }
     260: 
     261: static inline void remove_memory(int nid, u64 start, u64 size) {}
     262: #endif /* CONFIG_MEMORY_HOTREMOVE */
     263: 
     264: extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
     265:         void *arg, int (*func)(struct memory_block *, void *));
     266: extern int add_memory(int nid, u64 start, u64 size);
     267: extern int arch_add_memory(int nid, u64 start, u64 size);
     268: extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
     269: extern bool is_memblock_offlined(struct memory_block *mem);
     270: extern void remove_memory(int nid, u64 start, u64 size);
     271: extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn);
     272: extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms);
     273: extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
     274:                       unsigned long pnum);
     275: 
     276: #endif /* __LINUX_MEMORY_HOTPLUG_H */
     277: