Re: [PATCH] nommu: fix kobjsize() for SLOB and SLUB

Pekka J Enberg
2008-06-01T08:37:22Z

On Sun, 1 Jun 2008, Paul Mundt wrote:
> This still needs to be virt_to_head_page() I think.
>
> I don't have my nommu boards at home, so I'll test at the office tomorow
> morning and let you know.

Yes, I messed that up. Thanks a lot for your help, Paul!

Pekka

[PATCH] nommu: kobjsize fix
From: Christoph Lameter <clameter@sgi.com>

The kobjsize() function is broken with SLOB and SLUB. As summarized by Paul
Mundt:

The page->index bits look like they are being used for determining compound
order, which is _completely_ bogus, and only happens to "work" in a few
cases. Christoph and I have repeatedly asked for someone to explain what the
hell those tests are there for, as right now they not only look completely
bogus, but they also stop us from booting on SLOB. So far no one has
provided any input on why those page->index BUG_ON()'s have any right to
exist.

So while having 2 out of 3 SLAB allocators in a bootable state might seem
like progress, I'd rather see kobjsize() fixed correctly. Even my initial
patches worked for all 3.

If no one can speak up to defend those bits, they should be killed off before
2.6.26. Whether this is done in combination with your patch or Christoph's
patch or whatever else doesn't matter.

You can find the discussion here:

http://lkml.org/lkml/2008/5/22/223

Reported-by: Paul Mundt <lethal@linux-sh.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
---

diff --git a/mm/nommu.c b/mm/nommu.c
index dca93fc..935887b 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -109,16 +109,23 @@ unsigned int kobjsize(const void *objp)
* If the object we have should not have ksize performed on it,
* return size of 0
*/
- if (!objp || (unsigned long)objp >= memory_end || !((page = virt_to_page(objp))))
+ if (!objp)
+ return 0;
+
+ if ((unsigned long)objp >= memory_end)
+ return 0;
+
+ page = virt_to_head_page(objp);
+ if (!page)
return 0;

if (PageSlab(page))
return ksize(objp);

- BUG_ON(page->index < 0);
- BUG_ON(page->index >= MAX_ORDER);
+ if (WARN_ON(!PageCompound(page)))
+ return 0;

- return (PAGE_SIZE << page->index);
+ return PAGE_SIZE << compound_order(page);
}

/*