Hmm.  You might be right.  It should work without that first alignment
operation because the (size) is already aligned.  But for safety's sake I
would probably want to change the if() into a while() to allow count to be
adjusted twice if necessary, just to be sure.  The init function is not in
a critical path.  I'll test it out a bit and commit with a credit to you.
Thanks!

-Matt
diff --git a/sys/kern/kern_kmalloc.c b/sys/kern/kern_kmalloc.c
index d222e053869..27ae4a81ac9 100644
--- a/sys/kern/kern_kmalloc.c
+++ b/sys/kern/kern_kmalloc.c
@@ -288,21 +288,23 @@ malloc_mgt_init(struct malloc_type *type __unused,
 
 	/*
 	 * Figure out the count by taking into account the size of the fobjs[]
-	 * array by adding it to the object size.
+	 * array by adding it to the object size.  This initial calculation
+	 * ignores alignment edge-cases that might require the count to be
+	 * reduced.
 	 */
 	offset = offsetof(struct kmalloc_slab, fobjs[0]);
-	offset = __VM_CACHELINE_ALIGN(offset);
 	count = (KMALLOC_SLAB_SIZE - offset) / (size + sizeof(void *));
 
 	/*
-	 * However, the fobj[] array itself must be aligned, so we might
-	 * have to reduce the count by 1.  (We can do this becaues 'size'
-	 * is already aligned as well).
+	 * Recalculate the offset of the first object, this time including
+	 * the required alignment.  (size) should already be aligned.  This
+	 * may push the last object beyond the slab so check and loop with
+	 * a reduced count as necessary.
 	 */
 	offset = offsetof(struct kmalloc_slab, fobjs[count]);
 	offset = __VM_CACHELINE_ALIGN(offset);
 
-	if (offset + size * count > KMALLOC_SLAB_SIZE) {
+	while (offset + size * count > KMALLOC_SLAB_SIZE) {
 		--count;
 		offset = offsetof(struct kmalloc_slab, fobjs[count]);
 		offset = __VM_CACHELINE_ALIGN(offset);
@@ -311,6 +313,10 @@ malloc_mgt_init(struct malloc_type *type __unused,
 
 	mgt->slab_offset = offset;
 	mgt->slab_count	 = count;
+
+	kprintf("XXX mgt_init %s base offset %zx count %zd (end %08zx)\n",
+		type->ks_shortdesc, offset, count, offset + size * count);
+
 }
 
 void

Reply via email to