diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/hugetlb.c | 2 | ||||
| -rw-r--r-- | mm/kmemleak.c | 4 | ||||
| -rw-r--r-- | mm/memcontrol.c | 23 | ||||
| -rw-r--r-- | mm/memory.c | 11 | ||||
| -rw-r--r-- | mm/page_alloc.c | 21 | ||||
| -rw-r--r-- | mm/swapfile.c | 4 |
6 files changed, 46 insertions, 19 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d0351e31f474..cafdcee154e8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -2370,7 +2370,7 @@ void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) | |||
| 2370 | long chg = region_truncate(&inode->i_mapping->private_list, offset); | 2370 | long chg = region_truncate(&inode->i_mapping->private_list, offset); |
| 2371 | 2371 | ||
| 2372 | spin_lock(&inode->i_lock); | 2372 | spin_lock(&inode->i_lock); |
| 2373 | inode->i_blocks -= blocks_per_huge_page(h); | 2373 | inode->i_blocks -= (blocks_per_huge_page(h) * freed); |
| 2374 | spin_unlock(&inode->i_lock); | 2374 | spin_unlock(&inode->i_lock); |
| 2375 | 2375 | ||
| 2376 | hugetlb_put_quota(inode->i_mapping, (chg - freed)); | 2376 | hugetlb_put_quota(inode->i_mapping, (chg - freed)); |
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 5aabd41ffb8f..487267310a84 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
| @@ -1217,7 +1217,6 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) | |||
| 1217 | } | 1217 | } |
| 1218 | object = NULL; | 1218 | object = NULL; |
| 1219 | out: | 1219 | out: |
| 1220 | rcu_read_unlock(); | ||
| 1221 | return object; | 1220 | return object; |
| 1222 | } | 1221 | } |
| 1223 | 1222 | ||
| @@ -1233,13 +1232,11 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
| 1233 | 1232 | ||
| 1234 | ++(*pos); | 1233 | ++(*pos); |
| 1235 | 1234 | ||
| 1236 | rcu_read_lock(); | ||
| 1237 | list_for_each_continue_rcu(n, &object_list) { | 1235 | list_for_each_continue_rcu(n, &object_list) { |
| 1238 | next_obj = list_entry(n, struct kmemleak_object, object_list); | 1236 | next_obj = list_entry(n, struct kmemleak_object, object_list); |
| 1239 | if (get_object(next_obj)) | 1237 | if (get_object(next_obj)) |
| 1240 | break; | 1238 | break; |
| 1241 | } | 1239 | } |
| 1242 | rcu_read_unlock(); | ||
| 1243 | 1240 | ||
| 1244 | put_object(prev_obj); | 1241 | put_object(prev_obj); |
| 1245 | return next_obj; | 1242 | return next_obj; |
| @@ -1255,6 +1252,7 @@ static void kmemleak_seq_stop(struct seq_file *seq, void *v) | |||
| 1255 | * kmemleak_seq_start may return ERR_PTR if the scan_mutex | 1252 | * kmemleak_seq_start may return ERR_PTR if the scan_mutex |
| 1256 | * waiting was interrupted, so only release it if !IS_ERR. | 1253 | * waiting was interrupted, so only release it if !IS_ERR. |
| 1257 | */ | 1254 | */ |
| 1255 | rcu_read_unlock(); | ||
| 1258 | mutex_unlock(&scan_mutex); | 1256 | mutex_unlock(&scan_mutex); |
| 1259 | if (v) | 1257 | if (v) |
| 1260 | put_object(v); | 1258 | put_object(v); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e717964cb5a0..fd4529d86de5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -1207,6 +1207,12 @@ static int mem_cgroup_move_account(struct page_cgroup *pc, | |||
| 1207 | ret = 0; | 1207 | ret = 0; |
| 1208 | out: | 1208 | out: |
| 1209 | unlock_page_cgroup(pc); | 1209 | unlock_page_cgroup(pc); |
| 1210 | /* | ||
| 1211 | * We charges against "to" which may not have any tasks. Then, "to" | ||
| 1212 | * can be under rmdir(). But in current implementation, caller of | ||
| 1213 | * this function is just force_empty() and it's garanteed that | ||
| 1214 | * "to" is never removed. So, we don't check rmdir status here. | ||
| 1215 | */ | ||
| 1210 | return ret; | 1216 | return ret; |
| 1211 | } | 1217 | } |
| 1212 | 1218 | ||
| @@ -1428,6 +1434,7 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr, | |||
| 1428 | return; | 1434 | return; |
| 1429 | if (!ptr) | 1435 | if (!ptr) |
| 1430 | return; | 1436 | return; |
| 1437 | cgroup_exclude_rmdir(&ptr->css); | ||
| 1431 | pc = lookup_page_cgroup(page); | 1438 | pc = lookup_page_cgroup(page); |
| 1432 | mem_cgroup_lru_del_before_commit_swapcache(page); | 1439 | mem_cgroup_lru_del_before_commit_swapcache(page); |
| 1433 | __mem_cgroup_commit_charge(ptr, pc, ctype); | 1440 | __mem_cgroup_commit_charge(ptr, pc, ctype); |
| @@ -1457,8 +1464,12 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr, | |||
| 1457 | } | 1464 | } |
| 1458 | rcu_read_unlock(); | 1465 | rcu_read_unlock(); |
| 1459 | } | 1466 | } |
| 1460 | /* add this page(page_cgroup) to the LRU we want. */ | 1467 | /* |
| 1461 | 1468 | * At swapin, we may charge account against cgroup which has no tasks. | |
| 1469 | * So, rmdir()->pre_destroy() can be called while we do this charge. | ||
| 1470 | * In that case, we need to call pre_destroy() again. check it here. | ||
| 1471 | */ | ||
| 1472 | cgroup_release_and_wakeup_rmdir(&ptr->css); | ||
| 1462 | } | 1473 | } |
| 1463 | 1474 | ||
| 1464 | void mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr) | 1475 | void mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr) |
| @@ -1664,7 +1675,7 @@ void mem_cgroup_end_migration(struct mem_cgroup *mem, | |||
| 1664 | 1675 | ||
| 1665 | if (!mem) | 1676 | if (!mem) |
| 1666 | return; | 1677 | return; |
| 1667 | 1678 | cgroup_exclude_rmdir(&mem->css); | |
| 1668 | /* at migration success, oldpage->mapping is NULL. */ | 1679 | /* at migration success, oldpage->mapping is NULL. */ |
| 1669 | if (oldpage->mapping) { | 1680 | if (oldpage->mapping) { |
| 1670 | target = oldpage; | 1681 | target = oldpage; |
| @@ -1704,6 +1715,12 @@ void mem_cgroup_end_migration(struct mem_cgroup *mem, | |||
| 1704 | */ | 1715 | */ |
| 1705 | if (ctype == MEM_CGROUP_CHARGE_TYPE_MAPPED) | 1716 | if (ctype == MEM_CGROUP_CHARGE_TYPE_MAPPED) |
| 1706 | mem_cgroup_uncharge_page(target); | 1717 | mem_cgroup_uncharge_page(target); |
| 1718 | /* | ||
| 1719 | * At migration, we may charge account against cgroup which has no tasks | ||
| 1720 | * So, rmdir()->pre_destroy() can be called while we do this charge. | ||
| 1721 | * In that case, we need to call pre_destroy() again. check it here. | ||
| 1722 | */ | ||
| 1723 | cgroup_release_and_wakeup_rmdir(&mem->css); | ||
| 1707 | } | 1724 | } |
| 1708 | 1725 | ||
| 1709 | /* | 1726 | /* |
diff --git a/mm/memory.c b/mm/memory.c index 65216194eb8d..aede2ce3aba4 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -135,11 +135,12 @@ void pmd_clear_bad(pmd_t *pmd) | |||
| 135 | * Note: this doesn't free the actual pages themselves. That | 135 | * Note: this doesn't free the actual pages themselves. That |
| 136 | * has been handled earlier when unmapping all the memory regions. | 136 | * has been handled earlier when unmapping all the memory regions. |
| 137 | */ | 137 | */ |
| 138 | static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd) | 138 | static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, |
| 139 | unsigned long addr) | ||
| 139 | { | 140 | { |
| 140 | pgtable_t token = pmd_pgtable(*pmd); | 141 | pgtable_t token = pmd_pgtable(*pmd); |
| 141 | pmd_clear(pmd); | 142 | pmd_clear(pmd); |
| 142 | pte_free_tlb(tlb, token); | 143 | pte_free_tlb(tlb, token, addr); |
| 143 | tlb->mm->nr_ptes--; | 144 | tlb->mm->nr_ptes--; |
| 144 | } | 145 | } |
| 145 | 146 | ||
| @@ -157,7 +158,7 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | |||
| 157 | next = pmd_addr_end(addr, end); | 158 | next = pmd_addr_end(addr, end); |
| 158 | if (pmd_none_or_clear_bad(pmd)) | 159 | if (pmd_none_or_clear_bad(pmd)) |
| 159 | continue; | 160 | continue; |
| 160 | free_pte_range(tlb, pmd); | 161 | free_pte_range(tlb, pmd, addr); |
| 161 | } while (pmd++, addr = next, addr != end); | 162 | } while (pmd++, addr = next, addr != end); |
| 162 | 163 | ||
| 163 | start &= PUD_MASK; | 164 | start &= PUD_MASK; |
| @@ -173,7 +174,7 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | |||
| 173 | 174 | ||
| 174 | pmd = pmd_offset(pud, start); | 175 | pmd = pmd_offset(pud, start); |
| 175 | pud_clear(pud); | 176 | pud_clear(pud); |
| 176 | pmd_free_tlb(tlb, pmd); | 177 | pmd_free_tlb(tlb, pmd, start); |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 179 | static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, | 180 | static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, |
| @@ -206,7 +207,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, | |||
| 206 | 207 | ||
| 207 | pud = pud_offset(pgd, start); | 208 | pud = pud_offset(pgd, start); |
| 208 | pgd_clear(pgd); | 209 | pgd_clear(pgd); |
| 209 | pud_free_tlb(tlb, pud); | 210 | pud_free_tlb(tlb, pud, start); |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | /* | 213 | /* |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index caa92689aac9..d052abbe3063 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -882,7 +882,7 @@ retry_reserve: | |||
| 882 | */ | 882 | */ |
| 883 | static int rmqueue_bulk(struct zone *zone, unsigned int order, | 883 | static int rmqueue_bulk(struct zone *zone, unsigned int order, |
| 884 | unsigned long count, struct list_head *list, | 884 | unsigned long count, struct list_head *list, |
| 885 | int migratetype) | 885 | int migratetype, int cold) |
| 886 | { | 886 | { |
| 887 | int i; | 887 | int i; |
| 888 | 888 | ||
| @@ -901,7 +901,10 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
| 901 | * merge IO requests if the physical pages are ordered | 901 | * merge IO requests if the physical pages are ordered |
| 902 | * properly. | 902 | * properly. |
| 903 | */ | 903 | */ |
| 904 | list_add(&page->lru, list); | 904 | if (likely(cold == 0)) |
| 905 | list_add(&page->lru, list); | ||
| 906 | else | ||
| 907 | list_add_tail(&page->lru, list); | ||
| 905 | set_page_private(page, migratetype); | 908 | set_page_private(page, migratetype); |
| 906 | list = &page->lru; | 909 | list = &page->lru; |
| 907 | } | 910 | } |
| @@ -1119,7 +1122,8 @@ again: | |||
| 1119 | local_irq_save(flags); | 1122 | local_irq_save(flags); |
| 1120 | if (!pcp->count) { | 1123 | if (!pcp->count) { |
| 1121 | pcp->count = rmqueue_bulk(zone, 0, | 1124 | pcp->count = rmqueue_bulk(zone, 0, |
| 1122 | pcp->batch, &pcp->list, migratetype); | 1125 | pcp->batch, &pcp->list, |
| 1126 | migratetype, cold); | ||
| 1123 | if (unlikely(!pcp->count)) | 1127 | if (unlikely(!pcp->count)) |
| 1124 | goto failed; | 1128 | goto failed; |
| 1125 | } | 1129 | } |
| @@ -1138,7 +1142,8 @@ again: | |||
| 1138 | /* Allocate more to the pcp list if necessary */ | 1142 | /* Allocate more to the pcp list if necessary */ |
| 1139 | if (unlikely(&page->lru == &pcp->list)) { | 1143 | if (unlikely(&page->lru == &pcp->list)) { |
| 1140 | pcp->count += rmqueue_bulk(zone, 0, | 1144 | pcp->count += rmqueue_bulk(zone, 0, |
| 1141 | pcp->batch, &pcp->list, migratetype); | 1145 | pcp->batch, &pcp->list, |
| 1146 | migratetype, cold); | ||
| 1142 | page = list_entry(pcp->list.next, struct page, lru); | 1147 | page = list_entry(pcp->list.next, struct page, lru); |
| 1143 | } | 1148 | } |
| 1144 | 1149 | ||
| @@ -1740,8 +1745,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | |||
| 1740 | * be using allocators in order of preference for an area that is | 1745 | * be using allocators in order of preference for an area that is |
| 1741 | * too large. | 1746 | * too large. |
| 1742 | */ | 1747 | */ |
| 1743 | if (WARN_ON_ONCE(order >= MAX_ORDER)) | 1748 | if (order >= MAX_ORDER) { |
| 1749 | WARN_ON_ONCE(!(gfp_mask & __GFP_NOWARN)); | ||
| 1744 | return NULL; | 1750 | return NULL; |
| 1751 | } | ||
| 1745 | 1752 | ||
| 1746 | /* | 1753 | /* |
| 1747 | * GFP_THISNODE (meaning __GFP_THISNODE, __GFP_NORETRY and | 1754 | * GFP_THISNODE (meaning __GFP_THISNODE, __GFP_NORETRY and |
| @@ -1789,6 +1796,10 @@ rebalance: | |||
| 1789 | if (p->flags & PF_MEMALLOC) | 1796 | if (p->flags & PF_MEMALLOC) |
| 1790 | goto nopage; | 1797 | goto nopage; |
| 1791 | 1798 | ||
| 1799 | /* Avoid allocations with no watermarks from looping endlessly */ | ||
| 1800 | if (test_thread_flag(TIF_MEMDIE) && !(gfp_mask & __GFP_NOFAIL)) | ||
| 1801 | goto nopage; | ||
| 1802 | |||
| 1792 | /* Try direct reclaim and then allocating */ | 1803 | /* Try direct reclaim and then allocating */ |
| 1793 | page = __alloc_pages_direct_reclaim(gfp_mask, order, | 1804 | page = __alloc_pages_direct_reclaim(gfp_mask, order, |
| 1794 | zonelist, high_zoneidx, | 1805 | zonelist, high_zoneidx, |
diff --git a/mm/swapfile.c b/mm/swapfile.c index d1ade1a48ee7..8ffdc0d23c53 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
| @@ -753,7 +753,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) | |||
| 753 | 753 | ||
| 754 | if (!bdev) { | 754 | if (!bdev) { |
| 755 | if (bdev_p) | 755 | if (bdev_p) |
| 756 | *bdev_p = bdget(sis->bdev->bd_dev); | 756 | *bdev_p = bdgrab(sis->bdev); |
| 757 | 757 | ||
| 758 | spin_unlock(&swap_lock); | 758 | spin_unlock(&swap_lock); |
| 759 | return i; | 759 | return i; |
| @@ -765,7 +765,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) | |||
| 765 | struct swap_extent, list); | 765 | struct swap_extent, list); |
| 766 | if (se->start_block == offset) { | 766 | if (se->start_block == offset) { |
| 767 | if (bdev_p) | 767 | if (bdev_p) |
| 768 | *bdev_p = bdget(sis->bdev->bd_dev); | 768 | *bdev_p = bdgrab(sis->bdev); |
| 769 | 769 | ||
| 770 | spin_unlock(&swap_lock); | 770 | spin_unlock(&swap_lock); |
| 771 | bdput(bdev); | 771 | bdput(bdev); |
