IB/mlx4: Use flow counters on IBoE ports
authorOr Gerlitz <ogerlitz@mellanox.com>
Wed, 15 Jun 2011 14:49:57 +0000 (14:49 +0000)
committerRoland Dreier <roland@purestorage.com>
Tue, 19 Jul 2011 04:04:36 +0000 (21:04 -0700)
Allocate flow counter per Ethernet/IBoE port, and attach this counter
to all the QPs created on that port.  Based on patch by Eli Cohen
<eli@mellanox.co.il>.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.co.il>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
include/linux/mlx4/qp.h

index 621c409..fa643f4 100644 (file)
@@ -1098,11 +1098,21 @@ 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) {
+               if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
+                                               IB_LINK_LAYER_ETHERNET) {
+                       err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]);
+                       if (err)
+                               ibdev->counters[i] = -1;
+               } else
+                               ibdev->counters[i] = -1;
+       }
+
        spin_lock_init(&ibdev->sm_lock);
        mutex_init(&ibdev->cap_mask_mutex);
 
        if (ib_register_device(&ibdev->ib_dev, NULL))
-               goto err_map;
+               goto err_counter;
 
        if (mlx4_ib_mad_init(ibdev))
                goto err_reg;
@@ -1132,6 +1142,10 @@ err_notif:
 err_reg:
        ib_unregister_device(&ibdev->ib_dev);
 
+err_counter:
+       for (; i; --i)
+               mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]);
+
 err_map:
        iounmap(ibdev->uar_map);
 
@@ -1160,7 +1174,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
                ibdev->iboe.nb.notifier_call = NULL;
        }
        iounmap(ibdev->uar_map);
-
+       for (p = 0; p < ibdev->num_ports; ++p)
+               mlx4_counter_free(ibdev->dev, ibdev->counters[p]);
        mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
                mlx4_CLOSE_PORT(dev, p);
 
index 2a322f2..e4bf2cf 100644 (file)
@@ -193,6 +193,7 @@ struct mlx4_ib_dev {
        struct mutex            cap_mask_mutex;
        bool                    ib_active;
        struct mlx4_ib_iboe     iboe;
+       int                     counters[MLX4_MAX_PORTS];
 };
 
 static inline struct mlx4_ib_dev *to_mdev(struct ib_device *ibdev)
index 2001f20..3a91d9d 100644 (file)
@@ -893,7 +893,6 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
                        --path->static_rate;
        } else
                path->static_rate = 0;
-       path->counter_index = 0xff;
 
        if (ah->ah_flags & IB_AH_GRH) {
                if (ah->grh.sgid_index >= dev->dev->caps.gid_table_len[port]) {
@@ -1034,6 +1033,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                }
        }
 
+       if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
+               if (dev->counters[qp->port - 1] != -1) {
+                       context->pri_path.counter_index =
+                                               dev->counters[qp->port - 1];
+                       optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
+               } else
+                       context->pri_path.counter_index = 0xff;
+       }
+
        if (attr_mask & IB_QP_PKEY_INDEX) {
                context->pri_path.pkey_index = attr->pkey_index;
                optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
index 6486d88..4001c82 100644 (file)
@@ -54,7 +54,8 @@ enum mlx4_qp_optpar {
        MLX4_QP_OPTPAR_RETRY_COUNT              = 1 << 12,
        MLX4_QP_OPTPAR_RNR_RETRY                = 1 << 13,
        MLX4_QP_OPTPAR_ACK_TIMEOUT              = 1 << 14,
-       MLX4_QP_OPTPAR_SCHED_QUEUE              = 1 << 16
+       MLX4_QP_OPTPAR_SCHED_QUEUE              = 1 << 16,
+       MLX4_QP_OPTPAR_COUNTER_INDEX            = 1 << 20
 };
 
 enum mlx4_qp_state {