}
 EXPORT_SYMBOL(kmem_find_general_cachep);
 
-/* Cal the num objs, wastage, and bytes left over for a given slab size. */
-static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
-                          int flags, size_t *left_over, unsigned int *num)
+static size_t slab_mgmt_size(size_t nr_objs, size_t align)
 {
-       int i;
-       size_t wastage = PAGE_SIZE << gfporder;
-       size_t extra = 0;
-       size_t base = 0;
+       return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align);
+}
 
-       if (!(flags & CFLGS_OFF_SLAB)) {
-               base = sizeof(struct slab);
-               extra = sizeof(kmem_bufctl_t);
-       }
-       i = 0;
-       while (i * size + ALIGN(base + i * extra, align) <= wastage)
-               i++;
-       if (i > 0)
-               i--;
+/* Calculate the number of objects and left-over bytes for a given
+   buffer size. */
+static void cache_estimate(unsigned long gfporder, size_t buffer_size,
+                          size_t align, int flags, size_t *left_over,
+                          unsigned int *num)
+{
+       int nr_objs;
+       size_t mgmt_size;
+       size_t slab_size = PAGE_SIZE << gfporder;
 
-       if (i > SLAB_LIMIT)
-               i = SLAB_LIMIT;
+       /*
+        * The slab management structure can be either off the slab or
+        * on it. For the latter case, the memory allocated for a
+        * slab is used for:
+        *
+        * - The struct slab
+        * - One kmem_bufctl_t for each object
+        * - Padding to respect alignment of @align
+        * - @buffer_size bytes for each object
+        *
+        * If the slab management structure is off the slab, then the
+        * alignment will already be calculated into the size. Because
+        * the slabs are all pages aligned, the objects will be at the
+        * correct alignment when allocated.
+        */
+       if (flags & CFLGS_OFF_SLAB) {
+               mgmt_size = 0;
+               nr_objs = slab_size / buffer_size;
 
-       *num = i;
-       wastage -= i * size;
-       wastage -= ALIGN(base + i * extra, align);
-       *left_over = wastage;
+               if (nr_objs > SLAB_LIMIT)
+                       nr_objs = SLAB_LIMIT;
+       } else {
+               /*
+                * Ignore padding for the initial guess. The padding
+                * is at most @align-1 bytes, and @buffer_size is at
+                * least @align. In the worst case, this result will
+                * be one greater than the number of objects that fit
+                * into the memory allocation when taking the padding
+                * into account.
+                */
+               nr_objs = (slab_size - sizeof(struct slab)) /
+                         (buffer_size + sizeof(kmem_bufctl_t));
+
+               /*
+                * This calculated number will be either the right
+                * amount, or one greater than what we want.
+                */
+               if (slab_mgmt_size(nr_objs, align) + nr_objs*buffer_size
+                      > slab_size)
+                       nr_objs--;
+
+               if (nr_objs > SLAB_LIMIT)
+                       nr_objs = SLAB_LIMIT;
+
+               mgmt_size = slab_mgmt_size(nr_objs, align);
+       }
+       *num = nr_objs;
+       *left_over = slab_size - nr_objs*buffer_size - mgmt_size;
 }
 
 #define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg)