diff options
-rw-r--r-- | drivers/net/mlx4/mlx4.h | 1 | ||||
-rw-r--r-- | drivers/net/mlx4/mr.c | 26 |
2 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index a4023c2dd050..78038499cff5 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
@@ -118,6 +118,7 @@ struct mlx4_bitmap { | |||
118 | 118 | ||
119 | struct mlx4_buddy { | 119 | struct mlx4_buddy { |
120 | unsigned long **bits; | 120 | unsigned long **bits; |
121 | unsigned int *num_free; | ||
121 | int max_order; | 122 | int max_order; |
122 | spinlock_t lock; | 123 | spinlock_t lock; |
123 | }; | 124 | }; |
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index 03a9abcce524..b3ea93b98689 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c | |||
@@ -79,23 +79,26 @@ static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) | |||
79 | 79 | ||
80 | spin_lock(&buddy->lock); | 80 | spin_lock(&buddy->lock); |
81 | 81 | ||
82 | for (o = order; o <= buddy->max_order; ++o) { | 82 | for (o = order; o <= buddy->max_order; ++o) |
83 | m = 1 << (buddy->max_order - o); | 83 | if (buddy->num_free[o]) { |
84 | seg = find_first_bit(buddy->bits[o], m); | 84 | m = 1 << (buddy->max_order - o); |
85 | if (seg < m) | 85 | seg = find_first_bit(buddy->bits[o], m); |
86 | goto found; | 86 | if (seg < m) |
87 | } | 87 | goto found; |
88 | } | ||
88 | 89 | ||
89 | spin_unlock(&buddy->lock); | 90 | spin_unlock(&buddy->lock); |
90 | return -1; | 91 | return -1; |
91 | 92 | ||
92 | found: | 93 | found: |
93 | clear_bit(seg, buddy->bits[o]); | 94 | clear_bit(seg, buddy->bits[o]); |
95 | --buddy->num_free[o]; | ||
94 | 96 | ||
95 | while (o > order) { | 97 | while (o > order) { |
96 | --o; | 98 | --o; |
97 | seg <<= 1; | 99 | seg <<= 1; |
98 | set_bit(seg ^ 1, buddy->bits[o]); | 100 | set_bit(seg ^ 1, buddy->bits[o]); |
101 | ++buddy->num_free[o]; | ||
99 | } | 102 | } |
100 | 103 | ||
101 | spin_unlock(&buddy->lock); | 104 | spin_unlock(&buddy->lock); |
@@ -113,11 +116,13 @@ static void mlx4_buddy_free(struct mlx4_buddy *buddy, u32 seg, int order) | |||
113 | 116 | ||
114 | while (test_bit(seg ^ 1, buddy->bits[order])) { | 117 | while (test_bit(seg ^ 1, buddy->bits[order])) { |
115 | clear_bit(seg ^ 1, buddy->bits[order]); | 118 | clear_bit(seg ^ 1, buddy->bits[order]); |
119 | --buddy->num_free[order]; | ||
116 | seg >>= 1; | 120 | seg >>= 1; |
117 | ++order; | 121 | ++order; |
118 | } | 122 | } |
119 | 123 | ||
120 | set_bit(seg, buddy->bits[order]); | 124 | set_bit(seg, buddy->bits[order]); |
125 | ++buddy->num_free[order]; | ||
121 | 126 | ||
122 | spin_unlock(&buddy->lock); | 127 | spin_unlock(&buddy->lock); |
123 | } | 128 | } |
@@ -131,7 +136,9 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
131 | 136 | ||
132 | buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), | 137 | buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), |
133 | GFP_KERNEL); | 138 | GFP_KERNEL); |
134 | if (!buddy->bits) | 139 | buddy->num_free = kzalloc((buddy->max_order + 1) * sizeof (int *), |
140 | GFP_KERNEL); | ||
141 | if (!buddy->bits || !buddy->num_free) | ||
135 | goto err_out; | 142 | goto err_out; |
136 | 143 | ||
137 | for (i = 0; i <= buddy->max_order; ++i) { | 144 | for (i = 0; i <= buddy->max_order; ++i) { |
@@ -143,6 +150,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
143 | } | 150 | } |
144 | 151 | ||
145 | set_bit(0, buddy->bits[buddy->max_order]); | 152 | set_bit(0, buddy->bits[buddy->max_order]); |
153 | buddy->num_free[buddy->max_order] = 1; | ||
146 | 154 | ||
147 | return 0; | 155 | return 0; |
148 | 156 | ||
@@ -150,9 +158,10 @@ err_out_free: | |||
150 | for (i = 0; i <= buddy->max_order; ++i) | 158 | for (i = 0; i <= buddy->max_order; ++i) |
151 | kfree(buddy->bits[i]); | 159 | kfree(buddy->bits[i]); |
152 | 160 | ||
161 | err_out: | ||
153 | kfree(buddy->bits); | 162 | kfree(buddy->bits); |
163 | kfree(buddy->num_free); | ||
154 | 164 | ||
155 | err_out: | ||
156 | return -ENOMEM; | 165 | return -ENOMEM; |
157 | } | 166 | } |
158 | 167 | ||
@@ -164,6 +173,7 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) | |||
164 | kfree(buddy->bits[i]); | 173 | kfree(buddy->bits[i]); |
165 | 174 | ||
166 | kfree(buddy->bits); | 175 | kfree(buddy->bits); |
176 | kfree(buddy->num_free); | ||
167 | } | 177 | } |
168 | 178 | ||
169 | static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) | 179 | static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) |