Re: [PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 05:15:44PM -0800, Andrew Morton wrote:
> On Tue, 27 Nov 2012 22:34:10 -0200 Rafael Aquini  wrote:
> 
> > Do you want me to resubmit this patch with the changes you suggested?
> 
> oh, I think I can reach that far.  How's this look?
>

It looks great to me.

Just a small nitpick, 
here __balloon_page_flags should be changed to page_flags_cleared too:
> @@ -109,18 +110,16 @@ static inline void balloon_mapping_free(
>  /*
>   * __balloon_page_flags - helper to perform balloon @page ->flags tests.
>   *

Thanks!
--Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Andrew Morton
On Tue, 27 Nov 2012 22:34:10 -0200 Rafael Aquini  wrote:

> Do you want me to resubmit this patch with the changes you suggested?

oh, I think I can reach that far.  How's this look?

From: Andrew Morton 
Subject: 
mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix

use PAGE_FLAGS_CHECK_AT_PREP, s/__balloon_page_flags/page_flags_cleared/, small 
cleanups

Cc: "Michael S. Tsirkin" 
Cc: Andi Kleen 
Cc: Konrad Rzeszutek Wilk 
Cc: Mel Gorman 
Cc: Minchan Kim 
Cc: Rafael Aquini 
Cc: Rik van Riel 
Cc: Rusty Russell 
Cc: Sasha Levin 
Signed-off-by: Andrew Morton 
---

 include/linux/balloon_compaction.h |   21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff -puN 
include/linux/balloon_compaction.h~mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix
 include/linux/balloon_compaction.h
--- 
a/include/linux/balloon_compaction.h~mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix
+++ a/include/linux/balloon_compaction.h
@@ -41,6 +41,7 @@
 #ifndef _LINUX_BALLOON_COMPACTION_H
 #define _LINUX_BALLOON_COMPACTION_H
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -109,18 +110,16 @@ static inline void balloon_mapping_free(
 /*
  * __balloon_page_flags - helper to perform balloon @page ->flags tests.
  *
- * As balloon pages are got from Buddy, and we do not play with page->flags
+ * As balloon pages are obtained from buddy and we do not play with page->flags
  * at driver level (exception made when we get the page lock for compaction),
- * therefore we can safely identify a ballooned page by checking if the
- * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
- * This approach also helps on skipping ballooned pages that are locked for
- * compaction or release, thus mitigating their racy check at
- * balloon_page_movable()
+ * we can safely identify a ballooned page by checking if the
+ * PAGE_FLAGS_CHECK_AT_PREP page->flags are all cleared.  This approach also
+ * helps us skip ballooned pages that are locked for compaction or release, 
thus
+ * mitigating their racy check at balloon_page_movable()
  */
-#define BALLOON_PAGE_FLAGS_MASK   ((1UL << NR_PAGEFLAGS) - 1)
-static inline bool __balloon_page_flags(struct page *page)
+static inline bool page_flags_cleared(struct page *page)
 {
-   return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;
+   return !(page->flags & PAGE_FLAGS_CHECK_AT_PREP);
 }
 
 /*
@@ -149,10 +148,10 @@ static inline bool __is_movable_balloon_
 static inline bool balloon_page_movable(struct page *page)
 {
/*
-* Before dereferencing and testing mapping->flags, lets make sure
+* Before dereferencing and testing mapping->flags, let's make sure
 * this is not a page that uses ->mapping in a different way
 */
-   if (__balloon_page_flags(page) && !page_mapped(page) &&
+   if (page_flags_cleared(page) && !page_mapped(page) &&
page_count(page) == 1)
return __is_movable_balloon_page(page);
 
_

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 03:52:01PM -0800, Andrew Morton wrote:
> On Tue, 27 Nov 2012 21:31:10 -0200
> Rafael Aquini  wrote:
> 
> > This patch fixes the following crash by fixing and enhancing the way 
> > page->flags are tested to identify a ballooned page.
> > 
> > ---8<---
> > BUG: unable to handle kernel NULL pointer dereference at 0194
> > IP: [] isolate_migratepages_range+0x344/0x7b0
> > --->8---
> > 
> > The NULL pointer deref was taking place because balloon_page_movable()
> > page->flags tests were incomplete and we ended up 
> > inadvertently poking at private pages.
> > 
> > 
> >
> >  /*
> > + * __balloon_page_flags - helper to perform balloon @page ->flags tests.
> > + *
> > + * As balloon pages are got from Buddy, and we do not play with page->flags
> > + * at driver level (exception made when we get the page lock for 
> > compaction),
> > + * therefore we can safely identify a ballooned page by checking if the
> > + * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
> > + * This approach also helps on skipping ballooned pages that are locked for
> > + * compaction or release, thus mitigating their racy check at
> > + * balloon_page_movable()
> > + */
> > +#define BALLOON_PAGE_FLAGS_MASK   ((1UL << NR_PAGEFLAGS) - 1)
> 
> hm, this seems a bit fragile.
> 
> What's actually going on here?  You're assuming that a page fresh from
> buddy has all flags 0..NR_PAGEFLAGS cleared?
>
 
Yes, thats the idea, as when we get pages from freelists, they are all checked 
by prep_new_page()->check_new_page() before buffered_rmqueue() returns them.
By the path we use to get balloon pages, if the page has any of 0..NR_PAGEFLAGS
flags set at the alloc time it's regarded as bad_page by check_new_page(),
and we go after another victim.


> That may be true, I'm unsure.  Please take a look at
> PAGE_FLAGS_CHECK_AT_FREE and PAGE_FLAGS_CHECK_AT_PREP and work out why
> the heck these aren't the same thing!

Humm, I can't think of why, either... As I've followed the prep path, I didn't
notice that difference. I'll look at it closer, though.


>
> Either way around, doing
> 
>   #define BALLOON_PAGE_FLAGS_MASK PAGE_FLAGS_CHECK_AT_PREP
> 
> seems rather more maintainable.

As usual, your suggestion is far way better than my orinal proposal :)


> 
> > +static inline bool __balloon_page_flags(struct page *page)
> > +{
> > +   return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;
> 
> We have a neater way of doing the scalar-to-boolean conversion:
> 
>   return !(page->flags & BALLOON_PAGE_FLAGS_MASK);
> 

ditto! :)


Do you want me to resubmit this patch with the changes you suggested?


Cheers!
Rafael

> > +}
> > +
> > +/*
> >   * __is_movable_balloon_page - helper to perform @page mapping->flags tests
> >   */
> >  static inline bool __is_movable_balloon_page(struct page *page)
> > @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page 
> > *page)
> >  * Before dereferencing and testing mapping->flags, lets make sure
> >  * this is not a page that uses ->mapping in a different way
> >  */
> > -   if (!PageSlab(page) && !PageSwapCache(page) && !PageAnon(page) &&
> > -   !page_mapped(page))
> > +   if (__balloon_page_flags(page) && !page_mapped(page) &&
> > +   page_count(page) == 1)
> > return __is_movable_balloon_page(page);
> >  
> > return false;
> >
> > ...
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Andrew Morton
On Tue, 27 Nov 2012 21:31:10 -0200
Rafael Aquini  wrote:

> This patch fixes the following crash by fixing and enhancing the way 
> page->flags are tested to identify a ballooned page.
> 
> ---8<---
> BUG: unable to handle kernel NULL pointer dereference at 0194
> IP: [] isolate_migratepages_range+0x344/0x7b0
> --->8---
> 
> The NULL pointer deref was taking place because balloon_page_movable()
> page->flags tests were incomplete and we ended up 
> inadvertently poking at private pages.
> 
> 
>
>  /*
> + * __balloon_page_flags - helper to perform balloon @page ->flags tests.
> + *
> + * As balloon pages are got from Buddy, and we do not play with page->flags
> + * at driver level (exception made when we get the page lock for compaction),
> + * therefore we can safely identify a ballooned page by checking if the
> + * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
> + * This approach also helps on skipping ballooned pages that are locked for
> + * compaction or release, thus mitigating their racy check at
> + * balloon_page_movable()
> + */
> +#define BALLOON_PAGE_FLAGS_MASK   ((1UL << NR_PAGEFLAGS) - 1)

hm, this seems a bit fragile.

What's actually going on here?  You're assuming that a page fresh from
buddy has all flags 0..NR_PAGEFLAGS cleared?

That may be true, I'm unsure.  Please take a look at
PAGE_FLAGS_CHECK_AT_FREE and PAGE_FLAGS_CHECK_AT_PREP and work out why
the heck these aren't the same thing!

Either way around, doing

#define BALLOON_PAGE_FLAGS_MASK PAGE_FLAGS_CHECK_AT_PREP

seems rather more maintainable.

> +static inline bool __balloon_page_flags(struct page *page)
> +{
> + return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;

We have a neater way of doing the scalar-to-boolean conversion:

return !(page->flags & BALLOON_PAGE_FLAGS_MASK);

> +}
> +
> +/*
>   * __is_movable_balloon_page - helper to perform @page mapping->flags tests
>   */
>  static inline bool __is_movable_balloon_page(struct page *page)
> @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
>* Before dereferencing and testing mapping->flags, lets make sure
>* this is not a page that uses ->mapping in a different way
>*/
> - if (!PageSlab(page) && !PageSwapCache(page) && !PageAnon(page) &&
> - !page_mapped(page))
> + if (__balloon_page_flags(page) && !page_mapped(page) &&
> + page_count(page) == 1)
>   return __is_movable_balloon_page(page);
>  
>   return false;
>
> ...
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 09:31:10PM -0200, Rafael Aquini wrote:
> This patch fixes the following crash by fixing and enhancing the way 
> page->flags are tested to identify a ballooned page.
> 
> ---8<---
> BUG: unable to handle kernel NULL pointer dereference at 0194
> IP: [] isolate_migratepages_range+0x344/0x7b0
> --->8---
> 
> The NULL pointer deref was taking place because balloon_page_movable()
> page->flags tests were incomplete and we ended up 
> inadvertently poking at private pages.
> 
> Reported-by: Sasha Levin 
> Signed-off-by: Rafael Aquini 
> ---

Here it is Andrew, sorry by the lagged reply

Cheers!
--Rafael


>  include/linux/balloon_compaction.h | 21 +++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/balloon_compaction.h 
> b/include/linux/balloon_compaction.h
> index 68893bc..634a19b 100644
> --- a/include/linux/balloon_compaction.h
> +++ b/include/linux/balloon_compaction.h
> @@ -107,6 +107,23 @@ static inline void balloon_mapping_free(struct 
> address_space *balloon_mapping)
>  }
>  
>  /*
> + * __balloon_page_flags - helper to perform balloon @page ->flags tests.
> + *
> + * As balloon pages are got from Buddy, and we do not play with page->flags
> + * at driver level (exception made when we get the page lock for compaction),
> + * therefore we can safely identify a ballooned page by checking if the
> + * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
> + * This approach also helps on skipping ballooned pages that are locked for
> + * compaction or release, thus mitigating their racy check at
> + * balloon_page_movable()
> + */
> +#define BALLOON_PAGE_FLAGS_MASK   ((1UL << NR_PAGEFLAGS) - 1)
> +static inline bool __balloon_page_flags(struct page *page)
> +{
> + return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;
> +}
> +
> +/*
>   * __is_movable_balloon_page - helper to perform @page mapping->flags tests
>   */
>  static inline bool __is_movable_balloon_page(struct page *page)
> @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
>* Before dereferencing and testing mapping->flags, lets make sure
>* this is not a page that uses ->mapping in a different way
>*/
> - if (!PageSlab(page) && !PageSwapCache(page) && !PageAnon(page) &&
> - !page_mapped(page))
> + if (__balloon_page_flags(page) && !page_mapped(page) &&
> + page_count(page) == 1)
>   return __is_movable_balloon_page(page);
>  
>   return false;
> -- 
> 1.7.11.7
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mm: fix balloon_page_movable() page->flags check

2012-11-27 Thread Rafael Aquini
This patch fixes the following crash by fixing and enhancing the way 
page->flags are tested to identify a ballooned page.

---8<---
BUG: unable to handle kernel NULL pointer dereference at 0194
IP: [] isolate_migratepages_range+0x344/0x7b0
--->8---

The NULL pointer deref was taking place because balloon_page_movable()
page->flags tests were incomplete and we ended up 
inadvertently poking at private pages.

Reported-by: Sasha Levin 
Signed-off-by: Rafael Aquini 
---
 include/linux/balloon_compaction.h | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/linux/balloon_compaction.h 
