@@ -63,9 +63,14 @@ struct sbitmap {
unsigned int map_nr;
/**
- * @map: Allocated bitmap.
+ * @map: Aligned allocated bitmap.
*/
struct sbitmap_word *map;
+
+ /**
+ * @map_ptr: Originally allocated map pointer
+ */
+ void *map_ptr;
};
#define SBQ_WAIT_QUEUES 8
@@ -157,8 +162,8 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
*/
static inline void sbitmap_free(struct sbitmap *sb)
{
- kfree(sb->map);
- sb->map = NULL;
+ kfree(sb->map_ptr);
+ sb->map_ptr = sb->map = NULL;
}
/**
@@ -25,6 +25,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
{
unsigned int bits_per_word;
unsigned int i;
+ size_t size;
if (shift < 0) {
shift = ilog2(BITS_PER_LONG);
@@ -52,9 +53,11 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
return 0;
}
- sb->map = kcalloc_node(sb->map_nr, sizeof(*sb->map), flags, node);
- if (!sb->map)
+ size = sb->map_nr * sizeof(*sb->map) + L1_CACHE_BYTES - 1;
+ sb->map_ptr = kzalloc_node(size, flags, node);
+ if (!sb->map_ptr)
return -ENOMEM;
+ sb->map = PTR_ALIGN(sb->map_ptr, L1_CACHE_BYTES);
for (i = 0; i < sb->map_nr; i++) {
sb->map[i].depth = min(depth, bits_per_word);
We try to be careful with alignment for cache purposes, but all of that is worthless if we don't actually align the maps themselves. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- include/linux/sbitmap.h | 11 ++++++++--- lib/sbitmap.c | 7 +++++-- 2 files changed, 13 insertions(+), 5 deletions(-)