]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/blobdiff - mm/memory_hotplug.c
cls_can: Fixed protocol restriction + minor changes.
[lisovros/linux_canprio.git] / mm / memory_hotplug.c
index be211a582930d87bba2f959e2729399e364f6ae9..6345dfe78d2cbb6e104247886c4f8765f538f809 100644 (file)
@@ -415,12 +415,14 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
         * This means the page allocator ignores this zone.
         * So, zonelist must be updated after online.
         */
+       mutex_lock(&zonelists_mutex);
        if (!populated_zone(zone))
                need_zonelists_rebuild = 1;
 
        ret = walk_system_ram_range(pfn, nr_pages, &onlined_pages,
                online_pages_range);
        if (ret) {
+               mutex_unlock(&zonelists_mutex);
                printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
                        nr_pages, pfn);
                memory_notify(MEM_CANCEL_ONLINE, &arg);
@@ -429,8 +431,12 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
 
        zone->present_pages += onlined_pages;
        zone->zone_pgdat->node_present_pages += onlined_pages;
+       if (need_zonelists_rebuild)
+               build_all_zonelists(zone);
+       else
+               zone_pcp_update(zone);
 
-       zone_pcp_update(zone);
+       mutex_unlock(&zonelists_mutex);
        setup_per_zone_wmarks();
        calculate_zone_inactive_ratio(zone);
        if (onlined_pages) {
@@ -438,10 +444,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
                node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
        }
 
-       if (need_zonelists_rebuild)
-               build_all_zonelists();
-       else
-               vm_total_pages = nr_free_pagecache_pages();
+       vm_total_pages = nr_free_pagecache_pages();
 
        writeback_set_ratelimit();
 
@@ -482,6 +485,29 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
 }
 
 
+/*
+ * called by cpu_up() to online a node without onlined memory.
+ */
+int mem_online_node(int nid)
+{
+       pg_data_t       *pgdat;
+       int     ret;
+
+       lock_system_sleep();
+       pgdat = hotadd_new_pgdat(nid, 0);
+       if (pgdat) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       node_set_online(nid);
+       ret = register_one_node(nid);
+       BUG_ON(ret);
+
+out:
+       unlock_system_sleep();
+       return ret;
+}
+
 /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
 int __ref add_memory(int nid, u64 start, u64 size)
 {
@@ -558,19 +584,19 @@ static inline int pageblock_free(struct page *page)
 /* Return the start of the next active pageblock after a given page */
 static struct page *next_active_pageblock(struct page *page)
 {
-       int pageblocks_stride;
-
        /* Ensure the starting page is pageblock-aligned */
        BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1));
 
-       /* Move forward by at least 1 * pageblock_nr_pages */
-       pageblocks_stride = 1;
-
        /* If the entire pageblock is free, move to the end of free page */
-       if (pageblock_free(page))
-               pageblocks_stride += page_order(page) - pageblock_order;
+       if (pageblock_free(page)) {
+               int order;
+               /* be careful. we don't have locks, page_order can be changed.*/
+               order = page_order(page);
+               if ((order < MAX_ORDER) && (order >= pageblock_order))
+                       return page + (1 << order);
+       }
 
-       return page + (pageblocks_stride * pageblock_nr_pages);
+       return page + pageblock_nr_pages;
 }
 
 /* Checks if this range of memory is likely to be hot-removable. */
@@ -633,7 +659,7 @@ static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
  * Scanning pfn is much easier than scanning lru list.
  * Scan pfn from start to end and Find LRU page.
  */
-int scan_lru_pages(unsigned long start, unsigned long end)
+unsigned long scan_lru_pages(unsigned long start, unsigned long end)
 {
        unsigned long pfn;
        struct page *page;