b/include/linux/balloon_compaction.h
index 68893bc..634a19b 100644
--- a/include/linux/balloon_compaction.h
+++ b/include/linux/balloon_compaction.h
@@ -107,6 +107,23 @@ static inline void balloon_mapping_free(struct 
address_space *balloon_mapping)
 }
 
 /*
+ * __balloon_page_flags - helper to perform balloon @page ->flags tests.
+ *
+ * As balloon pages are got from Buddy, and we do not play with page->flags
+ * at driver level (exception made when we get the page lock for compaction),
+ * therefore we can safely identify a ballooned page by checking if the
+ * NR_PAGEFLAGS rightmost bits from the page->flags are all cleared.
+ * This approach also helps on skipping ballooned pages that are locked for
+ * compaction or release, thus mitigating their racy check at
+ * balloon_page_movable()
+ */
+#define BALLOON_PAGE_FLAGS_MASK   ((1UL << NR_PAGEFLAGS) - 1)
+static inline bool __balloon_page_flags(struct page *page)
+{
+   return page->flags & BALLOON_PAGE_FLAGS_MASK ? false : true;
+}
+
+/*
  * __is_movable_balloon_page - helper to perform @page mapping->flags tests
  */
 static inline bool __is_movable_balloon_page(struct page *page)
@@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
 * Before dereferencing and testing mapping->flags, lets make sure
 * this is not a page that uses ->mapping in a different way
 */
-   if (!PageSlab(page) && !PageSwapCache(page) && !PageAnon(page) &&
-   !page_mapped(page))
+   if (__balloon_page_flags(page) && !page_mapped(page) &&
+   page_count(page) == 1)
return __is_movable_balloon_page(page);
 
return false;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Rafael Aquini
This patch fixes the following crash by fixing and enhancing the way 
page-flags are tested to identify a ballooned page.

---8---
BUG: unable to handle kernel NULL pointer dereference at 0194
IP: [8122b354] isolate_migratepages_range+0x344/0x7b0
---8---

The NULL pointer deref was taking place because balloon_page_movable()
page-flags tests were incomplete and we ended up 
inadvertently poking at private pages.

Reported-by: Sasha Levin levinsasha...@gmail.com
Signed-off-by: Rafael Aquini aqu...@redhat.com
---
 include/linux/balloon_compaction.h | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/linux/balloon_compaction.h 
b/include/linux/balloon_compaction.h
index 68893bc..634a19b 100644
--- a/include/linux/balloon_compaction.h
+++ b/include/linux/balloon_compaction.h
@@ -107,6 +107,23 @@ static inline void balloon_mapping_free(struct 
address_space *balloon_mapping)
 }
 
 /*
+ * __balloon_page_flags - helper to perform balloon @page -flags tests.
+ *
+ * As balloon pages are got from Buddy, and we do not play with page-flags
+ * at driver level (exception made when we get the page lock for compaction),
+ * therefore we can safely identify a ballooned page by checking if the
+ * NR_PAGEFLAGS rightmost bits from the page-flags are all cleared.
+ * This approach also helps on skipping ballooned pages that are locked for
+ * compaction or release, thus mitigating their racy check at
+ * balloon_page_movable()
+ */
+#define BALLOON_PAGE_FLAGS_MASK   ((1UL  NR_PAGEFLAGS) - 1)
+static inline bool __balloon_page_flags(struct page *page)
+{
+   return page-flags  BALLOON_PAGE_FLAGS_MASK ? false : true;
+}
+
+/*
  * __is_movable_balloon_page - helper to perform @page mapping-flags tests
  */
 static inline bool __is_movable_balloon_page(struct page *page)
@@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
 * Before dereferencing and testing mapping-flags, lets make sure
 * this is not a page that uses -mapping in a different way
 */
-   if (!PageSlab(page)  !PageSwapCache(page)  !PageAnon(page) 
-   !page_mapped(page))
+   if (__balloon_page_flags(page)  !page_mapped(page) 
+   page_count(page) == 1)
return __is_movable_balloon_page(page);
 
return false;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 09:31:10PM -0200, Rafael Aquini wrote:
 This patch fixes the following crash by fixing and enhancing the way 
 page-flags are tested to identify a ballooned page.
 
 ---8---
 BUG: unable to handle kernel NULL pointer dereference at 0194
 IP: [8122b354] isolate_migratepages_range+0x344/0x7b0
 ---8---
 
 The NULL pointer deref was taking place because balloon_page_movable()
 page-flags tests were incomplete and we ended up 
 inadvertently poking at private pages.
 
 Reported-by: Sasha Levin levinsasha...@gmail.com
 Signed-off-by: Rafael Aquini aqu...@redhat.com
 ---

