aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4/alloc.c
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2008-10-10 15:01:37 -0400
committerRoland Dreier <rolandd@cisco.com>2008-10-10 15:01:37 -0400
commita3cdcbfa8fb1fccfe48d359da86e99546610c562 (patch)
treea25715b6e9169568c53f80dc9333e024f389b383 /drivers/net/mlx4/alloc.c
parentf6bccf695431da0e9bd773550ae91b8cb9ffb227 (diff)
mlx4_core: Add QP range reservation support
To allow allocating an aligned range of consecutive QP numbers, add an interface to reserve an aligned range of QP numbers and have the QP allocation function always take a QP number. This will be used for RSS support in the mlx4_en Ethernet driver and also potentially by IPoIB RSS support. Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
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);