|
@@ -1249,6 +1249,22 @@ static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void mlx4_ib_delete_counters_table(struct mlx4_ib_dev *ibdev,
|
|
|
+ struct mlx4_ib_counters *ctr_table)
|
|
|
+{
|
|
|
+ struct counter_index *counter, *tmp_count;
|
|
|
+
|
|
|
+ mutex_lock(&ctr_table->mutex);
|
|
|
+ list_for_each_entry_safe(counter, tmp_count, &ctr_table->counters_list,
|
|
|
+ list) {
|
|
|
+ if (counter->allocated)
|
|
|
+ mlx4_counter_free(ibdev->dev, counter->index);
|
|
|
+ list_del(&counter->list);
|
|
|
+ kfree(counter);
|
|
|
+ }
|
|
|
+ mutex_unlock(&ctr_table->mutex);
|
|
|
+}
|
|
|
+
|
|
|
int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
|
|
|
union ib_gid *gid)
|
|
|
{
|
|
@@ -2133,6 +2149,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
|
|
int num_req_counters;
|
|
|
int allocated;
|
|
|
u32 counter_index;
|
|
|
+ struct counter_index *new_counter_index = NULL;
|
|
|
|
|
|
pr_info_once("%s", mlx4_ib_version);
|
|
|
|
|
@@ -2304,6 +2321,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
|
|
if (init_node_data(ibdev))
|
|
|
goto err_map;
|
|
|
|
|
|
+ for (i = 0; i < ibdev->num_ports; ++i) {
|
|
|
+ mutex_init(&ibdev->counters_table[i].mutex);
|
|
|
+ INIT_LIST_HEAD(&ibdev->counters_table[i].counters_list);
|
|
|
+ }
|
|
|
+
|
|
|
num_req_counters = mlx4_is_bonded(dev) ? 1 : ibdev->num_ports;
|
|
|
for (i = 0; i < num_req_counters; ++i) {
|
|
|
mutex_init(&ibdev->qp1_proxy_lock[i]);
|
|
@@ -2322,15 +2344,34 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
|
|
counter_index = mlx4_get_default_counter_index(dev,
|
|
|
i + 1);
|
|
|
}
|
|
|
- ibdev->counters[i].index = counter_index;
|
|
|
- ibdev->counters[i].allocated = allocated;
|
|
|
+ new_counter_index = kmalloc(sizeof(*new_counter_index),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!new_counter_index) {
|
|
|
+ if (allocated)
|
|
|
+ mlx4_counter_free(ibdev->dev, counter_index);
|
|
|
+ goto err_counter;
|
|
|
+ }
|
|
|
+ new_counter_index->index = counter_index;
|
|
|
+ new_counter_index->allocated = allocated;
|
|
|
+ list_add_tail(&new_counter_index->list,
|
|
|
+ &ibdev->counters_table[i].counters_list);
|
|
|
+ ibdev->counters_table[i].default_counter = counter_index;
|
|
|
pr_info("counter index %d for port %d allocated %d\n",
|
|
|
counter_index, i + 1, allocated);
|
|
|
}
|
|
|
if (mlx4_is_bonded(dev))
|
|
|
for (i = 1; i < ibdev->num_ports ; ++i) {
|
|
|
- ibdev->counters[i].index = ibdev->counters[0].index;
|
|
|
- ibdev->counters[i].allocated = 0;
|
|
|
+ new_counter_index =
|
|
|
+ kmalloc(sizeof(struct counter_index),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!new_counter_index)
|
|
|
+ goto err_counter;
|
|
|
+ new_counter_index->index = counter_index;
|
|
|
+ new_counter_index->allocated = 0;
|
|
|
+ list_add_tail(&new_counter_index->list,
|
|
|
+ &ibdev->counters_table[i].counters_list);
|
|
|
+ ibdev->counters_table[i].default_counter =
|
|
|
+ counter_index;
|
|
|
}
|
|
|
|
|
|
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
|
|
@@ -2439,12 +2480,9 @@ err_steer_qp_release:
|
|
|
mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
|
|
|
ibdev->steer_qpn_count);
|
|
|
err_counter:
|
|
|
- for (i = 0; i < ibdev->num_ports; ++i) {
|
|
|
- if (ibdev->counters[i].index != -1 &&
|
|
|
- ibdev->counters[i].allocated)
|
|
|
- mlx4_counter_free(ibdev->dev,
|
|
|
- ibdev->counters[i].index);
|
|
|
- }
|
|
|
+ for (i = 0; i < ibdev->num_ports; ++i)
|
|
|
+ mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
|
|
|
+
|
|
|
err_map:
|
|
|
iounmap(ibdev->uar_map);
|
|
|
|
|
@@ -2548,9 +2586,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
|
|
|
|
|
|
iounmap(ibdev->uar_map);
|
|
|
for (p = 0; p < ibdev->num_ports; ++p)
|
|
|
- if (ibdev->counters[p].index != -1 &&
|
|
|
- ibdev->counters[p].allocated)
|
|
|
- mlx4_counter_free(ibdev->dev, ibdev->counters[p].index);
|
|
|
+ mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[p]);
|
|
|
+
|
|
|
mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
|
|
|
mlx4_CLOSE_PORT(dev, p);
|
|
|
|