Here it is Andrew, sorry by the lagged reply

Cheers!
--Rafael


  include/linux/balloon_compaction.h | 21 +++--
  1 file changed, 19 insertions(+), 2 deletions(-)
 
 diff --git a/include/linux/balloon_compaction.h 
 b/include/linux/balloon_compaction.h
 index 68893bc..634a19b 100644
 --- a/include/linux/balloon_compaction.h
 +++ b/include/linux/balloon_compaction.h
 @@ -107,6 +107,23 @@ static inline void balloon_mapping_free(struct 
 address_space *balloon_mapping)
  }
  
  /*
 + * __balloon_page_flags - helper to perform balloon @page -flags tests.
 + *
 + * As balloon pages are got from Buddy, and we do not play with page-flags
 + * at driver level (exception made when we get the page lock for compaction),
 + * therefore we can safely identify a ballooned page by checking if the
 + * NR_PAGEFLAGS rightmost bits from the page-flags are all cleared.
 + * This approach also helps on skipping ballooned pages that are locked for
 + * compaction or release, thus mitigating their racy check at
 + * balloon_page_movable()
 + */
 +#define BALLOON_PAGE_FLAGS_MASK   ((1UL  NR_PAGEFLAGS) - 1)
 +static inline bool __balloon_page_flags(struct page *page)
 +{
 + return page-flags  BALLOON_PAGE_FLAGS_MASK ? false : true;
 +}
 +
 +/*
   * __is_movable_balloon_page - helper to perform @page mapping-flags tests
   */
  static inline bool __is_movable_balloon_page(struct page *page)
 @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
* Before dereferencing and testing mapping-flags, lets make sure
* this is not a page that uses -mapping in a different way
*/
 - if (!PageSlab(page)  !PageSwapCache(page)  !PageAnon(page) 
 - !page_mapped(page))
 + if (__balloon_page_flags(page)  !page_mapped(page) 
 + page_count(page) == 1)
   return __is_movable_balloon_page(page);
  
   return false;
 -- 
 1.7.11.7
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Andrew Morton
On Tue, 27 Nov 2012 21:31:10 -0200
Rafael Aquini aqu...@redhat.com wrote:

 This patch fixes the following crash by fixing and enhancing the way 
 page-flags are tested to identify a ballooned page.
 
 ---8---
 BUG: unable to handle kernel NULL pointer dereference at 0194
 IP: [8122b354] isolate_migratepages_range+0x344/0x7b0
 ---8---
 
 The NULL pointer deref was taking place because balloon_page_movable()
 page-flags tests were incomplete and we ended up 
 inadvertently poking at private pages.
 
 

  /*
 + * __balloon_page_flags - helper to perform balloon @page -flags tests.
 + *
 + * As balloon pages are got from Buddy, and we do not play with page-flags
 + * at driver level (exception made when we get the page lock for compaction),
 + * therefore we can safely identify a ballooned page by checking if the
 + * NR_PAGEFLAGS rightmost bits from the page-flags are all cleared.
 + * This approach also helps on skipping ballooned pages that are locked for
 + * compaction or release, thus mitigating their racy check at
 + * balloon_page_movable()
 + */
 +#define BALLOON_PAGE_FLAGS_MASK   ((1UL  NR_PAGEFLAGS) - 1)

hm, this seems a bit fragile.

What's actually going on here?  You're assuming that a page fresh from
buddy has all flags 0..NR_PAGEFLAGS cleared?

That may be true, I'm unsure.  Please take a look at
PAGE_FLAGS_CHECK_AT_FREE and PAGE_FLAGS_CHECK_AT_PREP and work out why
the heck these aren't the same thing!

Either way around, doing

#define BALLOON_PAGE_FLAGS_MASK PAGE_FLAGS_CHECK_AT_PREP

seems rather more maintainable.

 +static inline bool __balloon_page_flags(struct page *page)
 +{
 + return page-flags  BALLOON_PAGE_FLAGS_MASK ? false : true;

We have a neater way of doing the scalar-to-boolean conversion:

return !(page-flags  BALLOON_PAGE_FLAGS_MASK);

 +}
 +
 +/*
   * __is_movable_balloon_page - helper to perform @page mapping-flags tests
   */
  static inline bool __is_movable_balloon_page(struct page *page)
 @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page *page)
