lkml.org 
[lkml]   [2011]   [May]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Kernel falls apart under light memory pressure (i.e. linking vmlinux)
On Fri, 20 May 2011 13:20:15 +0900
Minchan Kim <minchan.kim@gmail.com> wrote:

> So I want to resolve your problem asap.
> We don't have see report about that. Could you do git-bisect?
> FYI, Recently, big change of mm is compaction,transparent huge pages.
> Kame, could you point out thing related to memcg if you have a mind?
>

I don't doubt memcg at this stage because it never modify page->flags.
Consdering the case, PageActive() is set against off-LRU pages after
clear_active_flags() clears it.

Hmm, I think I don't understand the lock system fully but...how do you
think this ?

==

At splitting a hugepage, the routine marks all pmd as "splitting".

But assume a racy case where 2 threads run into spit at the
same time, one thread wins compound_lock() and do split, another
thread should not touch splitted pages.

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Index: mmotm-May11/mm/huge_memory.c
===================================================================
--- mmotm-May11.orig/mm/huge_memory.c
+++ mmotm-May11/mm/huge_memory.c
@@ -1150,7 +1150,7 @@ static int __split_huge_page_splitting(s
return ret;
}

-static void __split_huge_page_refcount(struct page *page)
+static bool __split_huge_page_refcount(struct page *page)
{
int i;
unsigned long head_index = page->index;
@@ -1161,6 +1161,11 @@ static void __split_huge_page_refcount(s
spin_lock_irq(&zone->lru_lock);
compound_lock(page);

+ if (!PageCompound(page)) {
+ compound_unlock(page);
+ spin_unlock_irq(&zone->lru_lock);
+ return false;
+ }
for (i = 1; i < HPAGE_PMD_NR; i++) {
struct page *page_tail = page + i;

@@ -1258,6 +1263,7 @@ static void __split_huge_page_refcount(s
* to be pinned by the caller.
*/
BUG_ON(page_count(page) <= 0);
+ return true;
}

static int __split_huge_page_map(struct page *page,
@@ -1367,7 +1373,8 @@ static void __split_huge_page(struct pag
mapcount, page_mapcount(page));
BUG_ON(mapcount != page_mapcount(page));

- __split_huge_page_refcount(page);
+ if (!__split_huge_page_refcount(page))
+ return;

mapcount2 = 0;
list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {


\
 
 \ /
  Last update: 2011-05-20 07:17    [W:1.387 / U:0.112 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site