All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Arcangeli <aarcange@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Hugh Dickins <hughd@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Rientjes <rientjes@google.com>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: Re: [PATCH] mm: PageBuddy and mapcount underflows robustness
Date: Fri, 18 Mar 2011 00:16:35 +0100	[thread overview]
Message-ID: <20110317231635.GC10696@random.random> (raw)
In-Reply-To: <AANLkTikWh5tFUZuALYRP3Dx2Zcs33u0UVdjf4d_7KhPJ@mail.gmail.com>

On Mon, Mar 14, 2011 at 10:30:11AM -0700, Linus Torvalds wrote:
> On Mon, Mar 14, 2011 at 9:59 AM, Andrea Arcangeli <aarcange@redhat.com> wrote:
> >
> > +#define PAGE_BUDDY_MAPCOUNT_VALUE (-1024*1024)
> 
> I realize that this is a nitpick, but from a code generation
> standpoint, large random constants like these are just nasty.
> 
> I would suggest aiming for constants that are easy to generate and/or
> fit better in the code stream. In many encoding schemes (eg x86), -128
> is much easier to generate, since it fits in a signed byte and allows
> small instructions etc. And in most RISC encodings, 8- or 16-bit
> constants can be encoded much more easily than something like your
> current one, and bigger ones often end up resulting in a load from
> memory or at least several immediate-building instructions.

-128 sure is ok with me. It's extremely unlikely to be off by 127
times, if we're off by more than 127 times we're still going to detect
the error.

> Also, this is just disgusting. It adds no safety here to have that
> VM_BUG_ON(), so it's just unnecessary code generation to do this.
> Also, we don't even WANT to do that stupid "__ClearPageBuddy()" in the
> first place! What those two code-sites actually want are just a simple
> 
>     reset_page_mapcount(page);
> 
> which does the right thing in _general_, and not just for the buddy
> case - we want to reset the mapcount for other reasons than just
> pagebuddy (ie the underflow/overflow case).

Agreed.

> And it avoids the VM_BUG_ON() too, making the crazy conditionals be not needed.

Well using reset_page_mapcount in the two error sites, didn't require
me to remove the VM_BUG_ON from __ClearPageBuddy so I left it
there...

===
Subject: mm: PageBuddy and mapcount robustness

From: Andrea Arcangeli <aarcange@redhat.com>

Change the _mapcount value indicating PageBuddy from -2 to -128 for
more robusteness against page_mapcount() undeflows.

Use reset_page_mapcount instead of __ClearPageBuddy in bad_page to
ignore the previous retval of PageBuddy().

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Reported-by: Hugh Dickins <hughd@google.com>
---
 include/linux/mm.h |   11 +++++++++--
 mm/page_alloc.c    |    4 ++--
 2 files changed, 11 insertions(+), 4 deletions(-)

--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -402,16 +402,23 @@ static inline void init_page_count(struc
 /*
  * PageBuddy() indicate that the page is free and in the buddy system
  * (see mm/page_alloc.c).
+ *
+ * PAGE_BUDDY_MAPCOUNT_VALUE must be <= -2 but better not too close to
+ * -2 so that an underflow of the page_mapcount() won't be mistaken
+ * for a genuine PAGE_BUDDY_MAPCOUNT_VALUE. -128 can be created very
+ * efficiently by most CPU architectures.
  */
+#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+
 static inline int PageBuddy(struct page *page)
 {
-	return atomic_read(&page->_mapcount) == -2;
+	return atomic_read(&page->_mapcount) == PAGE_BUDDY_MAPCOUNT_VALUE;
 }
 
 static inline void __SetPageBuddy(struct page *page)
 {
 	VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
-	atomic_set(&page->_mapcount, -2);
+	atomic_set(&page->_mapcount, PAGE_BUDDY_MAPCOUNT_VALUE);
 }
 
 static inline void __ClearPageBuddy(struct page *page)
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -286,7 +286,7 @@ static void bad_page(struct page *page)
 
 	/* Don't complain about poisoned pages */
 	if (PageHWPoison(page)) {
-		__ClearPageBuddy(page);
+		reset_page_mapcount(page); /* remove PageBuddy */
 		return;
 	}
 
@@ -317,7 +317,7 @@ static void bad_page(struct page *page)
 	dump_stack();
 out:
 	/* Leave bad fields for debug, except PageBuddy could make trouble */
-	__ClearPageBuddy(page);
+	reset_page_mapcount(page); /* remove PageBuddy */
 	add_taint(TAINT_BAD_PAGE);
 }
 

WARNING: multiple messages have this Message-ID (diff)
From: Andrea Arcangeli <aarcange@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Hugh Dickins <hughd@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Rientjes <rientjes@google.com>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: Re: [PATCH] mm: PageBuddy and mapcount underflows robustness
Date: Fri, 18 Mar 2011 00:16:35 +0100	[thread overview]
Message-ID: <20110317231635.GC10696@random.random> (raw)
In-Reply-To: <AANLkTikWh5tFUZuALYRP3Dx2Zcs33u0UVdjf4d_7KhPJ@mail.gmail.com>

On Mon, Mar 14, 2011 at 10:30:11AM -0700, Linus Torvalds wrote:
> On Mon, Mar 14, 2011 at 9:59 AM, Andrea Arcangeli <aarcange@redhat.com> wrote:
> >
> > +#define PAGE_BUDDY_MAPCOUNT_VALUE (-1024*1024)
> 
> I realize that this is a nitpick, but from a code generation
> standpoint, large random constants like these are just nasty.
> 
> I would suggest aiming for constants that are easy to generate and/or
> fit better in the code stream. In many encoding schemes (eg x86), -128
> is much easier to generate, since it fits in a signed byte and allows
> small instructions etc. And in most RISC encodings, 8- or 16-bit
> constants can be encoded much more easily than something like your
> current one, and bigger ones often end up resulting in a load from
> memory or at least several immediate-building instructions.

-128 sure is ok with me. It's extremely unlikely to be off by 127
times, if we're off by more than 127 times we're still going to detect
the error.

> Also, this is just disgusting. It adds no safety here to have that
> VM_BUG_ON(), so it's just unnecessary code generation to do this.
> Also, we don't even WANT to do that stupid "__ClearPageBuddy()" in the
> first place! What those two code-sites actually want are just a simple
> 
>     reset_page_mapcount(page);
> 
> which does the right thing in _general_, and not just for the buddy
> case - we want to reset the mapcount for other reasons than just
> pagebuddy (ie the underflow/overflow case).

Agreed.

> And it avoids the VM_BUG_ON() too, making the crazy conditionals be not needed.

Well using reset_page_mapcount in the two error sites, didn't require
me to remove the VM_BUG_ON from __ClearPageBuddy so I left it
there...

===
Subject: mm: PageBuddy and mapcount robustness

From: Andrea Arcangeli <aarcange@redhat.com>

Change the _mapcount value indicating PageBuddy from -2 to -128 for
more robusteness against page_mapcount() undeflows.

Use reset_page_mapcount instead of __ClearPageBuddy in bad_page to
ignore the previous retval of PageBuddy().

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Reported-by: Hugh Dickins <hughd@google.com>
---
 include/linux/mm.h |   11 +++++++++--
 mm/page_alloc.c    |    4 ++--
 2 files changed, 11 insertions(+), 4 deletions(-)

--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -402,16 +402,23 @@ static inline void init_page_count(struc
 /*
  * PageBuddy() indicate that the page is free and in the buddy system
  * (see mm/page_alloc.c).
+ *
+ * PAGE_BUDDY_MAPCOUNT_VALUE must be <= -2 but better not too close to
+ * -2 so that an underflow of the page_mapcount() won't be mistaken
+ * for a genuine PAGE_BUDDY_MAPCOUNT_VALUE. -128 can be created very
+ * efficiently by most CPU architectures.
  */
+#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+
 static inline int PageBuddy(struct page *page)
 {
-	return atomic_read(&page->_mapcount) == -2;
+	return atomic_read(&page->_mapcount) == PAGE_BUDDY_MAPCOUNT_VALUE;
 }
 
 static inline void __SetPageBuddy(struct page *page)
 {
 	VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
-	atomic_set(&page->_mapcount, -2);
+	atomic_set(&page->_mapcount, PAGE_BUDDY_MAPCOUNT_VALUE);
 }
 
 static inline void __ClearPageBuddy(struct page *page)
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -286,7 +286,7 @@ static void bad_page(struct page *page)
 
 	/* Don't complain about poisoned pages */
 	if (PageHWPoison(page)) {
-		__ClearPageBuddy(page);
+		reset_page_mapcount(page); /* remove PageBuddy */
 		return;
 	}
 
@@ -317,7 +317,7 @@ static void bad_page(struct page *page)
 	dump_stack();
 out:
 	/* Leave bad fields for debug, except PageBuddy could make trouble */
-	__ClearPageBuddy(page);
+	reset_page_mapcount(page); /* remove PageBuddy */
 	add_taint(TAINT_BAD_PAGE);
 }
 

--
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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2011-03-17 23:16 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-14  8:08 [PATCH] thp+memcg-numa: fix BUG at include/linux/mm.h:370! Hugh Dickins
2011-03-14  8:08 ` Hugh Dickins
2011-03-14 15:25 ` Minchan Kim
2011-03-14 15:25   ` Minchan Kim
2011-03-14 15:52 ` Andrea Arcangeli
2011-03-14 15:52   ` Andrea Arcangeli
2011-03-14 16:37   ` Hugh Dickins
2011-03-14 16:37     ` Hugh Dickins
2011-03-14 16:56     ` Linus Torvalds
2011-03-14 16:56       ` Linus Torvalds
2011-03-14 17:17       ` Andrea Arcangeli
2011-03-14 17:17         ` Andrea Arcangeli
2011-03-14 19:58         ` Johannes Weiner
2011-03-14 19:58           ` Johannes Weiner
2011-03-14 23:42           ` KAMEZAWA Hiroyuki
2011-03-14 23:42             ` KAMEZAWA Hiroyuki
2011-04-01 21:21           ` Andrea Arcangeli
2011-04-01 21:21             ` Andrea Arcangeli
2011-03-14 16:59     ` [PATCH] mm: PageBuddy and mapcount underflows robustness Andrea Arcangeli
2011-03-14 16:59       ` Andrea Arcangeli
2011-03-14 17:30       ` Linus Torvalds
2011-03-14 17:30         ` Linus Torvalds
2011-03-17 23:16         ` Andrea Arcangeli [this message]
2011-03-17 23:16           ` Andrea Arcangeli
2011-03-18 21:34           ` Hugh Dickins
2011-03-18 21:34             ` Hugh Dickins
2011-03-23 22:58             ` [stable] " Greg KH
2011-03-23 22:58               ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110317231635.GC10696@random.random \
    --to=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=rientjes@google.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.