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) |
