Merge branch 'akpm' (fixes from Andrew Morton)
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Oct 2013 23:58:23 +0000 (16:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Oct 2013 23:58:23 +0000 (16:58 -0700)
Merge four more fixes from Andrew Morton.

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  lib/scatterlist.c: don't flush_kernel_dcache_page on slab page
  mm: memcg: fix test for child groups
  mm: memcg: lockdep annotation for memcg OOM lock
  mm: memcg: use proper memcg in limit bypass

19 files changed:
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/radeon/evergreen_hdmi.c
drivers/gpu/drm/radeon/kv_dpm.c
drivers/gpu/drm/radeon/radeon.h
drivers/input/input.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/misc/cm109.c
drivers/input/mouse/alps.c
drivers/input/serio/i8042.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/pci/hotplug/acpiphp_glue.c
fs/dcache.c
fs/eventpoll.c
fs/select.c
mm/huge_memory.c
mm/memory.c
mm/migrate.c
mm/mprotect.c

index db59bb9..10d1de5 100644 (file)
@@ -107,8 +107,6 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
 static void intel_crt_get_config(struct intel_encoder *encoder,
                                 struct intel_crtc_config *pipe_config)
 {
-       struct drm_device *dev = encoder->base.dev;
-
        pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
 }
 
index fe1de85..57fcc4b 100644 (file)
@@ -291,6 +291,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
        /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */
 
        WREG32(HDMI_ACR_PACKET_CONTROL + offset,
+              HDMI_ACR_SOURCE | /* select SW CTS value */
               HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
 
        evergreen_hdmi_update_ACR(encoder, mode->clock);
index 7139906..b419055 100644 (file)
@@ -2635,7 +2635,7 @@ int kv_dpm_init(struct radeon_device *rdev)
        pi->caps_sclk_ds = true;
        pi->enable_auto_thermal_throttling = true;
        pi->disable_nb_ps3_in_battery = false;
-       pi->bapm_enable = true;
+       pi->bapm_enable = false;
        pi->voltage_drop_t = 0;
        pi->caps_sclk_throttle_low_notification = false;
        pi->caps_fps = false; /* true? */
index a400ac1..24f4960 100644 (file)
@@ -1272,8 +1272,8 @@ struct radeon_blacklist_clocks
 struct radeon_clock_and_voltage_limits {
        u32 sclk;
        u32 mclk;
-       u32 vddc;
-       u32 vddci;
+       u16 vddc;
+       u16 vddci;
 };
 
 struct radeon_clock_array {
index c044699..e75d015 100644 (file)
@@ -1734,6 +1734,7 @@ EXPORT_SYMBOL_GPL(input_class);
  */
 struct input_dev *input_allocate_device(void)
 {
+       static atomic_t input_no = ATOMIC_INIT(0);
        struct input_dev *dev;
 
        dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
@@ -1743,9 +1744,13 @@ struct input_dev *input_allocate_device(void)
                device_initialize(&dev->dev);
                mutex_init(&dev->mutex);
                spin_lock_init(&dev->event_lock);
+               init_timer(&dev->timer);
                INIT_LIST_HEAD(&dev->h_list);
                INIT_LIST_HEAD(&dev->node);
 
+               dev_set_name(&dev->dev, "input%ld",
+                            (unsigned long) atomic_inc_return(&input_no) - 1);
+
                __module_get(THIS_MODULE);
        }
 
@@ -2019,7 +2024,6 @@ static void devm_input_device_unregister(struct device *dev, void *res)
  */
 int input_register_device(struct input_dev *dev)
 {
-       static atomic_t input_no = ATOMIC_INIT(0);
        struct input_devres *devres = NULL;
        struct input_handler *handler;
        unsigned int packet_size;
@@ -2059,7 +2063,6 @@ int input_register_device(struct input_dev *dev)
         * If delay and period are pre-set by the driver, then autorepeating
         * is handled by the driver itself and we don't do it in input.c.
         */
-       init_timer(&dev->timer);
        if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
                dev->timer.data = (long) dev;
                dev->timer.function = input_repeat_key;
@@ -2073,9 +2076,6 @@ int input_register_device(struct input_dev *dev)
        if (!dev->setkeycode)
                dev->setkeycode = input_default_setkeycode;
 
-       dev_set_name(&dev->dev, "input%ld",
-                    (unsigned long) atomic_inc_return(&input_no) - 1);
-
        error = device_add(&dev->dev);
        if (error)
                goto err_free_vals;
index 134c3b4..a2e758d 100644 (file)
@@ -786,10 +786,17 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-       if (pdata)
+       if (pdata) {
                error = pxa27x_keypad_build_keycode(keypad);
-       else
+       } else {
                error = pxa27x_keypad_build_keycode_from_dt(keypad);
+               /*
+                * Data that we get from DT resides in dynamically
+                * allocated memory so we need to update our pdata
+                * pointer.
+                */
+               pdata = keypad->pdata;
+       }
        if (error) {
                dev_err(&pdev->dev, "failed to build keycode\n");
                goto failed_put_clk;
index 082684e..9365535 100644 (file)
@@ -351,7 +351,9 @@ static void cm109_urb_irq_callback(struct urb *urb)
        if (status) {
                if (status == -ESHUTDOWN)
                        return;
-               dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status);
+               dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n",
+                                   __func__, status);
+               goto out;
        }
 
        /* Special keys */
@@ -418,8 +420,12 @@ static void cm109_urb_ctl_callback(struct urb *urb)
             dev->ctl_data->byte[2],
             dev->ctl_data->byte[3]);
 
-       if (status)
-               dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status);
+       if (status) {
+               if (status == -ESHUTDOWN)
+                       return;
+               dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n",
+                                   __func__, status);
+       }
 
        spin_lock(&dev->ctl_submit_lock);
 
