|
@@ -565,9 +565,31 @@ static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
|
|
|
return cachep->array[smp_processor_id()];
|
|
|
}
|
|
|
|
|
|
-static size_t slab_mgmt_size(size_t nr_objs, size_t align)
|
|
|
+static int calculate_nr_objs(size_t slab_size, size_t buffer_size,
|
|
|
+ size_t idx_size, size_t align)
|
|
|
{
|
|
|
- return ALIGN(nr_objs * sizeof(unsigned int), align);
|
|
|
+ int nr_objs;
|
|
|
+ size_t freelist_size;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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 / (buffer_size + idx_size);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This calculated number will be either the right
|
|
|
+ * amount, or one greater than what we want.
|
|
|
+ */
|
|
|
+ freelist_size = slab_size - nr_objs * buffer_size;
|
|
|
+ if (freelist_size < ALIGN(nr_objs * idx_size, align))
|
|
|
+ nr_objs--;
|
|
|
+
|
|
|
+ return nr_objs;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -600,25 +622,9 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
|
|
|
nr_objs = slab_size / buffer_size;
|
|
|
|
|
|
} 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) / (buffer_size + sizeof(unsigned int));
|
|
|
-
|
|
|
- /*
|
|
|
- * 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--;
|
|
|
-
|
|
|
- mgmt_size = slab_mgmt_size(nr_objs, align);
|
|
|
+ nr_objs = calculate_nr_objs(slab_size, buffer_size,
|
|
|
+ sizeof(unsigned int), align);
|
|
|
+ mgmt_size = ALIGN(nr_objs * sizeof(unsigned int), align);
|
|
|
}
|
|
|
*num = nr_objs;
|
|
|
*left_over = slab_size - nr_objs*buffer_size - mgmt_size;
|