nommu: fix kobjsize() for SLOB and SLUB
[linux-2.6-block.git] / mm / nommu.c
index dca93fcb8b7a6517ad041221343bddf61e572644..3abd0845bda4a0901eed248ed96f7aef0c2f7ae8 100644 (file)
@@ -104,21 +104,43 @@ EXPORT_SYMBOL(vmtruncate);
 unsigned int kobjsize(const void *objp)
 {
        struct page *page;
+       int order = 0;
 
        /*
         * 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 the allocator sets PageSlab, we know the pointer came from
+        * kmalloc().
+        */
        if (PageSlab(page))
                return ksize(objp);
 
-       BUG_ON(page->index < 0);
-       BUG_ON(page->index >= MAX_ORDER);
+       /*
+        * The ksize() function is only guaranteed to work for pointers
+        * returned by kmalloc(). So handle arbitrary pointers, that we expect
+        * always to be compound pages, here.
+        */
+       if (PageCompound(page))
+               order = compound_order(page);
 
-       return (PAGE_SIZE << page->index);
+       /*
+        * Finally, handle arbitrary pointers that don't set PageSlab.
+        * Default to 0-order in the case when we're unable to ksize()
+        * the object.
+        */
+       return PAGE_SIZE << order;
 }
 
 /*