@@ -427,7 +433,7 @@ static void cm109_urb_ctl_callback(struct urb *urb)
 
        if (likely(!dev->shutdown)) {
 
-               if (dev->buzzer_pending) {
+               if (dev->buzzer_pending || status) {
                        dev->buzzer_pending = 0;
                        dev->ctl_urb_pending = 1;
                        cm109_submit_buzz_toggle(dev);
index 7c5d72a..8365847 100644 (file)
@@ -103,6 +103,7 @@ static const struct alps_model_info alps_model_data[] = {
        /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
        { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
+       { { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_DUALPOINT },              /* Dell XT2 */
        { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },           /* Dell Vostro 1400 */
        { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },                            /* Toshiba Tecra A11-11L */
index 78e4de4..52c9ebf 100644 (file)
@@ -223,21 +223,26 @@ static int i8042_flush(void)
 {
        unsigned long flags;
        unsigned char data, str;
-       int i = 0;
+       int count = 0;
+       int retval = 0;
 
        spin_lock_irqsave(&i8042_lock, flags);
 
-       while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) {
-               udelay(50);
-               data = i8042_read_data();
-               i++;
-               dbg("%02x <- i8042 (flush, %s)\n",
-                   data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
+       while ((str = i8042_read_status()) & I8042_STR_OBF) {
+               if (count++ < I8042_BUFFER_SIZE) {
+                       udelay(50);
+                       data = i8042_read_data();
+                       dbg("%02x <- i8042 (flush, %s)\n",
+                           data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
+               } else {
+                       retval = -EIO;
+                       break;
+               }
        }
 
        spin_unlock_irqrestore(&i8042_lock, flags);
 
-       return i;
+       return retval;
 }
 
 /*
@@ -849,7 +854,7 @@ static int __init i8042_check_aux(void)
 
 static int i8042_controller_check(void)
 {
-       if (i8042_flush() == I8042_BUFFER_SIZE) {
+       if (i8042_flush()) {
                pr_err("No controller found\n");
                return -ENODEV;
        }
index 79b69ea..e53416a 100644 (file)
@@ -1031,6 +1031,7 @@ static void wacom_destroy_leds(struct wacom *wacom)
 }
 
 static enum power_supply_property wacom_battery_props[] = {
+       POWER_SUPPLY_PROP_SCOPE,
        POWER_SUPPLY_PROP_CAPACITY
 };
 
@@ -1042,6 +1043,9 @@ static int wacom_battery_get_property(struct power_supply *psy,
        int ret = 0;
 
        switch (psp) {
+               case POWER_SUPPLY_PROP_SCOPE:
+                       val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+                       break;
                case POWER_SUPPLY_PROP_CAPACITY:
                        val->intval =
                                wacom->wacom_wac.battery_capacity * 100 / 31;
index b2aa503..c59b797 100644 (file)
@@ -2054,6 +2054,12 @@ static const struct wacom_features wacom_features_0x101 =
 static const struct wacom_features wacom_features_0x10D =
        { "Wacom ISDv4 10D",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10E =
+       { "Wacom ISDv4 10E",      WACOM_PKGLEN_MTTPC,     27760, 15694,  255,
+         0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10F =
+       { "Wacom ISDv4 10F",      WACOM_PKGLEN_MTTPC,     27760, 15694,  255,
+         0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x4001 =
        { "Wacom ISDv4 4001",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2248,6 +2254,8 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0x100) },
        { USB_DEVICE_WACOM(0x101) },
        { USB_DEVICE_WACOM(0x10D) },
+       { USB_DEVICE_WACOM(0x10E) },
+       { USB_DEVICE_WACOM(0x10F) },
        { USB_DEVICE_WACOM(0x300) },
        { USB_DEVICE_WACOM(0x301) },
        { USB_DEVICE_WACOM(0x304) },
index be12fbf..1ea7523 100644 (file)
@@ -552,9 +552,8 @@ static void __ref enable_slot(struct acpiphp_slot *slot)
        struct acpiphp_func *func;
        int max, pass;
        LIST_HEAD(add_list);
-       int nr_found;
 
-       nr_found = acpiphp_rescan_slot(slot);
+       acpiphp_rescan_slot(slot);
        max = acpiphp_max_busnr(bus);
        for (pass = 0; pass < 2; pass++) {
                list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -574,9 +573,6 @@ static void __ref enable_slot(struct acpiphp_slot *slot)
                }
        }
        __pci_bus_assign_resources(bus, &add_list, NULL);
-       /* Nothing more to do here if there are no new devices on this bus. */
-       if (!nr_found && (slot->flags & SLOT_ENABLED))
-               return;
 
        acpiphp_sanitize_bus(bus);
        acpiphp_set_hpp_values(bus);
index 20532cb..ae6ebb8 100644 (file)
@@ -542,7 +542,7 @@ EXPORT_SYMBOL(d_drop);
  * If ref is non-zero, then decrement the refcount too.
  * Returns dentry requiring refcount drop, or NULL if we're done.
  */
-static inline struct dentry *
+static struct dentry *
 dentry_kill(struct dentry *dentry, int unlock_on_failure)
        __releases(dentry->d_lock)
 {
@@ -630,7 +630,8 @@ repeat:
                        goto kill_it;
        }
 
-       dentry->d_flags |= DCACHE_REFERENCED;
+       if (!(dentry->d_flags & DCACHE_REFERENCED))
+               dentry->d_flags |= DCACHE_REFERENCED;
        dentry_lru_add(dentry);
 
        dentry->d_lockref.count--;
index 473e09d..810c28f 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/mutex.h>
 #include <linux/anon_inodes.h>
 #include <linux/device.h>
-#include <linux/freezer.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/mman.h>
@@ -1605,8 +1604,7 @@ fetch_events:
                        }
 
                        spin_unlock_irqrestore(&ep->lock, flags);
-                       if (!freezable_schedule_hrtimeout_range(to, slack,
-                                                               HRTIMER_MODE_ABS))
+                       if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
                                timed_out = 1;
 
                        spin_lock_irqsave(&ep->lock, flags);
index 35d4adc..dfd5cb1 100644 (file)
@@ -238,8 +238,7 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
 
        set_current_state(state);
        if (!pwq->triggered)
-               rc = freezable_schedule_hrtimeout_range(expires, slack,
-                                                       HRTIMER_MODE_ABS);
+               rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS);
        __set_current_state(TASK_RUNNING);
 
        /*
index 610e3df..cca80d9 100644 (file)
@@ -1278,64 +1278,90 @@ out:
 int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                                unsigned long addr, pmd_t pmd, pmd_t *pmdp)
 {
+       struct anon_vma *anon_vma = NULL;
        struct page *page;
        unsigned long haddr = addr & HPAGE_PMD_MASK;
+       int page_nid = -1, this_nid = numa_node_id();
        int target_nid;
-       int current_nid = -1;
-       bool migrated;
+       bool page_locked;
+       bool migrated = false;
 
        spin_lock(&mm->page_table_lock);
        if (unlikely(!pmd_same(pmd, *pmdp)))
                goto out_unlock;
 
        page = pmd_page(pmd);
-       get_page(page);
-       current_nid = page_to_nid(page);
+       page_nid = page_to_nid(page);
        count_vm_numa_event(NUMA_HINT_FAULTS);
-       if (current_nid == numa_node_id())
+       if (page_nid == this_nid)
                count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
 
+       /*
+        * Acquire the page lock to serialise THP migrations but avoid dropping
+        * page_table_lock if at all possible
+        */
+       page_locked = trylock_page(page);
        target_nid = mpol_misplaced(page, vma, haddr);
        if (target_nid == -1) {
-               put_page(page);
-               goto clear_pmdnuma;
+               /* If the page was locked, there are no parallel migrations */
+               if (page_locked)
+                       goto clear_pmdnuma;
+
+               /*
+                * Otherwise wait for potential migrations and retry. We do
+                * relock and check_same as the page may no longer be mapped.
+                * As the fault is being retried, do not account for it.
+                */
+               spin_unlock(&mm->page_table_lock);
+               wait_on_page_locked(page);
+               page_nid = -1;
+               goto out;
        }
 
-       /* Acquire the page lock to serialise THP migrations */
+       /* Page is misplaced, serialise migrations and parallel THP splits */
+       get_page(page);
        spin_unlock(&mm->page_table_lock);
-       lock_page(page);
+       if (!page_locked)
+               lock_page(page);
+       anon_vma = page_lock_anon_vma_read(page);
 
        /* Confirm the PTE did not while locked */
        spin_lock(&mm->page_table_lock);
        if (unlikely(!pmd_same(pmd, *pmdp))) {
                unlock_page(page);
                put_page(page);
+               page_nid = -1;
                goto out_unlock;
        }
-       spin_unlock(&mm->page_table_lock);
 
-       /* Migrate the THP to the requested node */
+       /*
+        * Migrate the THP to the requested node, returns with page unlocked
+        * and pmd_numa cleared.
+        */
+       spin_unlock(&mm->page_table_lock);
        migrated = migrate_misplaced_transhuge_page(mm, vma,
                                pmdp, pmd, addr, page, target_nid);
-       if (!migrated)
-               goto check_same;
-
-       task_numa_fault(target_nid, HPAGE_PMD_NR, true);
-       return 0;
+       if (migrated)
+               page_nid = target_nid;
 
-check_same:
-       spin_lock(&mm->page_table_lock);
-       if (unlikely(!pmd_same(pmd, *pmdp)))
-               goto out_unlock;
+       goto out;
 clear_pmdnuma:
+       BUG_ON(!PageLocked(page));
        pmd = pmd_mknonnuma(pmd);
        set_pmd_at(mm, haddr, pmdp, pmd);
        VM_BUG_ON(pmd_numa(*pmdp));
        update_mmu_cache_pmd(vma, addr, pmdp);
+       unlock_page(page);
 out_unlock:
        spin_unlock(&mm->page_table_lock);
-       if (current_nid != -1)
-               task_numa_fault(current_nid, HPAGE_PMD_NR, false);
+
+out:
+       if (anon_vma)
+               page_unlock_anon_vma_read(anon_vma);
+
+       if (page_nid != -1)
+               task_numa_fault(page_nid, HPAGE_PMD_NR, migrated);
+
        return 0;
 }
 
index 1311f26..d176154 100644 (file)
@@ -3521,12 +3521,12 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 }
 
 int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
-                               unsigned long addr, int current_nid)
+                               unsigned long addr, int page_nid)
 {
        get_page(page);
 
        count_vm_numa_event(NUMA_HINT_FAULTS);
-       if (current_nid == numa_node_id())
+       if (page_nid == numa_node_id())
                count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
 
        return mpol_misplaced(page, vma, addr);
@@ -3537,7 +3537,7 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
 {
        struct page *page = NULL;
        spinlock_t *ptl;
-       int current_nid = -1;
+       int page_nid = -1;
        int target_nid;
        bool migrated = false;
 
@@ -3567,15 +3567,10 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                return 0;
        }
 
-       current_nid = page_to_nid(page);
-       target_nid = numa_migrate_prep(page, vma, addr, current_nid);
+       page_nid = page_to_nid(page);
+       target_nid = numa_migrate_prep(page, vma, addr, page_nid);
        pte_unmap_unlock(ptep, ptl);
        if (target_nid == -1) {
-               /*
-                * Account for the fault against the current node if it not
-                * being replaced regardless of where the page is located.
-                */
-               current_nid = numa_node_id();
                put_page(page);
                goto out;
        }
@@ -3583,11 +3578,11 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
        /* Migrate to the requested node */
        migrated = migrate_misplaced_page(page, target_nid);
        if (migrated)
-               current_nid = target_nid;
+               page_nid = target_nid;
 
 out:
-       if (current_nid != -1)
-               task_numa_fault(current_nid, 1, migrated);
+       if (page_nid != -1)
+               task_numa_fault(page_nid, 1, migrated);
        return 0;
 }
 
@@ -3602,7 +3597,6 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
        unsigned long offset;
        spinlock_t *ptl;
        bool numa = false;
-       int local_nid = numa_node_id();
 
        spin_lock(&mm->page_table_lock);
        pmd = *pmdp;
@@ -3625,9 +3619,10 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
        for (addr = _addr + offset; addr < _addr + PMD_SIZE; pte++, addr += PAGE_SIZE) {
                pte_t pteval = *pte;
                struct page *page;
-               int curr_nid = local_nid;
+               int page_nid = -1;
                int target_nid;
-               bool migrated;
+               bool migrated = false;
+
                if (!pte_present(pteval))
                        continue;
                if (!pte_numa(pteval))
@@ -3649,25 +3644,19 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                if (unlikely(page_mapcount(page) != 1))
                        continue;
 
-               /*
-                * Note that the NUMA fault is later accounted to either
-                * the node that is currently running or where the page is
-                * migrated to.
-                */
-               curr_nid = local_nid;
-               target_nid = numa_migrate_prep(page, vma, addr,
-                                              page_to_nid(page));
-               if (target_nid == -1) {
+               page_nid = page_to_nid(page);
+               target_nid = numa_migrate_prep(page, vma, addr, page_nid);
+               pte_unmap_unlock(pte, ptl);
+               if (target_nid != -1) {
+                       migrated = migrate_misplaced_page(page, target_nid);
+                       if (migrated)
+                               page_nid = target_nid;
+               } else {
                        put_page(page);
-                       continue;
                }
 
-               /* Migrate to the requested node */
-               pte_unmap_unlock(pte, ptl);
-               migrated = migrate_misplaced_page(page, target_nid);
-               if (migrated)
-                       curr_nid = target_nid;
-               task_numa_fault(curr_nid, 1, migrated);
+               if (page_nid != -1)
+                       task_numa_fault(page_nid, 1, migrated);
 
                pte = pte_offset_map_lock(mm, pmdp, addr, &ptl);
        }
index 7a7325e..c046927 100644 (file)
@@ -1715,12 +1715,12 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                unlock_page(new_page);
                put_page(new_page);             /* Free it */
 
-               unlock_page(page);
+               /* Retake the callers reference and putback on LRU */
+               get_page(page);
                putback_lru_page(page);
-
-               count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);
-               isolated = 0;
-               goto out;
+               mod_zone_page_state(page_zone(page),
+                        NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR);
+               goto out_fail;
        }
 
        /*
@@ -1737,9 +1737,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
        entry = pmd_mkhuge(entry);
 
-       page_add_new_anon_rmap(new_page, vma, haddr);
-
+       pmdp_clear_flush(vma, haddr, pmd);
        set_pmd_at(mm, haddr, pmd, entry);
+       page_add_new_anon_rmap(new_page, vma, haddr);
        update_mmu_cache_pmd(vma, address, &entry);
        page_remove_rmap(page);
        /*
@@ -1758,7 +1758,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        count_vm_events(PGMIGRATE_SUCCESS, HPAGE_PMD_NR);
        count_vm_numa_events(NUMA_PAGE_MIGRATE, HPAGE_PMD_NR);
 
-out:
        mod_zone_page_state(page_zone(page),
                        NR_ISOLATED_ANON + page_lru,
                        -HPAGE_PMD_NR);
@@ -1767,6 +1766,10 @@ out:
 out_fail:
        count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);
 out_dropref:
+       entry = pmd_mknonnuma(entry);
+       set_pmd_at(mm, haddr, pmd, entry);
+       update_mmu_cache_pmd(vma, address, &entry);
+
        unlock_page(page);
        put_page(page);
        return 0;
index a3af058..412ba2b 100644 (file)
@@ -148,7 +148,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
                                split_huge_page_pmd(vma, addr, pmd);
                        else if (change_huge_pmd(vma, pmd, addr, newprot,
                                                 prot_numa)) {
-                               pages += HPAGE_PMD_NR;
+                               pages++;
                                continue;
                        }
                        /* fall through */