diff options
| -rw-r--r-- | MAINTAINERS | 3 | ||||
| -rw-r--r-- | arch/sh/kernel/sh_ksyms_32.c | 5 | ||||
| -rw-r--r-- | drivers/dma/ioat/dma.c | 11 | ||||
| -rw-r--r-- | fs/eventpoll.c | 4 | ||||
| -rw-r--r-- | mm/fremap.c | 8 | ||||
| -rw-r--r-- | mm/huge_memory.c | 3 | ||||
| -rw-r--r-- | mm/memcontrol.c | 2 | ||||
| -rw-r--r-- | mm/memory-failure.c | 10 | ||||
| -rw-r--r-- | mm/mlock.c | 44 |
9 files changed, 66 insertions, 24 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 21c038f216e3..6c2079270791 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1368,6 +1368,9 @@ T: git git://git.xilinx.com/linux-xlnx.git | |||
| 1368 | S: Supported | 1368 | S: Supported |
| 1369 | F: arch/arm/mach-zynq/ | 1369 | F: arch/arm/mach-zynq/ |
| 1370 | F: drivers/cpuidle/cpuidle-zynq.c | 1370 | F: drivers/cpuidle/cpuidle-zynq.c |
| 1371 | N: zynq | ||
| 1372 | N: xilinx | ||
| 1373 | F: drivers/clocksource/cadence_ttc_timer.c | ||
| 1371 | 1374 | ||
| 1372 | ARM SMMU DRIVER | 1375 | ARM SMMU DRIVER |
| 1373 | M: Will Deacon <will.deacon@arm.com> | 1376 | M: Will Deacon <will.deacon@arm.com> |
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 2a0a596ebf67..d77f2f6c7ff0 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c | |||
| @@ -20,6 +20,11 @@ EXPORT_SYMBOL(csum_partial_copy_generic); | |||
| 20 | EXPORT_SYMBOL(copy_page); | 20 | EXPORT_SYMBOL(copy_page); |
| 21 | EXPORT_SYMBOL(__clear_user); | 21 | EXPORT_SYMBOL(__clear_user); |
| 22 | EXPORT_SYMBOL(empty_zero_page); | 22 | EXPORT_SYMBOL(empty_zero_page); |
| 23 | #ifdef CONFIG_FLATMEM | ||
| 24 | /* need in pfn_valid macro */ | ||
| 25 | EXPORT_SYMBOL(min_low_pfn); | ||
| 26 | EXPORT_SYMBOL(max_low_pfn); | ||
| 27 | #endif | ||
| 23 | 28 | ||
| 24 | #define DECLARE_EXPORT(name) \ | 29 | #define DECLARE_EXPORT(name) \ |
| 25 | extern void name(void);EXPORT_SYMBOL(name) | 30 | extern void name(void);EXPORT_SYMBOL(name) |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 1a49c777607c..87529181efcc 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
| @@ -817,7 +817,15 @@ int ioat_dma_self_test(struct ioatdma_device *device) | |||
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | dma_src = dma_map_single(dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE); | 819 | dma_src = dma_map_single(dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE); |
| 820 | if (dma_mapping_error(dev, dma_src)) { | ||
| 821 | dev_err(dev, "mapping src buffer failed\n"); | ||
| 822 | goto free_resources; | ||
| 823 | } | ||
| 820 | dma_dest = dma_map_single(dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); | 824 | dma_dest = dma_map_single(dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); |
| 825 | if (dma_mapping_error(dev, dma_dest)) { | ||
| 826 | dev_err(dev, "mapping dest buffer failed\n"); | ||
| 827 | goto unmap_src; | ||
| 828 | } | ||
| 821 | flags = DMA_PREP_INTERRUPT; | 829 | flags = DMA_PREP_INTERRUPT; |
| 822 | tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src, | 830 | tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src, |
| 823 | IOAT_TEST_SIZE, flags); | 831 | IOAT_TEST_SIZE, flags); |
| @@ -855,8 +863,9 @@ int ioat_dma_self_test(struct ioatdma_device *device) | |||
| 855 | } | 863 | } |
| 856 | 864 | ||
| 857 | unmap_dma: | 865 | unmap_dma: |
| 858 | dma_unmap_single(dev, dma_src, IOAT_TEST_SIZE, DMA_TO_DEVICE); | ||
| 859 | dma_unmap_single(dev, dma_dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); | 866 | dma_unmap_single(dev, dma_dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); |
| 867 | unmap_src: | ||
| 868 | dma_unmap_single(dev, dma_src, IOAT_TEST_SIZE, DMA_TO_DEVICE); | ||
| 860 | free_resources: | 869 | free_resources: |
| 861 | dma->device_free_chan_resources(dma_chan); | 870 | dma->device_free_chan_resources(dma_chan); |
| 862 | out: | 871 | out: |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 8b5e2584c840..af903128891c 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
| @@ -1907,10 +1907,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
| 1907 | } | 1907 | } |
| 1908 | } | 1908 | } |
| 1909 | } | 1909 | } |
| 1910 | if (op == EPOLL_CTL_DEL && is_file_epoll(tf.file)) { | ||
| 1911 | tep = tf.file->private_data; | ||
| 1912 | mutex_lock_nested(&tep->mtx, 1); | ||
| 1913 | } | ||
| 1914 | 1910 | ||
| 1915 | /* | 1911 | /* |
| 1916 | * Try to lookup the file inside our RB tree, Since we grabbed "mtx" | 1912 | * Try to lookup the file inside our RB tree, Since we grabbed "mtx" |
diff --git a/mm/fremap.c b/mm/fremap.c index 5bff08147768..bbc4d660221a 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
| @@ -208,9 +208,10 @@ get_write_lock: | |||
| 208 | if (mapping_cap_account_dirty(mapping)) { | 208 | if (mapping_cap_account_dirty(mapping)) { |
| 209 | unsigned long addr; | 209 | unsigned long addr; |
| 210 | struct file *file = get_file(vma->vm_file); | 210 | struct file *file = get_file(vma->vm_file); |
| 211 | /* mmap_region may free vma; grab the info now */ | ||
| 212 | vm_flags = vma->vm_flags; | ||
| 211 | 213 | ||
| 212 | addr = mmap_region(file, start, size, | 214 | addr = mmap_region(file, start, size, vm_flags, pgoff); |
| 213 | vma->vm_flags, pgoff); | ||
| 214 | fput(file); | 215 | fput(file); |
| 215 | if (IS_ERR_VALUE(addr)) { | 216 | if (IS_ERR_VALUE(addr)) { |
| 216 | err = addr; | 217 | err = addr; |
| @@ -218,7 +219,7 @@ get_write_lock: | |||
| 218 | BUG_ON(addr != start); | 219 | BUG_ON(addr != start); |
| 219 | err = 0; | 220 | err = 0; |
| 220 | } | 221 | } |
| 221 | goto out; | 222 | goto out_freed; |
| 222 | } | 223 | } |
| 223 | mutex_lock(&mapping->i_mmap_mutex); | 224 | mutex_lock(&mapping->i_mmap_mutex); |
| 224 | flush_dcache_mmap_lock(mapping); | 225 | flush_dcache_mmap_lock(mapping); |
| @@ -253,6 +254,7 @@ get_write_lock: | |||
| 253 | out: | 254 | out: |
| 254 | if (vma) | 255 | if (vma) |
| 255 | vm_flags = vma->vm_flags; | 256 | vm_flags = vma->vm_flags; |
| 257 | out_freed: | ||
| 256 | if (likely(!has_write_lock)) | 258 | if (likely(!has_write_lock)) |
| 257 | up_read(&mm->mmap_sem); | 259 | up_read(&mm->mmap_sem); |
| 258 | else | 260 | else |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 7de1bf85f683..9c0b17295ba0 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
| @@ -883,9 +883,6 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm, | |||
| 883 | goto out_unlock; | 883 | goto out_unlock; |
| 884 | } | 884 | } |
| 885 | 885 | ||
| 886 | /* mmap_sem prevents this happening but warn if that changes */ | ||
| 887 | WARN_ON(pmd_trans_migrating(pmd)); | ||
| 888 | |||
| 889 | if (unlikely(pmd_trans_splitting(pmd))) { | 886 | if (unlikely(pmd_trans_splitting(pmd))) { |
| 890 | /* split huge page running from under us */ | 887 | /* split huge page running from under us */ |
| 891 | spin_unlock(src_ptl); | 888 | spin_unlock(src_ptl); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bf5e89457149..7f1a356153c0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -338,7 +338,7 @@ struct mem_cgroup { | |||
| 338 | static size_t memcg_size(void) | 338 | static size_t memcg_size(void) |
| 339 | { | 339 | { |
| 340 | return sizeof(struct mem_cgroup) + | 340 | return sizeof(struct mem_cgroup) + |
| 341 | nr_node_ids * sizeof(struct mem_cgroup_per_node); | 341 | nr_node_ids * sizeof(struct mem_cgroup_per_node *); |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | /* internal only representation about the status of kmem accounting. */ | 344 | /* internal only representation about the status of kmem accounting. */ |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index db08af92c6fc..fabe55046c1d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
| @@ -938,6 +938,16 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
| 938 | BUG_ON(!PageHWPoison(p)); | 938 | BUG_ON(!PageHWPoison(p)); |
| 939 | return SWAP_FAIL; | 939 | return SWAP_FAIL; |
| 940 | } | 940 | } |
| 941 | /* | ||
| 942 | * We pinned the head page for hwpoison handling, | ||
| 943 | * now we split the thp and we are interested in | ||
| 944 | * the hwpoisoned raw page, so move the refcount | ||
| 945 | * to it. | ||
| 946 | */ | ||
| 947 | if (hpage != p) { | ||
| 948 | put_page(hpage); | ||
| 949 | get_page(p); | ||
| 950 | } | ||
| 941 | /* THP is split, so ppage should be the real poisoned page. */ | 951 | /* THP is split, so ppage should be the real poisoned page. */ |
| 942 | ppage = p; | 952 | ppage = p; |
| 943 | } | 953 | } |
diff --git a/mm/mlock.c b/mm/mlock.c index d480cd6fc475..192e6eebe4f2 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
| @@ -133,7 +133,10 @@ static void __munlock_isolation_failed(struct page *page) | |||
| 133 | 133 | ||
| 134 | /** | 134 | /** |
| 135 | * munlock_vma_page - munlock a vma page | 135 | * munlock_vma_page - munlock a vma page |
| 136 | * @page - page to be unlocked | 136 | * @page - page to be unlocked, either a normal page or THP page head |
| 137 | * | ||
| 138 | * returns the size of the page as a page mask (0 for normal page, | ||
| 139 | * HPAGE_PMD_NR - 1 for THP head page) | ||
| 137 | * | 140 | * |
| 138 | * called from munlock()/munmap() path with page supposedly on the LRU. | 141 | * called from munlock()/munmap() path with page supposedly on the LRU. |
| 139 | * When we munlock a page, because the vma where we found the page is being | 142 | * When we munlock a page, because the vma where we found the page is being |
| @@ -148,21 +151,30 @@ static void __munlock_isolation_failed(struct page *page) | |||
| 148 | */ | 151 | */ |
| 149 | unsigned int munlock_vma_page(struct page *page) | 152 | unsigned int munlock_vma_page(struct page *page) |
| 150 | { | 153 | { |
| 151 | unsigned int page_mask = 0; | 154 | unsigned int nr_pages; |
| 152 | 155 | ||
| 153 | BUG_ON(!PageLocked(page)); | 156 | BUG_ON(!PageLocked(page)); |
| 154 | 157 | ||
| 155 | if (TestClearPageMlocked(page)) { | 158 | if (TestClearPageMlocked(page)) { |
| 156 | unsigned int nr_pages = hpage_nr_pages(page); | 159 | nr_pages = hpage_nr_pages(page); |
| 157 | mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages); | 160 | mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages); |
| 158 | page_mask = nr_pages - 1; | ||
| 159 | if (!isolate_lru_page(page)) | 161 | if (!isolate_lru_page(page)) |
| 160 | __munlock_isolated_page(page); | 162 | __munlock_isolated_page(page); |
| 161 | else | 163 | else |
| 162 | __munlock_isolation_failed(page); | 164 | __munlock_isolation_failed(page); |
| 165 | } else { | ||
| 166 | nr_pages = hpage_nr_pages(page); | ||
| 163 | } | 167 | } |
| 164 | 168 | ||
| 165 | return page_mask; | 169 | /* |
| 170 | * Regardless of the original PageMlocked flag, we determine nr_pages | ||
| 171 | * after touching the flag. This leaves a possible race with a THP page | ||
| 172 | * split, such that a whole THP page was munlocked, but nr_pages == 1. | ||
| 173 | * Returning a smaller mask due to that is OK, the worst that can | ||
| 174 | * happen is subsequent useless scanning of the former tail pages. | ||
| 175 | * The NR_MLOCK accounting can however become broken. | ||
| 176 | */ | ||
| 177 | return nr_pages - 1; | ||
| 166 | } | 178 | } |
| 167 | 179 | ||
| 168 | /** | 180 | /** |
| @@ -286,10 +298,12 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) | |||
| 286 | { | 298 | { |
| 287 | int i; | 299 | int i; |
| 288 | int nr = pagevec_count(pvec); | 300 | int nr = pagevec_count(pvec); |
| 289 | int delta_munlocked = -nr; | 301 | int delta_munlocked; |
| 290 | struct pagevec pvec_putback; | 302 | struct pagevec pvec_putback; |
| 291 | int pgrescued = 0; | 303 | int pgrescued = 0; |
| 292 | 304 | ||
| 305 | pagevec_init(&pvec_putback, 0); | ||
| 306 | |||
| 293 | /* Phase 1: page isolation */ | 307 | /* Phase 1: page isolation */ |
| 294 | spin_lock_irq(&zone->lru_lock); | 308 | spin_lock_irq(&zone->lru_lock); |
| 295 | for (i = 0; i < nr; i++) { | 309 | for (i = 0; i < nr; i++) { |
| @@ -318,18 +332,21 @@ skip_munlock: | |||
| 318 | /* | 332 | /* |
| 319 | * We won't be munlocking this page in the next phase | 333 | * We won't be munlocking this page in the next phase |
| 320 | * but we still need to release the follow_page_mask() | 334 | * but we still need to release the follow_page_mask() |
| 321 | * pin. | 335 | * pin. We cannot do it under lru_lock however. If it's |
| 336 | * the last pin, __page_cache_release would deadlock. | ||
| 322 | */ | 337 | */ |
| 338 | pagevec_add(&pvec_putback, pvec->pages[i]); | ||
| 323 | pvec->pages[i] = NULL; | 339 | pvec->pages[i] = NULL; |
| 324 | put_page(page); | ||
| 325 | delta_munlocked++; | ||
| 326 | } | 340 | } |
| 327 | } | 341 | } |
| 342 | delta_munlocked = -nr + pagevec_count(&pvec_putback); | ||
| 328 | __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked); | 343 | __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked); |
| 329 | spin_unlock_irq(&zone->lru_lock); | 344 | spin_unlock_irq(&zone->lru_lock); |
| 330 | 345 | ||
| 346 | /* Now we can release pins of pages that we are not munlocking */ | ||
| 347 | pagevec_release(&pvec_putback); | ||
| 348 | |||
| 331 | /* Phase 2: page munlock */ | 349 | /* Phase 2: page munlock */ |
| 332 | pagevec_init(&pvec_putback, 0); | ||
| 333 | for (i = 0; i < nr; i++) { | 350 | for (i = 0; i < nr; i++) { |
| 334 | struct page *page = pvec->pages[i]; | 351 | struct page *page = pvec->pages[i]; |
| 335 | 352 | ||
| @@ -440,7 +457,8 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, | |||
| 440 | 457 | ||
| 441 | while (start < end) { | 458 | while (start < end) { |
| 442 | struct page *page = NULL; | 459 | struct page *page = NULL; |
| 443 | unsigned int page_mask, page_increm; | 460 | unsigned int page_mask; |
| 461 | unsigned long page_increm; | ||
| 444 | struct pagevec pvec; | 462 | struct pagevec pvec; |
| 445 | struct zone *zone; | 463 | struct zone *zone; |
| 446 | int zoneid; | 464 | int zoneid; |
| @@ -490,7 +508,9 @@ void munlock_vma_pages_range(struct vm_area_struct *vma, | |||
| 490 | goto next; | 508 | goto next; |
| 491 | } | 509 | } |
| 492 | } | 510 | } |
| 493 | page_increm = 1 + (~(start >> PAGE_SHIFT) & page_mask); | 511 | /* It's a bug to munlock in the middle of a THP page */ |
| 512 | VM_BUG_ON((start >> PAGE_SHIFT) & page_mask); | ||
| 513 | page_increm = 1 + page_mask; | ||
| 494 | start += page_increm * PAGE_SIZE; | 514 | start += page_increm * PAGE_SIZE; |
| 495 | next: | 515 | next: |
| 496 | cond_resched(); | 516 | cond_resched(); |
