memory_hotplug.c (92fd4d4d67b945c0766416284d4ab236b31542c4) memory_hotplug.c (20d6c96b5f1cad5c5da4641945ec17a1d9a1afc8)
1/*
2 * linux/mm/memory_hotplug.c
3 *
4 * Copyright (C)
5 */
6
7#include <linux/stddef.h>
8#include <linux/mm.h>

--- 20 unchanged lines hidden (view full) ---

29#include <linux/suspend.h>
30#include <linux/mm_inline.h>
31#include <linux/firmware-map.h>
32
33#include <asm/tlbflush.h>
34
35#include "internal.h"
36
1/*
2 * linux/mm/memory_hotplug.c
3 *
4 * Copyright (C)
5 */
6
7#include <linux/stddef.h>
8#include <linux/mm.h>

--- 20 unchanged lines hidden (view full) ---

29#include <linux/suspend.h>
30#include <linux/mm_inline.h>
31#include <linux/firmware-map.h>
32
33#include <asm/tlbflush.h>
34
35#include "internal.h"
36
37DEFINE_MUTEX(mem_hotplug_mutex);
38
39void lock_memory_hotplug(void)
40{
41 mutex_lock(&mem_hotplug_mutex);
42
43 /* for exclusive hibernation if CONFIG_HIBERNATION=y */
44 lock_system_sleep();
45}
46
47void unlock_memory_hotplug(void)
48{
49 unlock_system_sleep();
50 mutex_unlock(&mem_hotplug_mutex);
51}
52
53
37/* add this memory to iomem resource */
38static struct resource *register_memory_resource(u64 start, u64 size)
39{
40 struct resource *res;
41 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
42 BUG_ON(!res);
43
44 res->name = "System RAM";

--- 443 unchanged lines hidden (view full) ---

488/*
489 * called by cpu_up() to online a node without onlined memory.
490 */
491int mem_online_node(int nid)
492{
493 pg_data_t *pgdat;
494 int ret;
495
54/* add this memory to iomem resource */
55static struct resource *register_memory_resource(u64 start, u64 size)
56{
57 struct resource *res;
58 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
59 BUG_ON(!res);
60
61 res->name = "System RAM";

--- 443 unchanged lines hidden (view full) ---

505/*
506 * called by cpu_up() to online a node without onlined memory.
507 */
508int mem_online_node(int nid)
509{
510 pg_data_t *pgdat;
511 int ret;
512
496 lock_system_sleep();
513 lock_memory_hotplug();
497 pgdat = hotadd_new_pgdat(nid, 0);
498 if (pgdat) {
499 ret = -ENOMEM;
500 goto out;
501 }
502 node_set_online(nid);
503 ret = register_one_node(nid);
504 BUG_ON(ret);
505
506out:
514 pgdat = hotadd_new_pgdat(nid, 0);
515 if (pgdat) {
516 ret = -ENOMEM;
517 goto out;
518 }
519 node_set_online(nid);
520 ret = register_one_node(nid);
521 BUG_ON(ret);
522
523out:
507 unlock_system_sleep();
524 unlock_memory_hotplug();
508 return ret;
509}
510
511/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
512int __ref add_memory(int nid, u64 start, u64 size)
513{
514 pg_data_t *pgdat = NULL;
515 int new_pgdat = 0;
516 struct resource *res;
517 int ret;
518
525 return ret;
526}
527
528/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
529int __ref add_memory(int nid, u64 start, u64 size)
530{
531 pg_data_t *pgdat = NULL;
532 int new_pgdat = 0;
533 struct resource *res;
534 int ret;
535
519 lock_system_sleep();
536 lock_memory_hotplug();
520
521 res = register_memory_resource(start, size);
522 ret = -EEXIST;
523 if (!res)
524 goto out;
525
526 if (!node_online(nid)) {
527 pgdat = hotadd_new_pgdat(nid, start);

--- 30 unchanged lines hidden (view full) ---

558error:
559 /* rollback pgdat allocation and others */
560 if (new_pgdat)
561 rollback_node_hotadd(nid, pgdat);
562 if (res)
563 release_memory_resource(res);
564
565out:
537
538 res = register_memory_resource(start, size);
539 ret = -EEXIST;
540 if (!res)
541 goto out;
542
543 if (!node_online(nid)) {
544 pgdat = hotadd_new_pgdat(nid, start);

--- 30 unchanged lines hidden (view full) ---

575error:
576 /* rollback pgdat allocation and others */
577 if (new_pgdat)
578 rollback_node_hotadd(nid, pgdat);
579 if (res)
580 release_memory_resource(res);
581
582out:
566 unlock_system_sleep();
583 unlock_memory_hotplug();
567 return ret;
568}
569EXPORT_SYMBOL_GPL(add_memory);
570
571#ifdef CONFIG_MEMORY_HOTREMOVE
572/*
573 * A free page on the buddy free lists (not the per-cpu lists) has PageBuddy
574 * set and the size of the free page is given by page_order(). Using this,

--- 211 unchanged lines hidden (view full) ---

786 return -EINVAL;
787 if (!IS_ALIGNED(end_pfn, pageblock_nr_pages))
788 return -EINVAL;
789 /* This makes hotplug much easier...and readable.
790 we assume this for now. .*/
791 if (!test_pages_in_a_zone(start_pfn, end_pfn))
792 return -EINVAL;
793
584 return ret;
585}
586EXPORT_SYMBOL_GPL(add_memory);
587
588#ifdef CONFIG_MEMORY_HOTREMOVE
589/*
590 * A free page on the buddy free lists (not the per-cpu lists) has PageBuddy
591 * set and the size of the free page is given by page_order(). Using this,

--- 211 unchanged lines hidden (view full) ---

803 return -EINVAL;
804 if (!IS_ALIGNED(end_pfn, pageblock_nr_pages))
805 return -EINVAL;
806 /* This makes hotplug much easier...and readable.
807 we assume this for now. .*/
808 if (!test_pages_in_a_zone(start_pfn, end_pfn))
809 return -EINVAL;
810
794 lock_system_sleep();
811 lock_memory_hotplug();
795
796 zone = page_zone(pfn_to_page(start_pfn));
797 node = zone_to_nid(zone);
798 nr_pages = end_pfn - start_pfn;
799
800 /* set above range as isolated */
801 ret = start_isolate_page_range(start_pfn, end_pfn);
802 if (ret)

--- 72 unchanged lines hidden (view full) ---

875 node_clear_state(node, N_HIGH_MEMORY);
876 kswapd_stop(node);
877 }
878
879 vm_total_pages = nr_free_pagecache_pages();
880 writeback_set_ratelimit();
881
882 memory_notify(MEM_OFFLINE, &arg);
812
813 zone = page_zone(pfn_to_page(start_pfn));
814 node = zone_to_nid(zone);
815 nr_pages = end_pfn - start_pfn;
816
817 /* set above range as isolated */
818 ret = start_isolate_page_range(start_pfn, end_pfn);
819 if (ret)

--- 72 unchanged lines hidden (view full) ---

892 node_clear_state(node, N_HIGH_MEMORY);
893 kswapd_stop(node);
894 }
895
896 vm_total_pages = nr_free_pagecache_pages();
897 writeback_set_ratelimit();
898
899 memory_notify(MEM_OFFLINE, &arg);
883 unlock_system_sleep();
900 unlock_memory_hotplug();
884 return 0;
885
886failed_removal:
887 printk(KERN_INFO "memory offlining %lx to %lx failed\n",
888 start_pfn, end_pfn);
889 memory_notify(MEM_CANCEL_OFFLINE, &arg);
890 /* pushback to free area */
891 undo_isolate_page_range(start_pfn, end_pfn);
892
893out:
901 return 0;
902
903failed_removal:
904 printk(KERN_INFO "memory offlining %lx to %lx failed\n",
905 start_pfn, end_pfn);
906 memory_notify(MEM_CANCEL_OFFLINE, &arg);
907 /* pushback to free area */
908 undo_isolate_page_range(start_pfn, end_pfn);
909
910out:
894 unlock_system_sleep();
911 unlock_memory_hotplug();
895 return ret;
896}
897
898int remove_memory(u64 start, u64 size)
899{
900 unsigned long start_pfn, end_pfn;
901
902 start_pfn = PFN_DOWN(start);
903 end_pfn = start_pfn + PFN_DOWN(size);
904 return offline_pages(start_pfn, end_pfn, 120 * HZ);
905}
906#else
907int remove_memory(u64 start, u64 size)
908{
909 return -EINVAL;
910}
911#endif /* CONFIG_MEMORY_HOTREMOVE */
912EXPORT_SYMBOL_GPL(remove_memory);
912 return ret;
913}
914
915int remove_memory(u64 start, u64 size)
916{
917 unsigned long start_pfn, end_pfn;
918
919 start_pfn = PFN_DOWN(start);
920 end_pfn = start_pfn + PFN_DOWN(size);
921 return offline_pages(start_pfn, end_pfn, 120 * HZ);
922}
923#else
924int remove_memory(u64 start, u64 size)
925{
926 return -EINVAL;
927}
928#endif /* CONFIG_MEMORY_HOTREMOVE */
929EXPORT_SYMBOL_GPL(remove_memory);