diff options
Diffstat (limited to 'kernel/events/uprobes.c')
-rw-r--r-- | kernel/events/uprobes.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 6f3254e8c137..1d0af8a2c646 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -167,6 +167,11 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, | |||
167 | /* For mmu_notifiers */ | 167 | /* For mmu_notifiers */ |
168 | const unsigned long mmun_start = addr; | 168 | const unsigned long mmun_start = addr; |
169 | const unsigned long mmun_end = addr + PAGE_SIZE; | 169 | const unsigned long mmun_end = addr + PAGE_SIZE; |
170 | struct mem_cgroup *memcg; | ||
171 | |||
172 | err = mem_cgroup_try_charge(kpage, vma->vm_mm, GFP_KERNEL, &memcg); | ||
173 | if (err) | ||
174 | return err; | ||
170 | 175 | ||
171 | /* For try_to_free_swap() and munlock_vma_page() below */ | 176 | /* For try_to_free_swap() and munlock_vma_page() below */ |
172 | lock_page(page); | 177 | lock_page(page); |
@@ -179,6 +184,8 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, | |||
179 | 184 | ||
180 | get_page(kpage); | 185 | get_page(kpage); |
181 | page_add_new_anon_rmap(kpage, vma, addr); | 186 | page_add_new_anon_rmap(kpage, vma, addr); |
187 | mem_cgroup_commit_charge(kpage, memcg, false); | ||
188 | lru_cache_add_active_or_unevictable(kpage, vma); | ||
182 | 189 | ||
183 | if (!PageAnon(page)) { | 190 | if (!PageAnon(page)) { |
184 | dec_mm_counter(mm, MM_FILEPAGES); | 191 | dec_mm_counter(mm, MM_FILEPAGES); |
@@ -200,6 +207,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, | |||
200 | 207 | ||
201 | err = 0; | 208 | err = 0; |
202 | unlock: | 209 | unlock: |
210 | mem_cgroup_cancel_charge(kpage, memcg); | ||
203 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); | 211 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); |
204 | unlock_page(page); | 212 | unlock_page(page); |
205 | return err; | 213 | return err; |
@@ -315,18 +323,11 @@ retry: | |||
315 | if (!new_page) | 323 | if (!new_page) |
316 | goto put_old; | 324 | goto put_old; |
317 | 325 | ||
318 | if (mem_cgroup_charge_anon(new_page, mm, GFP_KERNEL)) | ||
319 | goto put_new; | ||
320 | |||
321 | __SetPageUptodate(new_page); | 326 | __SetPageUptodate(new_page); |
322 | copy_highpage(new_page, old_page); | 327 | copy_highpage(new_page, old_page); |
323 | copy_to_page(new_page, vaddr, &opcode, UPROBE_SWBP_INSN_SIZE); | 328 | copy_to_page(new_page, vaddr, &opcode, UPROBE_SWBP_INSN_SIZE); |
324 | 329 | ||
325 | ret = __replace_page(vma, vaddr, old_page, new_page); | 330 | ret = __replace_page(vma, vaddr, old_page, new_page); |
326 | if (ret) | ||
327 | mem_cgroup_uncharge_page(new_page); | ||
328 | |||
329 | put_new: | ||
330 | page_cache_release(new_page); | 331 | page_cache_release(new_page); |
331 | put_old: | 332 | put_old: |
332 | put_page(old_page); | 333 | put_page(old_page); |