* Before dereferencing and testing mapping-flags, lets make sure
* this is not a page that uses -mapping in a different way
*/
 - if (!PageSlab(page)  !PageSwapCache(page)  !PageAnon(page) 
 - !page_mapped(page))
 + if (__balloon_page_flags(page)  !page_mapped(page) 
 + page_count(page) == 1)
   return __is_movable_balloon_page(page);
  
   return false;

 ...

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 03:52:01PM -0800, Andrew Morton wrote:
 On Tue, 27 Nov 2012 21:31:10 -0200
 Rafael Aquini aqu...@redhat.com wrote:
 
  This patch fixes the following crash by fixing and enhancing the way 
  page-flags are tested to identify a ballooned page.
  
  ---8---
  BUG: unable to handle kernel NULL pointer dereference at 0194
  IP: [8122b354] isolate_migratepages_range+0x344/0x7b0
  ---8---
  
  The NULL pointer deref was taking place because balloon_page_movable()
  page-flags tests were incomplete and we ended up 
  inadvertently poking at private pages.
  
  
 
   /*
  + * __balloon_page_flags - helper to perform balloon @page -flags tests.
  + *
  + * As balloon pages are got from Buddy, and we do not play with page-flags
  + * at driver level (exception made when we get the page lock for 
  compaction),
  + * therefore we can safely identify a ballooned page by checking if the
  + * NR_PAGEFLAGS rightmost bits from the page-flags are all cleared.
  + * This approach also helps on skipping ballooned pages that are locked for
  + * compaction or release, thus mitigating their racy check at
  + * balloon_page_movable()
  + */
  +#define BALLOON_PAGE_FLAGS_MASK   ((1UL  NR_PAGEFLAGS) - 1)
 
 hm, this seems a bit fragile.
 
 What's actually going on here?  You're assuming that a page fresh from
 buddy has all flags 0..NR_PAGEFLAGS cleared?

 
Yes, thats the idea, as when we get pages from freelists, they are all checked 
by prep_new_page()-check_new_page() before buffered_rmqueue() returns them.
By the path we use to get balloon pages, if the page has any of 0..NR_PAGEFLAGS
flags set at the alloc time it's regarded as bad_page by check_new_page(),
and we go after another victim.


 That may be true, I'm unsure.  Please take a look at
 PAGE_FLAGS_CHECK_AT_FREE and PAGE_FLAGS_CHECK_AT_PREP and work out why
 the heck these aren't the same thing!

Humm, I can't think of why, either... As I've followed the prep path, I didn't
notice that difference. I'll look at it closer, though.



 Either way around, doing
 
   #define BALLOON_PAGE_FLAGS_MASK PAGE_FLAGS_CHECK_AT_PREP
 
 seems rather more maintainable.

As usual, your suggestion is far way better than my orinal proposal :)


 
  +static inline bool __balloon_page_flags(struct page *page)
  +{
  +   return page-flags  BALLOON_PAGE_FLAGS_MASK ? false : true;
 
 We have a neater way of doing the scalar-to-boolean conversion:
 
   return !(page-flags  BALLOON_PAGE_FLAGS_MASK);
 

ditto! :)


Do you want me to resubmit this patch with the changes you suggested?


Cheers!
Rafael

  +}
  +
  +/*
* __is_movable_balloon_page - helper to perform @page mapping-flags tests
*/
   static inline bool __is_movable_balloon_page(struct page *page)
  @@ -135,8 +152,8 @@ static inline bool balloon_page_movable(struct page 
  *page)
   * Before dereferencing and testing mapping-flags, lets make sure
   * this is not a page that uses -mapping in a different way
   */
  -   if (!PageSlab(page)  !PageSwapCache(page)  !PageAnon(page) 
  -   !page_mapped(page))
  +   if (__balloon_page_flags(page)  !page_mapped(page) 
  +   page_count(page) == 1)
  return __is_movable_balloon_page(page);
   
  return false;
 
  ...
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Andrew Morton
On Tue, 27 Nov 2012 22:34:10 -0200 Rafael Aquini aqu...@redhat.com wrote:

 Do you want me to resubmit this patch with the changes you suggested?

