diff options
Diffstat (limited to 'sys/ofed/drivers/net/mlx4/alloc.c')
-rw-r--r-- | sys/ofed/drivers/net/mlx4/alloc.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/sys/ofed/drivers/net/mlx4/alloc.c b/sys/ofed/drivers/net/mlx4/alloc.c index c22791a..38f3caf 100644 --- a/sys/ofed/drivers/net/mlx4/alloc.c +++ b/sys/ofed/drivers/net/mlx4/alloc.c @@ -34,6 +34,7 @@ #include <linux/errno.h> #include <linux/slab.h> #include <linux/mm.h> +//#include <linux/export.h> /* XXX SK probabaly not needed in freeBSD XXX */ #include <linux/bitmap.h> #include <linux/dma-mapping.h> #include <linux/vmalloc.h> @@ -77,14 +78,15 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj) static unsigned long find_aligned_range(unsigned long *bitmap, u32 start, u32 nbits, - int len, int align) + int len, int align, u32 skip_mask) { unsigned long end, i; again: start = ALIGN(start, align); - while ((start < nbits) && test_bit(start, bitmap)) + while ((start < nbits) && (test_bit(start, bitmap) || + (start & skip_mask))) start += align; if (start >= nbits) @@ -95,7 +97,7 @@ again: return -1; for (i = start + 1; i < end; i++) { - if (test_bit(i, bitmap)) { + if (test_bit(i, bitmap) || ((u32)i & skip_mask)) { start = i + 1; goto again; } @@ -104,27 +106,27 @@ again: return start; } -u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) +u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, + int align, u32 skip_mask) { - u32 obj, i; + u32 obj; - if (likely(cnt == 1 && align == 1)) + if (likely(cnt == 1 && align == 1 && !skip_mask)) return mlx4_bitmap_alloc(bitmap); spin_lock(&bitmap->lock); obj = find_aligned_range(bitmap->table, bitmap->last, - bitmap->max, cnt, align); + bitmap->max, cnt, align, skip_mask); if (obj >= bitmap->max) { bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) & bitmap->mask; obj = find_aligned_range(bitmap->table, 0, bitmap->max, - cnt, align); + cnt, align, skip_mask); } if (obj < bitmap->max) { - for (i = 0; i < cnt; i++) - set_bit(obj + i, bitmap->table); + bitmap_set(bitmap->table, obj, cnt); if (obj == bitmap->last) { bitmap->last = (obj + cnt); if (bitmap->last >= bitmap->max) @@ -149,16 +151,10 @@ u32 mlx4_bitmap_avail(struct mlx4_bitmap *bitmap) void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) { - u32 i; - obj &= bitmap->max + bitmap->reserved_top - 1; spin_lock(&bitmap->lock); - for (i = 0; i < cnt; i++) - clear_bit(obj + i, bitmap->table); - bitmap->last = min(bitmap->last, obj); - bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) - & bitmap->mask; + bitmap_clear(bitmap->table, obj, cnt); bitmap->avail += cnt; spin_unlock(&bitmap->lock); } @@ -166,12 +162,17 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved_bot, u32 reserved_top) { - int i; + /* sanity check */ + if (num <= (u64)reserved_top + reserved_bot) + return -EINVAL; /* num must be a power of 2 */ if (num != roundup_pow_of_two(num)) return -EINVAL; + if (reserved_bot + reserved_top >= num) + return -EINVAL; + bitmap->last = 0; bitmap->top = 0; bitmap->max = num - reserved_top; @@ -184,8 +185,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, if (!bitmap->table) return -ENOMEM; - for (i = 0; i < reserved_bot; ++i) - set_bit(i, bitmap->table); + bitmap_set(bitmap->table, 0, reserved_bot); return 0; } @@ -207,7 +207,6 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, { dma_addr_t t; - buf->direct.buf = NULL; if (size <= max_direct) { buf->nbufs = 1; buf->npages = 1; @@ -229,11 +228,10 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, int i; buf->direct.buf = NULL; - buf->direct.map = 0; buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; buf->npages = buf->nbufs; buf->page_shift = PAGE_SHIFT; - buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list, + buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list), GFP_KERNEL); if (!buf->page_list) return -ENOMEM; @@ -291,7 +289,6 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf) buf->page_list[i].map); kfree(buf->page_list); } - buf->direct.buf = NULL; } EXPORT_SYMBOL_GPL(mlx4_buf_free); |