#endif
+static __inline unsigned long
+powerof2_size(unsigned long size)
+{
+ int i, wt;
+
+ if (size == 0)
+ return 0;
+
+ i = flsl(size);
+ wt = (size & ~(1 << (i - 1)));
+ if (!wt)
+ --i;
+
+ return (1UL << i);
+}
+
/*
* kmalloc() (SLAB ALLOCATOR)
*
* M_ZERO - zero the returned memory.
* M_USE_RESERVE - allow greater drawdown of the free list
* M_USE_INTERRUPT_RESERVE - allow the freelist to be exhausted
+ * M_POWEROF2 - roundup size to the nearest power of 2
*
* MPSAFE
*/
}
++type->ks_calls;
+ if (flags & M_POWEROF2)
+ size = powerof2_size(size);
+
/*
* Handle the case where the limit is reached. Panic if we can't return
* NULL. The original malloc code looped, but this tended to
}
void *
-kmalloc_powerof2(unsigned long size_alloc, struct malloc_type *type, int flags)
-{
- unsigned long size;
-
- for (size = 1; size < size_alloc; size <<= 1)
- ; /* EMPTY */
- return kmalloc(size, type, flags);
-}
-
-void *
kmalloc_cachealign(unsigned long size_alloc, struct malloc_type *type,
int flags)
{
if (size_alloc < __VM_CACHELINE_SIZE)
size_alloc = __VM_CACHELINE_SIZE;
- return kmalloc_powerof2(size_alloc, type, flags);
+ return kmalloc(size_alloc, type, flags | M_POWEROF2);
}
maxsize = check_kmalloc(dmat, *vaddr, 0);
if (maxsize) {
kfree(*vaddr, M_DEVBUF);
- *vaddr = kmalloc_powerof2(maxsize, M_DEVBUF, mflags);
+ *vaddr = kmalloc(maxsize, M_DEVBUF,
+ mflags | M_POWEROF2);
check_kmalloc(dmat, *vaddr, 1);
}
} else {
maxsize = check_kmalloc(dmat, *vaddr, 0);
if (maxsize) {
kfree(*vaddr, M_DEVBUF);
- *vaddr = kmalloc_powerof2(maxsize, M_DEVBUF, mflags);
+ *vaddr = kmalloc(maxsize, M_DEVBUF,
+ mflags | M_POWEROF2);
check_kmalloc(dmat, *vaddr, 1);
}
} else {
#define M_PASSIVE_ZERO 0x0800 /* (internal to the slab code only) */
#define M_USE_INTERRUPT_RESERVE \
0x1000 /* can exhaust free list entirely */
+#define M_POWEROF2 0x2000 /* roundup size to the nearest power of 2 */
/*
* M_NOWAIT has to be a set of flags for equivalence to prior use.
#define kstrdup_debug(str, type, file, line) \
kstrdup(str, type)
#endif
-void *kmalloc_powerof2 (unsigned long size, struct malloc_type *type,
- int flags);
void *kmalloc_cachealign (unsigned long size, struct malloc_type *type,
int flags);
void kfree (void *addr, struct malloc_type *type);