All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20130403002309.GD16026@blaptop>

diff --git a/a/1.txt b/N1/1.txt
index 0ee1ac2..4dd3dda 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -20,8 +20,8 @@ On Tue, Apr 02, 2013 at 03:25:25PM +0200, Michael Kerrisk wrote:
 > including MMOTM of 26 March, and encounter this error:
 > 
 >   CC      mm/ksm.o
-> mm/ksm.c: In function a??try_to_unmap_ksma??:
-> mm/ksm.c:1970:32: error: a??vmaa?? undeclared (first use in this function)
+> mm/ksm.c: In function ‘try_to_unmap_ksm’:
+> mm/ksm.c:1970:32: error: ‘vma’ undeclared (first use in this function)
 > mm/ksm.c:1970:32: note: each undeclared identifier is reported only
 > once for each function it appears in
 > make[1]: *** [mm/ksm.o] Error 1
@@ -30,3 +30,415 @@ On Tue, Apr 02, 2013 at 03:25:25PM +0200, Michael Kerrisk wrote:
 I did it based on mmotm-2013-03-22-15-21 and you found build problem.
 Could you apply below patch? I will fix up below in next spin.
 Thanks for the testing!
+
+>From 0934270618ccd4883d6bb05653c664a385fb9441 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Wed, 3 Apr 2013 09:19:49 +0900
+Subject: [PATCH] fix: compile error for CONFIG_KSM
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+---
+ include/linux/rmap.h | 2 ++
+ mm/ksm.c             | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+index 6c7d030..7bcf090 100644
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -14,6 +14,8 @@ extern int isolate_lru_page(struct page *page);
+ extern void putback_lru_page(struct page *page);
+ extern unsigned long reclaim_pages_from_list(struct list_head *page_list,
+ 					     struct vm_area_struct *vma);
++extern unsigned long vma_address(struct page *page,
++				struct vm_area_struct *vma);
+ 
+ /*
+  * The anon_vma heads a list of private "related" vmas, to scan if
+diff --git a/mm/ksm.c b/mm/ksm.c
+index 1a90d13..44de936 100644
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -1967,7 +1967,7 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags,
+ 
+ 	if (target_vma) {
+ 		unsigned long address = vma_address(page, target_vma);
+-		ret = try_to_unmap_one(page, vma, address, flags);
++		ret = try_to_unmap_one(page, target_vma, address, flags);
+ 		goto out;
+ 	}
+ again:
+-- 
+1.8.2
+
+> 
+> Cheers,
+> 
+> Michael
+> 
+> 
+> > Signed-off-by: Sangseok Lee <sangseok.lee@lge.com>
+> > Signed-off-by: Minchan Kim <minchan@kernel.org>
+> > ---
+> >  fs/proc/task_mmu.c   |  2 +-
+> >  include/linux/ksm.h  |  6 ++++--
+> >  include/linux/rmap.h |  8 +++++---
+> >  mm/ksm.c             |  9 +++++++-
+> >  mm/memory-failure.c  |  2 +-
+> >  mm/migrate.c         |  6 ++++--
+> >  mm/rmap.c            | 58 +++++++++++++++++++++++++++++++++++++---------------
+> >  mm/vmscan.c          | 14 +++++++++++--
+> >  8 files changed, 77 insertions(+), 28 deletions(-)
+> >
+> > diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+> > index c3713a4..7f6aaf5 100644
+> > --- a/fs/proc/task_mmu.c
+> > +++ b/fs/proc/task_mmu.c
+> > @@ -1154,7 +1154,7 @@ cont:
+> >                         break;
+> >         }
+> >         pte_unmap_unlock(pte - 1, ptl);
+> > -       reclaim_pages_from_list(&page_list);
+> > +       reclaim_pages_from_list(&page_list, vma);
+> >         if (addr != end)
+> >                 goto cont;
+> >
+> > diff --git a/include/linux/ksm.h b/include/linux/ksm.h
+> > index 45c9b6a..d8e556b 100644
+> > --- a/include/linux/ksm.h
+> > +++ b/include/linux/ksm.h
+> > @@ -75,7 +75,8 @@ struct page *ksm_might_need_to_copy(struct page *page,
+> >
+> >  int page_referenced_ksm(struct page *page,
+> >                         struct mem_cgroup *memcg, unsigned long *vm_flags);
+> > -int try_to_unmap_ksm(struct page *page, enum ttu_flags flags);
+> > +int try_to_unmap_ksm(struct page *page,
+> > +                       enum ttu_flags flags, struct vm_area_struct *vma);
+> >  int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,
+> >                   struct vm_area_struct *, unsigned long, void *), void *arg);
+> >  void ksm_migrate_page(struct page *newpage, struct page *oldpage);
+> > @@ -115,7 +116,8 @@ static inline int page_referenced_ksm(struct page *page,
+> >         return 0;
+> >  }
+> >
+> > -static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
+> > +static inline int try_to_unmap_ksm(struct page *page,
+> > +                       enum ttu_flags flags, struct vm_area_struct *target_vma)
+> >  {
+> >         return 0;
+> >  }
+> > diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+> > index a24e34e..6c7d030 100644
+> > --- a/include/linux/rmap.h
+> > +++ b/include/linux/rmap.h
+> > @@ -12,7 +12,8 @@
+> >
+> >  extern int isolate_lru_page(struct page *page);
+> >  extern void putback_lru_page(struct page *page);
+> > -extern unsigned long reclaim_pages_from_list(struct list_head *page_list);
+> > +extern unsigned long reclaim_pages_from_list(struct list_head *page_list,
+> > +                                            struct vm_area_struct *vma);
+> >
+> >  /*
+> >   * The anon_vma heads a list of private "related" vmas, to scan if
+> > @@ -192,7 +193,8 @@ int page_referenced_one(struct page *, struct vm_area_struct *,
+> >
+> >  #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)
+> >
+> > -int try_to_unmap(struct page *, enum ttu_flags flags);
+> > +int try_to_unmap(struct page *, enum ttu_flags flags,
+> > +                       struct vm_area_struct *vma);
+> >  int try_to_unmap_one(struct page *, struct vm_area_struct *,
+> >                         unsigned long address, enum ttu_flags flags);
+> >
+> > @@ -259,7 +261,7 @@ static inline int page_referenced(struct page *page, int is_locked,
+> >         return 0;
+> >  }
+> >
+> > -#define try_to_unmap(page, refs) SWAP_FAIL
+> > +#define try_to_unmap(page, refs, vma) SWAP_FAIL
+> >
+> >  static inline int page_mkclean(struct page *page)
+> >  {
+> > diff --git a/mm/ksm.c b/mm/ksm.c
+> > index 7f629e4..1a90d13 100644
+> > --- a/mm/ksm.c
+> > +++ b/mm/ksm.c
+> > @@ -1949,7 +1949,8 @@ out:
+> >         return referenced;
+> >  }
+> >
+> > -int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
+> > +int try_to_unmap_ksm(struct page *page, enum ttu_flags flags,
+> > +                       struct vm_area_struct *target_vma)
+> >  {
+> >         struct stable_node *stable_node;
+> >         struct hlist_node *hlist;
+> > @@ -1963,6 +1964,12 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
+> >         stable_node = page_stable_node(page);
+> >         if (!stable_node)
+> >                 return SWAP_FAIL;
+> > +
+> > +       if (target_vma) {
+> > +               unsigned long address = vma_address(page, target_vma);
+> > +               ret = try_to_unmap_one(page, vma, address, flags);
+> > +               goto out;
+> > +       }
+> >  again:
+> >         hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
+> >                 struct anon_vma *anon_vma = rmap_item->anon_vma;
+> > diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+> > index ceb0c7f..f3928e4 100644
+> > --- a/mm/memory-failure.c
+> > +++ b/mm/memory-failure.c
+> > @@ -955,7 +955,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
+> >         if (hpage != ppage)
+> >                 lock_page(ppage);
+> >
+> > -       ret = try_to_unmap(ppage, ttu);
+> > +       ret = try_to_unmap(ppage, ttu, NULL);
+> >         if (ret != SWAP_SUCCESS)
+> >                 printk(KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n",
+> >                                 pfn, page_mapcount(ppage));
+> > diff --git a/mm/migrate.c b/mm/migrate.c
+> > index 6fa4ebc..aafbc66 100644
+> > --- a/mm/migrate.c
+> > +++ b/mm/migrate.c
+> > @@ -820,7 +820,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
+> >         }
+> >
+> >         /* Establish migration ptes or remove ptes */
+> > -       try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
+> > +       try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS,
+> > +                       NULL);
+> >
+> >  skip_unmap:
+> >         if (!page_mapped(page))
+> > @@ -947,7 +948,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
+> >         if (PageAnon(hpage))
+> >                 anon_vma = page_get_anon_vma(hpage);
+> >
+> > -       try_to_unmap(hpage, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
+> > +       try_to_unmap(hpage, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS,
+> > +                                               NULL);
+> >
+> >         if (!page_mapped(hpage))
+> >                 rc = move_to_new_page(new_hpage, hpage, 1, mode);
+> > diff --git a/mm/rmap.c b/mm/rmap.c
+> > index 6280da8..a880f24 100644
+> > --- a/mm/rmap.c
+> > +++ b/mm/rmap.c
+> > @@ -1435,13 +1435,16 @@ bool is_vma_temporary_stack(struct vm_area_struct *vma)
+> >
+> >  /**
+> >   * try_to_unmap_anon - unmap or unlock anonymous page using the object-based
+> > - * rmap method
+> > + * rmap method if @vma is NULL
+> >   * @page: the page to unmap/unlock
+> >   * @flags: action and flags
+> > + * @target_vma: vma for unmapping a @page
+> >   *
+> >   * Find all the mappings of a page using the mapping pointer and the vma chains
+> >   * contained in the anon_vma struct it points to.
+> >   *
+> > + * If @target_vma isn't NULL, this function unmap a page from the vma
+> > + *
+> >   * This function is only called from try_to_unmap/try_to_munlock for
+> >   * anonymous pages.
+> >   * When called from try_to_munlock(), the mmap_sem of the mm containing the vma
+> > @@ -1449,12 +1452,19 @@ bool is_vma_temporary_stack(struct vm_area_struct *vma)
+> >   * vm_flags for that VMA.  That should be OK, because that vma shouldn't be
+> >   * 'LOCKED.
+> >   */
+> > -static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
+> > +static int try_to_unmap_anon(struct page *page, enum ttu_flags flags,
+> > +                                       struct vm_area_struct *target_vma)
+> >  {
+> > +       int ret = SWAP_AGAIN;
+> > +       unsigned long address;
+> >         struct anon_vma *anon_vma;
+> >         pgoff_t pgoff;
+> >         struct anon_vma_chain *avc;
+> > -       int ret = SWAP_AGAIN;
+> > +
+> > +       if (target_vma) {
+> > +               address = vma_address(page, target_vma);
+> > +               return try_to_unmap_one(page, target_vma, address, flags);
+> > +       }
+> >
+> >         anon_vma = page_lock_anon_vma_read(page);
+> >         if (!anon_vma)
+> > @@ -1463,7 +1473,6 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
+> >         pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+> >         anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
+> >                 struct vm_area_struct *vma = avc->vma;
+> > -               unsigned long address;
+> >
+> >                 /*
+> >                  * During exec, a temporary VMA is setup and later moved.
+> > @@ -1491,6 +1500,7 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
+> >   * try_to_unmap_file - unmap/unlock file page using the object-based rmap method
+> >   * @page: the page to unmap/unlock
+> >   * @flags: action and flags
+> > + * @target_vma: vma for unmapping @page
+> >   *
+> >   * Find all the mappings of a page using the mapping pointer and the vma chains
+> >   * contained in the address_space struct it points to.
+> > @@ -1502,7 +1512,8 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
+> >   * vm_flags for that VMA.  That should be OK, because that vma shouldn't be
+> >   * 'LOCKED.
+> >   */
+> > -static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
+> > +static int try_to_unmap_file(struct page *page, enum ttu_flags flags,
+> > +                               struct vm_area_struct *target_vma)
+> >  {
+> >         struct address_space *mapping = page->mapping;
+> >         pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+> > @@ -1512,16 +1523,27 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)
+> >         unsigned long max_nl_cursor = 0;
+> >         unsigned long max_nl_size = 0;
+> >         unsigned int mapcount;
+> > +       unsigned long address;
+> >
+> >         if (PageHuge(page))
+> >                 pgoff = page->index << compound_order(page);
+> >
+> >         mutex_lock(&mapping->i_mmap_mutex);
+> > -       vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
+> > -               unsigned long address = vma_address(page, vma);
+> > -               ret = try_to_unmap_one(page, vma, address, flags);
+> > -               if (ret != SWAP_AGAIN || !page_mapped(page))
+> > +       if (target_vma) {
+> > +               /* We don't handle non-linear vma on ramfs */
+> > +               if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
+> >                         goto out;
+> > +
+> > +               address = vma_address(page, target_vma);
+> > +               ret = try_to_unmap_one(page, target_vma, address, flags);
+> > +               goto out;
+> > +       } else {
+> > +               vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
+> > +                       address = vma_address(page, vma);
+> > +                       ret = try_to_unmap_one(page, vma, address, flags);
+> > +                       if (ret != SWAP_AGAIN || !page_mapped(page))
+> > +                               goto out;
+> > +               }
+> >         }
+> >
+> >         if (list_empty(&mapping->i_mmap_nonlinear))
+> > @@ -1602,9 +1624,12 @@ out:
+> >   * try_to_unmap - try to remove all page table mappings to a page
+> >   * @page: the page to get unmapped
+> >   * @flags: action and flags
+> > + * @vma : target vma for reclaim
+> >   *
+> >   * Tries to remove all the page table entries which are mapping this
+> >   * page, used in the pageout path.  Caller must hold the page lock.
+> > + * If @vma is not NULL, this function try to remove @page from only @vma
+> > + * without peeking all mapped vma for @page.
+> >   * Return values are:
+> >   *
+> >   * SWAP_SUCCESS        - we succeeded in removing all mappings
+> > @@ -1612,7 +1637,8 @@ out:
+> >   * SWAP_FAIL   - the page is unswappable
+> >   * SWAP_MLOCK  - page is mlocked.
+> >   */
+> > -int try_to_unmap(struct page *page, enum ttu_flags flags)
+> > +int try_to_unmap(struct page *page, enum ttu_flags flags,
+> > +                               struct vm_area_struct *vma)
+> >  {
+> >         int ret;
+> >
+> > @@ -1620,11 +1646,11 @@ int try_to_unmap(struct page *page, enum ttu_flags flags)
+> >         VM_BUG_ON(!PageHuge(page) && PageTransHuge(page));
+> >
+> >         if (unlikely(PageKsm(page)))
+> > -               ret = try_to_unmap_ksm(page, flags);
+> > +               ret = try_to_unmap_ksm(page, flags, vma);
+> >         else if (PageAnon(page))
+> > -               ret = try_to_unmap_anon(page, flags);
+> > +               ret = try_to_unmap_anon(page, flags, vma);
+> >         else
+> > -               ret = try_to_unmap_file(page, flags);
+> > +               ret = try_to_unmap_file(page, flags, vma);
+> >         if (ret != SWAP_MLOCK && !page_mapped(page))
+> >                 ret = SWAP_SUCCESS;
+> >         return ret;
+> > @@ -1650,11 +1676,11 @@ int try_to_munlock(struct page *page)
+> >         VM_BUG_ON(!PageLocked(page) || PageLRU(page));
+> >
+> >         if (unlikely(PageKsm(page)))
+> > -               return try_to_unmap_ksm(page, TTU_MUNLOCK);
+> > +               return try_to_unmap_ksm(page, TTU_MUNLOCK, NULL);
+> >         else if (PageAnon(page))
+> > -               return try_to_unmap_anon(page, TTU_MUNLOCK);
+> > +               return try_to_unmap_anon(page, TTU_MUNLOCK, NULL);
+> >         else
+> > -               return try_to_unmap_file(page, TTU_MUNLOCK);
+> > +               return try_to_unmap_file(page, TTU_MUNLOCK, NULL);
+> >  }
+> >
+> >  void __put_anon_vma(struct anon_vma *anon_vma)
+> > diff --git a/mm/vmscan.c b/mm/vmscan.c
+> > index 367d0f4..df9c4d3 100644
+> > --- a/mm/vmscan.c
+> > +++ b/mm/vmscan.c
+> > @@ -92,6 +92,13 @@ struct scan_control {
+> >          * are scanned.
+> >          */
+> >         nodemask_t      *nodemask;
+> > +
+> > +       /*
+> > +        * Reclaim pages from a vma. If the page is shared by other tasks
+> > +        * it is zapped from a vma without reclaim so it ends up remaining
+> > +        * on memory until last task zap it.
+> > +        */
+> > +       struct vm_area_struct *target_vma;
+> >  };
+> >
+> >  #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
+> > @@ -793,7 +800,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
+> >                  * processes. Try to unmap it here.
+> >                  */
+> >                 if (page_mapped(page) && mapping) {
+> > -                       switch (try_to_unmap(page, ttu_flags)) {
+> > +                       switch (try_to_unmap(page,
+> > +                                       ttu_flags, sc->target_vma)) {
+> >                         case SWAP_FAIL:
+> >                                 goto activate_locked;
+> >                         case SWAP_AGAIN:
+> > @@ -1000,13 +1008,15 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
+> >  }
+> >
+> >  #ifdef CONFIG_PROCESS_RECLAIM
+> > -unsigned long reclaim_pages_from_list(struct list_head *page_list)
+> > +unsigned long reclaim_pages_from_list(struct list_head *page_list,
+> > +                                       struct vm_area_struct *vma)
+> >  {
+> >         struct scan_control sc = {
+> >                 .gfp_mask = GFP_KERNEL,
+> >                 .priority = DEF_PRIORITY,
+> >                 .may_unmap = 1,
+> >                 .may_swap = 1,
+> > +               .target_vma = vma,
+> >         };
+> >
+> >         unsigned long nr_reclaimed;
+> > --
+> > 1.8.2
+> >
+> > --
+> > To unsubscribe, send a message with 'unsubscribe linux-mm' in
+> > the body to majordomo@kvack.org.  For more info on Linux MM,
+> > see: http://www.linux-mm.org/ .
+> > Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
+> 
+> --
+> To unsubscribe, send a message with 'unsubscribe linux-mm' in
+> the body to majordomo@kvack.org.  For more info on Linux MM,
+> see: http://www.linux-mm.org/ .
+> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
+
+-- 
+Kind regards,
+Minchan Kim
diff --git a/a/content_digest b/N1/content_digest
index fc03651..778b490 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -37,8 +37,8 @@
  "> including MMOTM of 26 March, and encounter this error:\n"
  "> \n"
  ">   CC      mm/ksm.o\n"
- "> mm/ksm.c: In function a??try_to_unmap_ksma??:\n"
- "> mm/ksm.c:1970:32: error: a??vmaa?? undeclared (first use in this function)\n"
+ "> mm/ksm.c: In function \342\200\230try_to_unmap_ksm\342\200\231:\n"
+ "> mm/ksm.c:1970:32: error: \342\200\230vma\342\200\231 undeclared (first use in this function)\n"
  "> mm/ksm.c:1970:32: note: each undeclared identifier is reported only\n"
  "> once for each function it appears in\n"
  "> make[1]: *** [mm/ksm.o] Error 1\n"
@@ -46,6 +46,418 @@
  "\n"
  "I did it based on mmotm-2013-03-22-15-21 and you found build problem.\n"
  "Could you apply below patch? I will fix up below in next spin.\n"
- Thanks for the testing!
+ "Thanks for the testing!\n"
+ "\n"
+ ">From 0934270618ccd4883d6bb05653c664a385fb9441 Mon Sep 17 00:00:00 2001\n"
+ "From: Minchan Kim <minchan@kernel.org>\n"
+ "Date: Wed, 3 Apr 2013 09:19:49 +0900\n"
+ "Subject: [PATCH] fix: compile error for CONFIG_KSM\n"
+ "\n"
+ "Signed-off-by: Minchan Kim <minchan@kernel.org>\n"
+ "---\n"
+ " include/linux/rmap.h | 2 ++\n"
+ " mm/ksm.c             | 2 +-\n"
+ " 2 files changed, 3 insertions(+), 1 deletion(-)\n"
+ "\n"
+ "diff --git a/include/linux/rmap.h b/include/linux/rmap.h\n"
+ "index 6c7d030..7bcf090 100644\n"
+ "--- a/include/linux/rmap.h\n"
+ "+++ b/include/linux/rmap.h\n"
+ "@@ -14,6 +14,8 @@ extern int isolate_lru_page(struct page *page);\n"
+ " extern void putback_lru_page(struct page *page);\n"
+ " extern unsigned long reclaim_pages_from_list(struct list_head *page_list,\n"
+ " \t\t\t\t\t     struct vm_area_struct *vma);\n"
+ "+extern unsigned long vma_address(struct page *page,\n"
+ "+\t\t\t\tstruct vm_area_struct *vma);\n"
+ " \n"
+ " /*\n"
+ "  * The anon_vma heads a list of private \"related\" vmas, to scan if\n"
+ "diff --git a/mm/ksm.c b/mm/ksm.c\n"
+ "index 1a90d13..44de936 100644\n"
+ "--- a/mm/ksm.c\n"
+ "+++ b/mm/ksm.c\n"
+ "@@ -1967,7 +1967,7 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags,\n"
+ " \n"
+ " \tif (target_vma) {\n"
+ " \t\tunsigned long address = vma_address(page, target_vma);\n"
+ "-\t\tret = try_to_unmap_one(page, vma, address, flags);\n"
+ "+\t\tret = try_to_unmap_one(page, target_vma, address, flags);\n"
+ " \t\tgoto out;\n"
+ " \t}\n"
+ " again:\n"
+ "-- \n"
+ "1.8.2\n"
+ "\n"
+ "> \n"
+ "> Cheers,\n"
+ "> \n"
+ "> Michael\n"
+ "> \n"
+ "> \n"
+ "> > Signed-off-by: Sangseok Lee <sangseok.lee@lge.com>\n"
+ "> > Signed-off-by: Minchan Kim <minchan@kernel.org>\n"
+ "> > ---\n"
+ "> >  fs/proc/task_mmu.c   |  2 +-\n"
+ "> >  include/linux/ksm.h  |  6 ++++--\n"
+ "> >  include/linux/rmap.h |  8 +++++---\n"
+ "> >  mm/ksm.c             |  9 +++++++-\n"
+ "> >  mm/memory-failure.c  |  2 +-\n"
+ "> >  mm/migrate.c         |  6 ++++--\n"
+ "> >  mm/rmap.c            | 58 +++++++++++++++++++++++++++++++++++++---------------\n"
+ "> >  mm/vmscan.c          | 14 +++++++++++--\n"
+ "> >  8 files changed, 77 insertions(+), 28 deletions(-)\n"
+ "> >\n"
+ "> > diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c\n"
+ "> > index c3713a4..7f6aaf5 100644\n"
+ "> > --- a/fs/proc/task_mmu.c\n"
+ "> > +++ b/fs/proc/task_mmu.c\n"
+ "> > @@ -1154,7 +1154,7 @@ cont:\n"
+ "> >                         break;\n"
+ "> >         }\n"
+ "> >         pte_unmap_unlock(pte - 1, ptl);\n"
+ "> > -       reclaim_pages_from_list(&page_list);\n"
+ "> > +       reclaim_pages_from_list(&page_list, vma);\n"
+ "> >         if (addr != end)\n"
+ "> >                 goto cont;\n"
+ "> >\n"
+ "> > diff --git a/include/linux/ksm.h b/include/linux/ksm.h\n"
+ "> > index 45c9b6a..d8e556b 100644\n"
+ "> > --- a/include/linux/ksm.h\n"
+ "> > +++ b/include/linux/ksm.h\n"
+ "> > @@ -75,7 +75,8 @@ struct page *ksm_might_need_to_copy(struct page *page,\n"
+ "> >\n"
+ "> >  int page_referenced_ksm(struct page *page,\n"
+ "> >                         struct mem_cgroup *memcg, unsigned long *vm_flags);\n"
+ "> > -int try_to_unmap_ksm(struct page *page, enum ttu_flags flags);\n"
+ "> > +int try_to_unmap_ksm(struct page *page,\n"
+ "> > +                       enum ttu_flags flags, struct vm_area_struct *vma);\n"
+ "> >  int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,\n"
+ "> >                   struct vm_area_struct *, unsigned long, void *), void *arg);\n"
+ "> >  void ksm_migrate_page(struct page *newpage, struct page *oldpage);\n"
+ "> > @@ -115,7 +116,8 @@ static inline int page_referenced_ksm(struct page *page,\n"
+ "> >         return 0;\n"
+ "> >  }\n"
+ "> >\n"
+ "> > -static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)\n"
+ "> > +static inline int try_to_unmap_ksm(struct page *page,\n"
+ "> > +                       enum ttu_flags flags, struct vm_area_struct *target_vma)\n"
+ "> >  {\n"
+ "> >         return 0;\n"
+ "> >  }\n"
+ "> > diff --git a/include/linux/rmap.h b/include/linux/rmap.h\n"
+ "> > index a24e34e..6c7d030 100644\n"
+ "> > --- a/include/linux/rmap.h\n"
+ "> > +++ b/include/linux/rmap.h\n"
+ "> > @@ -12,7 +12,8 @@\n"
+ "> >\n"
+ "> >  extern int isolate_lru_page(struct page *page);\n"
+ "> >  extern void putback_lru_page(struct page *page);\n"
+ "> > -extern unsigned long reclaim_pages_from_list(struct list_head *page_list);\n"
+ "> > +extern unsigned long reclaim_pages_from_list(struct list_head *page_list,\n"
+ "> > +                                            struct vm_area_struct *vma);\n"
+ "> >\n"
+ "> >  /*\n"
+ "> >   * The anon_vma heads a list of private \"related\" vmas, to scan if\n"
+ "> > @@ -192,7 +193,8 @@ int page_referenced_one(struct page *, struct vm_area_struct *,\n"
+ "> >\n"
+ "> >  #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)\n"
+ "> >\n"
+ "> > -int try_to_unmap(struct page *, enum ttu_flags flags);\n"
+ "> > +int try_to_unmap(struct page *, enum ttu_flags flags,\n"
+ "> > +                       struct vm_area_struct *vma);\n"
+ "> >  int try_to_unmap_one(struct page *, struct vm_area_struct *,\n"
+ "> >                         unsigned long address, enum ttu_flags flags);\n"
+ "> >\n"
+ "> > @@ -259,7 +261,7 @@ static inline int page_referenced(struct page *page, int is_locked,\n"
+ "> >         return 0;\n"
+ "> >  }\n"
+ "> >\n"
+ "> > -#define try_to_unmap(page, refs) SWAP_FAIL\n"
+ "> > +#define try_to_unmap(page, refs, vma) SWAP_FAIL\n"
+ "> >\n"
+ "> >  static inline int page_mkclean(struct page *page)\n"
+ "> >  {\n"
+ "> > diff --git a/mm/ksm.c b/mm/ksm.c\n"
+ "> > index 7f629e4..1a90d13 100644\n"
+ "> > --- a/mm/ksm.c\n"
+ "> > +++ b/mm/ksm.c\n"
+ "> > @@ -1949,7 +1949,8 @@ out:\n"
+ "> >         return referenced;\n"
+ "> >  }\n"
+ "> >\n"
+ "> > -int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)\n"
+ "> > +int try_to_unmap_ksm(struct page *page, enum ttu_flags flags,\n"
+ "> > +                       struct vm_area_struct *target_vma)\n"
+ "> >  {\n"
+ "> >         struct stable_node *stable_node;\n"
+ "> >         struct hlist_node *hlist;\n"
+ "> > @@ -1963,6 +1964,12 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)\n"
+ "> >         stable_node = page_stable_node(page);\n"
+ "> >         if (!stable_node)\n"
+ "> >                 return SWAP_FAIL;\n"
+ "> > +\n"
+ "> > +       if (target_vma) {\n"
+ "> > +               unsigned long address = vma_address(page, target_vma);\n"
+ "> > +               ret = try_to_unmap_one(page, vma, address, flags);\n"
+ "> > +               goto out;\n"
+ "> > +       }\n"
+ "> >  again:\n"
+ "> >         hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {\n"
+ "> >                 struct anon_vma *anon_vma = rmap_item->anon_vma;\n"
+ "> > diff --git a/mm/memory-failure.c b/mm/memory-failure.c\n"
+ "> > index ceb0c7f..f3928e4 100644\n"
+ "> > --- a/mm/memory-failure.c\n"
+ "> > +++ b/mm/memory-failure.c\n"
+ "> > @@ -955,7 +955,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,\n"
+ "> >         if (hpage != ppage)\n"
+ "> >                 lock_page(ppage);\n"
+ "> >\n"
+ "> > -       ret = try_to_unmap(ppage, ttu);\n"
+ "> > +       ret = try_to_unmap(ppage, ttu, NULL);\n"
+ "> >         if (ret != SWAP_SUCCESS)\n"
+ "> >                 printk(KERN_ERR \"MCE %#lx: failed to unmap page (mapcount=%d)\\n\",\n"
+ "> >                                 pfn, page_mapcount(ppage));\n"
+ "> > diff --git a/mm/migrate.c b/mm/migrate.c\n"
+ "> > index 6fa4ebc..aafbc66 100644\n"
+ "> > --- a/mm/migrate.c\n"
+ "> > +++ b/mm/migrate.c\n"
+ "> > @@ -820,7 +820,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage,\n"
+ "> >         }\n"
+ "> >\n"
+ "> >         /* Establish migration ptes or remove ptes */\n"
+ "> > -       try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);\n"
+ "> > +       try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS,\n"
+ "> > +                       NULL);\n"
+ "> >\n"
+ "> >  skip_unmap:\n"
+ "> >         if (!page_mapped(page))\n"
+ "> > @@ -947,7 +948,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,\n"
+ "> >         if (PageAnon(hpage))\n"
+ "> >                 anon_vma = page_get_anon_vma(hpage);\n"
+ "> >\n"
+ "> > -       try_to_unmap(hpage, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);\n"
+ "> > +       try_to_unmap(hpage, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS,\n"
+ "> > +                                               NULL);\n"
+ "> >\n"
+ "> >         if (!page_mapped(hpage))\n"
+ "> >                 rc = move_to_new_page(new_hpage, hpage, 1, mode);\n"
+ "> > diff --git a/mm/rmap.c b/mm/rmap.c\n"
+ "> > index 6280da8..a880f24 100644\n"
+ "> > --- a/mm/rmap.c\n"
+ "> > +++ b/mm/rmap.c\n"
+ "> > @@ -1435,13 +1435,16 @@ bool is_vma_temporary_stack(struct vm_area_struct *vma)\n"
+ "> >\n"
+ "> >  /**\n"
+ "> >   * try_to_unmap_anon - unmap or unlock anonymous page using the object-based\n"
+ "> > - * rmap method\n"
+ "> > + * rmap method if @vma is NULL\n"
+ "> >   * @page: the page to unmap/unlock\n"
+ "> >   * @flags: action and flags\n"
+ "> > + * @target_vma: vma for unmapping a @page\n"
+ "> >   *\n"
+ "> >   * Find all the mappings of a page using the mapping pointer and the vma chains\n"
+ "> >   * contained in the anon_vma struct it points to.\n"
+ "> >   *\n"
+ "> > + * If @target_vma isn't NULL, this function unmap a page from the vma\n"
+ "> > + *\n"
+ "> >   * This function is only called from try_to_unmap/try_to_munlock for\n"
+ "> >   * anonymous pages.\n"
+ "> >   * When called from try_to_munlock(), the mmap_sem of the mm containing the vma\n"
+ "> > @@ -1449,12 +1452,19 @@ bool is_vma_temporary_stack(struct vm_area_struct *vma)\n"
+ "> >   * vm_flags for that VMA.  That should be OK, because that vma shouldn't be\n"
+ "> >   * 'LOCKED.\n"
+ "> >   */\n"
+ "> > -static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)\n"
+ "> > +static int try_to_unmap_anon(struct page *page, enum ttu_flags flags,\n"
+ "> > +                                       struct vm_area_struct *target_vma)\n"
+ "> >  {\n"
+ "> > +       int ret = SWAP_AGAIN;\n"
+ "> > +       unsigned long address;\n"
+ "> >         struct anon_vma *anon_vma;\n"
+ "> >         pgoff_t pgoff;\n"
+ "> >         struct anon_vma_chain *avc;\n"
+ "> > -       int ret = SWAP_AGAIN;\n"
+ "> > +\n"
+ "> > +       if (target_vma) {\n"
+ "> > +               address = vma_address(page, target_vma);\n"
+ "> > +               return try_to_unmap_one(page, target_vma, address, flags);\n"
+ "> > +       }\n"
+ "> >\n"
+ "> >         anon_vma = page_lock_anon_vma_read(page);\n"
+ "> >         if (!anon_vma)\n"
+ "> > @@ -1463,7 +1473,6 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)\n"
+ "> >         pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);\n"
+ "> >         anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {\n"
+ "> >                 struct vm_area_struct *vma = avc->vma;\n"
+ "> > -               unsigned long address;\n"
+ "> >\n"
+ "> >                 /*\n"
+ "> >                  * During exec, a temporary VMA is setup and later moved.\n"
+ "> > @@ -1491,6 +1500,7 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)\n"
+ "> >   * try_to_unmap_file - unmap/unlock file page using the object-based rmap method\n"
+ "> >   * @page: the page to unmap/unlock\n"
+ "> >   * @flags: action and flags\n"
+ "> > + * @target_vma: vma for unmapping @page\n"
+ "> >   *\n"
+ "> >   * Find all the mappings of a page using the mapping pointer and the vma chains\n"
+ "> >   * contained in the address_space struct it points to.\n"
+ "> > @@ -1502,7 +1512,8 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)\n"
+ "> >   * vm_flags for that VMA.  That should be OK, because that vma shouldn't be\n"
+ "> >   * 'LOCKED.\n"
+ "> >   */\n"
+ "> > -static int try_to_unmap_file(struct page *page, enum ttu_flags flags)\n"
+ "> > +static int try_to_unmap_file(struct page *page, enum ttu_flags flags,\n"
+ "> > +                               struct vm_area_struct *target_vma)\n"
+ "> >  {\n"
+ "> >         struct address_space *mapping = page->mapping;\n"
+ "> >         pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);\n"
+ "> > @@ -1512,16 +1523,27 @@ static int try_to_unmap_file(struct page *page, enum ttu_flags flags)\n"
+ "> >         unsigned long max_nl_cursor = 0;\n"
+ "> >         unsigned long max_nl_size = 0;\n"
+ "> >         unsigned int mapcount;\n"
+ "> > +       unsigned long address;\n"
+ "> >\n"
+ "> >         if (PageHuge(page))\n"
+ "> >                 pgoff = page->index << compound_order(page);\n"
+ "> >\n"
+ "> >         mutex_lock(&mapping->i_mmap_mutex);\n"
+ "> > -       vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {\n"
+ "> > -               unsigned long address = vma_address(page, vma);\n"
+ "> > -               ret = try_to_unmap_one(page, vma, address, flags);\n"
+ "> > -               if (ret != SWAP_AGAIN || !page_mapped(page))\n"
+ "> > +       if (target_vma) {\n"
+ "> > +               /* We don't handle non-linear vma on ramfs */\n"
+ "> > +               if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))\n"
+ "> >                         goto out;\n"
+ "> > +\n"
+ "> > +               address = vma_address(page, target_vma);\n"
+ "> > +               ret = try_to_unmap_one(page, target_vma, address, flags);\n"
+ "> > +               goto out;\n"
+ "> > +       } else {\n"
+ "> > +               vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {\n"
+ "> > +                       address = vma_address(page, vma);\n"
+ "> > +                       ret = try_to_unmap_one(page, vma, address, flags);\n"
+ "> > +                       if (ret != SWAP_AGAIN || !page_mapped(page))\n"
+ "> > +                               goto out;\n"
+ "> > +               }\n"
+ "> >         }\n"
+ "> >\n"
+ "> >         if (list_empty(&mapping->i_mmap_nonlinear))\n"
+ "> > @@ -1602,9 +1624,12 @@ out:\n"
+ "> >   * try_to_unmap - try to remove all page table mappings to a page\n"
+ "> >   * @page: the page to get unmapped\n"
+ "> >   * @flags: action and flags\n"
+ "> > + * @vma : target vma for reclaim\n"
+ "> >   *\n"
+ "> >   * Tries to remove all the page table entries which are mapping this\n"
+ "> >   * page, used in the pageout path.  Caller must hold the page lock.\n"
+ "> > + * If @vma is not NULL, this function try to remove @page from only @vma\n"
+ "> > + * without peeking all mapped vma for @page.\n"
+ "> >   * Return values are:\n"
+ "> >   *\n"
+ "> >   * SWAP_SUCCESS        - we succeeded in removing all mappings\n"
+ "> > @@ -1612,7 +1637,8 @@ out:\n"
+ "> >   * SWAP_FAIL   - the page is unswappable\n"
+ "> >   * SWAP_MLOCK  - page is mlocked.\n"
+ "> >   */\n"
+ "> > -int try_to_unmap(struct page *page, enum ttu_flags flags)\n"
+ "> > +int try_to_unmap(struct page *page, enum ttu_flags flags,\n"
+ "> > +                               struct vm_area_struct *vma)\n"
+ "> >  {\n"
+ "> >         int ret;\n"
+ "> >\n"
+ "> > @@ -1620,11 +1646,11 @@ int try_to_unmap(struct page *page, enum ttu_flags flags)\n"
+ "> >         VM_BUG_ON(!PageHuge(page) && PageTransHuge(page));\n"
+ "> >\n"
+ "> >         if (unlikely(PageKsm(page)))\n"
+ "> > -               ret = try_to_unmap_ksm(page, flags);\n"
+ "> > +               ret = try_to_unmap_ksm(page, flags, vma);\n"
+ "> >         else if (PageAnon(page))\n"
+ "> > -               ret = try_to_unmap_anon(page, flags);\n"
+ "> > +               ret = try_to_unmap_anon(page, flags, vma);\n"
+ "> >         else\n"
+ "> > -               ret = try_to_unmap_file(page, flags);\n"
+ "> > +               ret = try_to_unmap_file(page, flags, vma);\n"
+ "> >         if (ret != SWAP_MLOCK && !page_mapped(page))\n"
+ "> >                 ret = SWAP_SUCCESS;\n"
+ "> >         return ret;\n"
+ "> > @@ -1650,11 +1676,11 @@ int try_to_munlock(struct page *page)\n"
+ "> >         VM_BUG_ON(!PageLocked(page) || PageLRU(page));\n"
+ "> >\n"
+ "> >         if (unlikely(PageKsm(page)))\n"
+ "> > -               return try_to_unmap_ksm(page, TTU_MUNLOCK);\n"
+ "> > +               return try_to_unmap_ksm(page, TTU_MUNLOCK, NULL);\n"
+ "> >         else if (PageAnon(page))\n"
+ "> > -               return try_to_unmap_anon(page, TTU_MUNLOCK);\n"
+ "> > +               return try_to_unmap_anon(page, TTU_MUNLOCK, NULL);\n"
+ "> >         else\n"
+ "> > -               return try_to_unmap_file(page, TTU_MUNLOCK);\n"
+ "> > +               return try_to_unmap_file(page, TTU_MUNLOCK, NULL);\n"
+ "> >  }\n"
+ "> >\n"
+ "> >  void __put_anon_vma(struct anon_vma *anon_vma)\n"
+ "> > diff --git a/mm/vmscan.c b/mm/vmscan.c\n"
+ "> > index 367d0f4..df9c4d3 100644\n"
+ "> > --- a/mm/vmscan.c\n"
+ "> > +++ b/mm/vmscan.c\n"
+ "> > @@ -92,6 +92,13 @@ struct scan_control {\n"
+ "> >          * are scanned.\n"
+ "> >          */\n"
+ "> >         nodemask_t      *nodemask;\n"
+ "> > +\n"
+ "> > +       /*\n"
+ "> > +        * Reclaim pages from a vma. If the page is shared by other tasks\n"
+ "> > +        * it is zapped from a vma without reclaim so it ends up remaining\n"
+ "> > +        * on memory until last task zap it.\n"
+ "> > +        */\n"
+ "> > +       struct vm_area_struct *target_vma;\n"
+ "> >  };\n"
+ "> >\n"
+ "> >  #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))\n"
+ "> > @@ -793,7 +800,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,\n"
+ "> >                  * processes. Try to unmap it here.\n"
+ "> >                  */\n"
+ "> >                 if (page_mapped(page) && mapping) {\n"
+ "> > -                       switch (try_to_unmap(page, ttu_flags)) {\n"
+ "> > +                       switch (try_to_unmap(page,\n"
+ "> > +                                       ttu_flags, sc->target_vma)) {\n"
+ "> >                         case SWAP_FAIL:\n"
+ "> >                                 goto activate_locked;\n"
+ "> >                         case SWAP_AGAIN:\n"
+ "> > @@ -1000,13 +1008,15 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,\n"
+ "> >  }\n"
+ "> >\n"
+ "> >  #ifdef CONFIG_PROCESS_RECLAIM\n"
+ "> > -unsigned long reclaim_pages_from_list(struct list_head *page_list)\n"
+ "> > +unsigned long reclaim_pages_from_list(struct list_head *page_list,\n"
+ "> > +                                       struct vm_area_struct *vma)\n"
+ "> >  {\n"
+ "> >         struct scan_control sc = {\n"
+ "> >                 .gfp_mask = GFP_KERNEL,\n"
+ "> >                 .priority = DEF_PRIORITY,\n"
+ "> >                 .may_unmap = 1,\n"
+ "> >                 .may_swap = 1,\n"
+ "> > +               .target_vma = vma,\n"
+ "> >         };\n"
+ "> >\n"
+ "> >         unsigned long nr_reclaimed;\n"
+ "> > --\n"
+ "> > 1.8.2\n"
+ "> >\n"
+ "> > --\n"
+ "> > To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
+ "> > the body to majordomo@kvack.org.  For more info on Linux MM,\n"
+ "> > see: http://www.linux-mm.org/ .\n"
+ "> > Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>\n"
+ "> \n"
+ "> --\n"
+ "> To unsubscribe, send a message with 'unsubscribe linux-mm' in\n"
+ "> the body to majordomo@kvack.org.  For more info on Linux MM,\n"
+ "> see: http://www.linux-mm.org/ .\n"
+ "> Don't email: <a href=mailto:\"dont@kvack.org\"> email@kvack.org </a>\n"
+ "\n"
+ "-- \n"
+ "Kind regards,\n"
+ Minchan Kim
 
-b92691760753d3219307a1b731c234ca3e6366ba0179d028c4d213425db59665
+d08c5e38561ce07e20731a6ac5def013c4446e8de86b8c47295d9ba695341e29

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.