|
@@ -4952,26 +4952,41 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave)
|
|
|
struct res_counter *counter;
|
|
|
struct res_counter *tmp;
|
|
|
int err;
|
|
|
- int index;
|
|
|
+ int *counters_arr = NULL;
|
|
|
+ int i, j;
|
|
|
|
|
|
err = move_all_busy(dev, slave, RES_COUNTER);
|
|
|
if (err)
|
|
|
mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
|
|
|
slave);
|
|
|
|
|
|
- spin_lock_irq(mlx4_tlock(dev));
|
|
|
- list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
|
|
|
- if (counter->com.owner == slave) {
|
|
|
- index = counter->com.res_id;
|
|
|
- rb_erase(&counter->com.node,
|
|
|
- &tracker->res_tree[RES_COUNTER]);
|
|
|
- list_del(&counter->com.list);
|
|
|
- kfree(counter);
|
|
|
- __mlx4_counter_free(dev, index);
|
|
|
+ counters_arr = kmalloc_array(dev->caps.max_counters,
|
|
|
+ sizeof(*counters_arr), GFP_KERNEL);
|
|
|
+ if (!counters_arr)
|
|
|
+ return;
|
|
|
+
|
|
|
+ do {
|
|
|
+ i = 0;
|
|
|
+ j = 0;
|
|
|
+ spin_lock_irq(mlx4_tlock(dev));
|
|
|
+ list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
|
|
|
+ if (counter->com.owner == slave) {
|
|
|
+ counters_arr[i++] = counter->com.res_id;
|
|
|
+ rb_erase(&counter->com.node,
|
|
|
+ &tracker->res_tree[RES_COUNTER]);
|
|
|
+ list_del(&counter->com.list);
|
|
|
+ kfree(counter);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ spin_unlock_irq(mlx4_tlock(dev));
|
|
|
+
|
|
|
+ while (j < i) {
|
|
|
+ __mlx4_counter_free(dev, counters_arr[j++]);
|
|
|
mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
|
|
|
}
|
|
|
- }
|
|
|
- spin_unlock_irq(mlx4_tlock(dev));
|
|
|
+ } while (i);
|
|
|
+
|
|
|
+ kfree(counters_arr);
|
|
|
}
|
|
|
|
|
|
static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
|