oh, I think I can reach that far.  How's this look?

From: Andrew Morton a...@linux-foundation.org
Subject: 
mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix

use PAGE_FLAGS_CHECK_AT_PREP, s/__balloon_page_flags/page_flags_cleared/, small 
cleanups

Cc: Michael S. Tsirkin m...@redhat.com
Cc: Andi Kleen a...@firstfloor.org
Cc: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Cc: Mel Gorman m...@csn.ul.ie
Cc: Minchan Kim minc...@kernel.org
Cc: Rafael Aquini aqu...@redhat.com
Cc: Rik van Riel r...@redhat.com
Cc: Rusty Russell ru...@rustcorp.com.au
Cc: Sasha Levin levinsasha...@gmail.com
Signed-off-by: Andrew Morton a...@linux-foundation.org
---

 include/linux/balloon_compaction.h |   21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff -puN 
include/linux/balloon_compaction.h~mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix
 include/linux/balloon_compaction.h
--- 
a/include/linux/balloon_compaction.h~mm-introduce-a-common-interface-for-balloon-pages-mobility-mm-fix-balloon_page_movable-page-flags-check-fix
+++ a/include/linux/balloon_compaction.h
@@ -41,6 +41,7 @@
 #ifndef _LINUX_BALLOON_COMPACTION_H
 #define _LINUX_BALLOON_COMPACTION_H
 #include linux/pagemap.h
+#include linux/page-flags.h
 #include linux/migrate.h
 #include linux/gfp.h
 #include linux/err.h
@@ -109,18 +110,16 @@ static inline void balloon_mapping_free(
 /*
  * __balloon_page_flags - helper to perform balloon @page -flags tests.
  *
- * As balloon pages are got from Buddy, and we do not play with page-flags
+ * As balloon pages are obtained from buddy and we do not play with page-flags
  * at driver level (exception made when we get the page lock for compaction),
- * therefore we can safely identify a ballooned page by checking if the
- * NR_PAGEFLAGS rightmost bits from the page-flags are all cleared.
- * This approach also helps on skipping ballooned pages that are locked for
- * compaction or release, thus mitigating their racy check at
- * balloon_page_movable()
+ * we can safely identify a ballooned page by checking if the
+ * PAGE_FLAGS_CHECK_AT_PREP page-flags are all cleared.  This approach also
+ * helps us skip ballooned pages that are locked for compaction or release, 
thus
+ * mitigating their racy check at balloon_page_movable()
  */
-#define BALLOON_PAGE_FLAGS_MASK   ((1UL  NR_PAGEFLAGS) - 1)
-static inline bool __balloon_page_flags(struct page *page)
+static inline bool page_flags_cleared(struct page *page)
 {
-   return page-flags  BALLOON_PAGE_FLAGS_MASK ? false : true;
+   return !(page-flags  PAGE_FLAGS_CHECK_AT_PREP);
 }
 
 /*
@@ -149,10 +148,10 @@ static inline bool __is_movable_balloon_
 static inline bool balloon_page_movable(struct page *page)
 {
/*
-* Before dereferencing and testing mapping-flags, lets make sure
+* Before dereferencing and testing mapping-flags, let's make sure
 * this is not a page that uses -mapping in a different way
 */
-   if (__balloon_page_flags(page)  !page_mapped(page) 
+   if (page_flags_cleared(page)  !page_mapped(page) 
page_count(page) == 1)
return __is_movable_balloon_page(page);
 
_

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] mm: fix balloon_page_movable() page-flags check

2012-11-27 Thread Rafael Aquini
On Tue, Nov 27, 2012 at 05:15:44PM -0800, Andrew Morton wrote:
 On Tue, 27 Nov 2012 22:34:10 -0200 Rafael Aquini aqu...@redhat.com wrote:
 
  Do you want me to resubmit this patch with the changes you suggested?
 
 oh, I think I can reach that far.  How's this look?


It looks great to me.

Just a small nitpick, 
here __balloon_page_flags should be changed to page_flags_cleared too:
 @@ -109,18 +110,16 @@ static inline void balloon_mapping_free(
  /*
   * __balloon_page_flags - helper to perform balloon @page -flags tests.
   *

Thanks!
--Rafael
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/