aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4/alloc.c')
-rw-r--r--drivers/net/mlx4/alloc.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index 096bca54bcf7..e6c0d5bb5dcb 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -65,10 +65,82 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
65 65
66void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj) 66void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
67{ 67{
68 mlx4_bitmap_free_range(bitmap, obj, 1);
69}
70
71static unsigned long find_aligned_range(unsigned long *bitmap,
72 u32 start, u32 nbits,
73 int len, int align)
74{
75 unsigned long end, i;
76
77again:
78 start = ALIGN(start, align);
79
80 while ((start < nbits) && test_bit(start, bitmap))
81 start += align;
82
83 if (start >= nbits)
84 return -1;
85
86 end = start+len;
87 if (end > nbits)
88 return -1;
89
90 for (i = start + 1; i < end; i++) {
91 if (test_bit(i, bitmap)) {
92 start = i + 1;
93 goto again;
94 }
95 }
96
97 return start;
98}
99
100u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
101{
102 u32 obj, i;
103
104 if (likely(cnt == 1 && align == 1))
105 return mlx4_bitmap_alloc(bitmap);
106
107 spin_lock(&bitmap->lock);
108
109 obj = find_aligned_range(bitmap->table, bitmap->last,
110 bitmap->max, cnt, align);
111 if (obj >= bitmap->max) {
112 bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
113 obj = find_aligned_range(bitmap->table, 0,
114 bitmap->max,
115 cnt, align);
116 }
117
118 if (obj < bitmap->max) {
119 for (i = 0; i < cnt; i++)
120 set_bit(obj + i, bitmap->table);
121 if (obj == bitmap->last) {
122 bitmap->last = (obj + cnt);
123 if (bitmap->last >= bitmap->max)
124 bitmap->last = 0;
125 }
126 obj |= bitmap->top;
127 } else
128 obj = -1;
129
130 spin_unlock(&bitmap->lock);
131
132 return obj;
133}
134
135void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt)
136{
137 u32 i;
138
68 obj &= bitmap->max - 1; 139 obj &= bitmap->max - 1;
69 140
70 spin_lock(&bitmap->lock); 141 spin_lock(&bitmap->lock);
71 clear_bit(obj, bitmap->table); 142 for (i = 0; i < cnt; i++)
143 clear_bit(obj + i, bitmap->table);
72 bitmap->last = min(bitmap->last, obj); 144 bitmap->last = min(bitmap->last, obj);
73 bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask; 145 bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask;
74 spin_unlock(&bitmap->lock); 146 spin_unlock(&bitmap->lock);