diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 6 | ||||
-rw-r--r-- | mm/madvise.c | 2 | ||||
-rw-r--r-- | mm/memcontrol.c | 27 | ||||
-rw-r--r-- | mm/memory-failure.c | 17 |
4 files changed, 29 insertions, 23 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 000a220e2a41..088358c8006b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -257,9 +257,11 @@ static int filemap_check_errors(struct address_space *mapping) | |||
257 | { | 257 | { |
258 | int ret = 0; | 258 | int ret = 0; |
259 | /* Check for outstanding write errors */ | 259 | /* Check for outstanding write errors */ |
260 | if (test_and_clear_bit(AS_ENOSPC, &mapping->flags)) | 260 | if (test_bit(AS_ENOSPC, &mapping->flags) && |
261 | test_and_clear_bit(AS_ENOSPC, &mapping->flags)) | ||
261 | ret = -ENOSPC; | 262 | ret = -ENOSPC; |
262 | if (test_and_clear_bit(AS_EIO, &mapping->flags)) | 263 | if (test_bit(AS_EIO, &mapping->flags) && |
264 | test_and_clear_bit(AS_EIO, &mapping->flags)) | ||
263 | ret = -EIO; | 265 | ret = -EIO; |
264 | return ret; | 266 | return ret; |
265 | } | 267 | } |
diff --git a/mm/madvise.c b/mm/madvise.c index 539eeb96b323..a402f8fdc68e 100644 --- a/mm/madvise.c +++ b/mm/madvise.c | |||
@@ -195,7 +195,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma, | |||
195 | for (; start < end; start += PAGE_SIZE) { | 195 | for (; start < end; start += PAGE_SIZE) { |
196 | index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | 196 | index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; |
197 | 197 | ||
198 | page = find_get_page(mapping, index); | 198 | page = find_get_entry(mapping, index); |
199 | if (!radix_tree_exceptional_entry(page)) { | 199 | if (!radix_tree_exceptional_entry(page)) { |
200 | if (page) | 200 | if (page) |
201 | page_cache_release(page); | 201 | page_cache_release(page); |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c47dffdcb246..5177c6d4a2dd 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1077,9 +1077,18 @@ static struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm) | |||
1077 | 1077 | ||
1078 | rcu_read_lock(); | 1078 | rcu_read_lock(); |
1079 | do { | 1079 | do { |
1080 | memcg = mem_cgroup_from_task(rcu_dereference(mm->owner)); | 1080 | /* |
1081 | if (unlikely(!memcg)) | 1081 | * Page cache insertions can happen withou an |
1082 | * actual mm context, e.g. during disk probing | ||
1083 | * on boot, loopback IO, acct() writes etc. | ||
1084 | */ | ||
1085 | if (unlikely(!mm)) | ||
1082 | memcg = root_mem_cgroup; | 1086 | memcg = root_mem_cgroup; |
1087 | else { | ||
1088 | memcg = mem_cgroup_from_task(rcu_dereference(mm->owner)); | ||
1089 | if (unlikely(!memcg)) | ||
1090 | memcg = root_mem_cgroup; | ||
1091 | } | ||
1083 | } while (!css_tryget(&memcg->css)); | 1092 | } while (!css_tryget(&memcg->css)); |
1084 | rcu_read_unlock(); | 1093 | rcu_read_unlock(); |
1085 | return memcg; | 1094 | return memcg; |
@@ -3958,17 +3967,9 @@ int mem_cgroup_charge_file(struct page *page, struct mm_struct *mm, | |||
3958 | return 0; | 3967 | return 0; |
3959 | } | 3968 | } |
3960 | 3969 | ||
3961 | /* | 3970 | memcg = mem_cgroup_try_charge_mm(mm, gfp_mask, 1, true); |
3962 | * Page cache insertions can happen without an actual mm | 3971 | if (!memcg) |
3963 | * context, e.g. during disk probing on boot. | 3972 | return -ENOMEM; |
3964 | */ | ||
3965 | if (unlikely(!mm)) | ||
3966 | memcg = root_mem_cgroup; | ||
3967 | else { | ||
3968 | memcg = mem_cgroup_try_charge_mm(mm, gfp_mask, 1, true); | ||
3969 | if (!memcg) | ||
3970 | return -ENOMEM; | ||
3971 | } | ||
3972 | __mem_cgroup_commit_charge(memcg, page, 1, type, false); | 3973 | __mem_cgroup_commit_charge(memcg, page, 1, type, false); |
3973 | return 0; | 3974 | return 0; |
3974 | } | 3975 | } |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 35ef28acf137..9ccef39a9de2 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1081,15 +1081,16 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1081 | return 0; | 1081 | return 0; |
1082 | } else if (PageHuge(hpage)) { | 1082 | } else if (PageHuge(hpage)) { |
1083 | /* | 1083 | /* |
1084 | * Check "just unpoisoned", "filter hit", and | 1084 | * Check "filter hit" and "race with other subpage." |
1085 | * "race with other subpage." | ||
1086 | */ | 1085 | */ |
1087 | lock_page(hpage); | 1086 | lock_page(hpage); |
1088 | if (!PageHWPoison(hpage) | 1087 | if (PageHWPoison(hpage)) { |
1089 | || (hwpoison_filter(p) && TestClearPageHWPoison(p)) | 1088 | if ((hwpoison_filter(p) && TestClearPageHWPoison(p)) |
1090 | || (p != hpage && TestSetPageHWPoison(hpage))) { | 1089 | || (p != hpage && TestSetPageHWPoison(hpage))) { |
1091 | atomic_long_sub(nr_pages, &num_poisoned_pages); | 1090 | atomic_long_sub(nr_pages, &num_poisoned_pages); |
1092 | return 0; | 1091 | unlock_page(hpage); |
1092 | return 0; | ||
1093 | } | ||
1093 | } | 1094 | } |
1094 | set_page_hwpoison_huge_page(hpage); | 1095 | set_page_hwpoison_huge_page(hpage); |
1095 | res = dequeue_hwpoisoned_huge_page(hpage); | 1096 | res = dequeue_hwpoisoned_huge_page(hpage); |
@@ -1152,6 +1153,8 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1152 | */ | 1153 | */ |
1153 | if (!PageHWPoison(p)) { | 1154 | if (!PageHWPoison(p)) { |
1154 | printk(KERN_ERR "MCE %#lx: just unpoisoned\n", pfn); | 1155 | printk(KERN_ERR "MCE %#lx: just unpoisoned\n", pfn); |
1156 | atomic_long_sub(nr_pages, &num_poisoned_pages); | ||
1157 | put_page(hpage); | ||
1155 | res = 0; | 1158 | res = 0; |
1156 | goto out; | 1159 | goto out; |
1157 | } | 1160 | } |