All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo)
@ 2015-06-10 14:59 Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 01/13] net/mlx4_core: Check before cleaning counters bitmap Or Gerlitz
                   ` (12 more replies)
  0 siblings, 13 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Amir Vadai, Tal Alon, Or Gerlitz

Hi Dave,

This series from Eran and Hadar is further dealing with traffic 
counters in the mlx4 driver, this time mostly around SRIOV.

We added a new ndo to read the VF counters through the PF netdev 
netlink infrastructure plus mlx4 implementation for that ndo.

Or.

Eran Ben Elisha (13):
  net/mlx4_core: Check before cleaning counters bitmap
  net/mlx4_core: Reset counters data when freed
  net/mlx4_core: Add sink counter
  net/mlx4_core: Remove counters table allocation from VF flow
  net/mlx4_core: Adjust counter grant policy in the resource tracker
  net/mlx4_core: Add port attribute when tracking counters
  net/mlx4_core: Allocate default counter per port
  IB/mlx4: Add RoCE/IB dedicated counters
  IB/mlx4: Set VF to read from QP counters
  net/mlx4_core: Add helper to query counters
  net/mlx4_en: Show PF own statistics via ethtool
  net/core: Add reading VF statistics through the PF netdevice
  net/mlx4_en: Support ndo_get_vf_stats

 drivers/infiniband/hw/mlx4/mad.c                   |   38 ++---
 drivers/infiniband/hw/mlx4/main.c                  |   43 ++++--
 drivers/infiniband/hw/mlx4/mlx4_ib.h               |    7 +-
 drivers/infiniband/hw/mlx4/qp.c                    |    7 +-
 drivers/net/ethernet/mellanox/mlx4/cmd.c           |   86 ++++++++++
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c    |   17 ++
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |   23 +++-
 drivers/net/ethernet/mellanox/mlx4/en_port.c       |   24 +++-
 drivers/net/ethernet/mellanox/mlx4/en_resources.c  |    2 +-
 drivers/net/ethernet/mellanox/mlx4/main.c          |  134 ++++++++++++++--
 drivers/net/ethernet/mellanox/mlx4/mlx4.h          |    5 +
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h       |    2 +
 drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h    |   11 +-
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  |  173 +++++++++++++++++++-
 include/linux/mlx4/cmd.h                           |    6 +
 include/linux/mlx4/device.h                        |   10 +
 include/linux/netdevice.h                          |    4 +
 include/uapi/linux/if_link.h                       |   11 ++
 net/core/rtnetlink.c                               |   12 +-
 19 files changed, 545 insertions(+), 70 deletions(-)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH net-next 01/13] net/mlx4_core: Check before cleaning counters bitmap
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 02/13] net/mlx4_core: Reset counters data when freed Or Gerlitz
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

If counters are not supported by the device. The indices bitmap table is not
allocated during initialization. Add the symmetrical check before cleaning
the counters bitmap table or freeing a counter.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/main.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 0dbd704..f95466f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2204,6 +2204,9 @@ static int mlx4_init_counters_table(struct mlx4_dev *dev)
 
 static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
 {
+	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
+		return;
+
 	mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
 }
 
@@ -2241,6 +2244,9 @@ EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
 
 void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 {
+	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
+		return;
+
 	mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx, MLX4_USE_RR);
 	return;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 02/13] net/mlx4_core: Reset counters data when freed
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 01/13] net/mlx4_core: Check before cleaning counters bitmap Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 03/13] net/mlx4_core: Add sink counter Or Gerlitz
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Add resetting the counter data to the free counter flow, so the counter's
data won't be accessible anymore if querying the counter. Also, on next
counter allocation (to another VM for example), it will be fresh and clear.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/main.c |   21 +++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx4/mlx4.h |    2 ++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index f95466f..11f5568 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2242,11 +2242,32 @@ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 }
 EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
 
+static int __mlx4_clear_if_stat(struct mlx4_dev *dev,
+				u8 counter_index)
+{
+	struct mlx4_cmd_mailbox *if_stat_mailbox;
+	int err;
+	u32 if_stat_in_mod = (counter_index & 0xff) | MLX4_QUERY_IF_STAT_RESET;
+
+	if_stat_mailbox = mlx4_alloc_cmd_mailbox(dev);
+	if (IS_ERR(if_stat_mailbox))
+		return PTR_ERR(if_stat_mailbox);
+
+	err = mlx4_cmd_box(dev, 0, if_stat_mailbox->dma, if_stat_in_mod, 0,
+			   MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C,
+			   MLX4_CMD_NATIVE);
+
+	mlx4_free_cmd_mailbox(dev, if_stat_mailbox);
+	return err;
+}
+
 void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 {
 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
 		return;
 
+	__mlx4_clear_if_stat(dev, idx);
+
 	mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx, MLX4_USE_RR);
 	return;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index f424900..8d2d359 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -65,6 +65,8 @@
 
 #define INIT_HCA_TPT_MW_ENABLE          (1 << 7)
 
+#define MLX4_QUERY_IF_STAT_RESET	BIT(31)
+
 enum {
 	MLX4_HCR_BASE		= 0x80680,
 	MLX4_HCR_SIZE		= 0x0001c,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 03/13] net/mlx4_core: Add sink counter
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 01/13] net/mlx4_core: Check before cleaning counters bitmap Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 02/13] net/mlx4_core: Reset counters data when freed Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 04/13] net/mlx4_core: Remove counters table allocation from VF flow Or Gerlitz
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Reserve the last valid counter index for "sink" counter, when a
new counter cannot be allocated, the driver will use this counter.

In order to avoid allocating this counter on any other flow, fix the
indices bitmap allocation range, and reserve the sink counter index.

Add macro for the sink counter index and replace all appearences of the
index with the macro.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/infiniband/hw/mlx4/qp.c                   |    3 ++-
 drivers/net/ethernet/mellanox/mlx4/en_resources.c |    2 +-
 drivers/net/ethernet/mellanox/mlx4/main.c         |   11 +++++++----
 include/linux/mlx4/device.h                       |    1 +
 4 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 02fc91c..c7d916f 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1544,7 +1544,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
 						dev->counters[qp->port - 1];
 			optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
 		} else
-			context->pri_path.counter_index = 0xff;
+			context->pri_path.counter_index =
+				MLX4_SINK_COUNTER_INDEX(dev->dev);
 
 		if (qp->flags & MLX4_IB_QP_NETIF) {
 			mlx4_ib_steer_qp_reg(dev, qp, 1);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
index 34f2fdf..97bcb91 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -66,7 +66,7 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 		context->pri_path.sched_queue |= user_prio << 3;
 		context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP;
 	}
-	context->pri_path.counter_index = 0xff;
+	context->pri_path.counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
 	context->cqn_send = cpu_to_be32(cqn);
 	context->cqn_recv = cpu_to_be32(cqn);
 	context->db_rec_addr = cpu_to_be64(priv->res.db.dma << 2);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 11f5568..9c1b8b0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -479,7 +479,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 		}
 	}
 
-	dev->caps.max_counters = 1 << ilog2(dev_cap->max_counters);
+	dev->caps.max_counters = dev_cap->max_counters;
 
 	dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps;
 	dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] =
@@ -2193,13 +2193,16 @@ err_free_icm:
 static int mlx4_init_counters_table(struct mlx4_dev *dev)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
-	int nent;
+	int nent_pow2;
 
 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
 		return -ENOENT;
 
-	nent = dev->caps.max_counters;
-	return mlx4_bitmap_init(&priv->counters_bitmap, nent, nent - 1, 0, 0);
+	nent_pow2 = roundup_pow_of_two(dev->caps.max_counters);
+	/* reserve last counter index for sink counter */
+	return mlx4_bitmap_init(&priv->counters_bitmap, nent_pow2,
+				nent_pow2 - 1, 0,
+				nent_pow2 - dev->caps.max_counters + 1);
 }
 
 static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index ad31e47..312c504 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -957,6 +957,7 @@ struct mlx4_mad_ifc {
 			((dev)->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
 
 #define MLX4_INVALID_SLAVE_ID	0xFF
+#define MLX4_SINK_COUNTER_INDEX(dev)	(dev->caps.max_counters - 1)
 
 void handle_port_mgmt_change_event(struct work_struct *work);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 04/13] net/mlx4_core: Remove counters table allocation from VF flow
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (2 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 03/13] net/mlx4_core: Add sink counter Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 05/13] net/mlx4_core: Adjust counter grant policy in the resource tracker Or Gerlitz
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Since virtual functions get their counters indices allocation from the PF,
allocate counters indices bitmap only in case the function isn't virtual.

Also, check that the device has counters to allocate before creating the
indices bitmap table.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/main.c |   25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 9c1b8b0..c3fe49e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2198,6 +2198,9 @@ static int mlx4_init_counters_table(struct mlx4_dev *dev)
 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
 		return -ENOENT;
 
+	if (!dev->caps.max_counters)
+		return -ENOSPC;
+
 	nent_pow2 = roundup_pow_of_two(dev->caps.max_counters);
 	/* reserve last counter index for sink counter */
 	return mlx4_bitmap_init(&priv->counters_bitmap, nent_pow2,
@@ -2210,6 +2213,9 @@ static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
 		return;
 
+	if (!dev->caps.max_counters)
+		return;
+
 	mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
 }
 
@@ -2425,10 +2431,12 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 		goto err_srq_table_free;
 	}
 
-	err = mlx4_init_counters_table(dev);
-	if (err && err != -ENOENT) {
-		mlx4_err(dev, "Failed to initialize counters table, aborting\n");
-		goto err_qp_table_free;
+	if (!mlx4_is_slave(dev)) {
+		err = mlx4_init_counters_table(dev);
+		if (err && err != -ENOENT) {
+			mlx4_err(dev, "Failed to initialize counters table, aborting\n");
+			goto err_qp_table_free;
+		}
 	}
 
 	if (!mlx4_is_slave(dev)) {
@@ -2470,7 +2478,8 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 	return 0;
 
 err_counters_table_free:
-	mlx4_cleanup_counters_table(dev);
+	if (!mlx4_is_slave(dev))
+		mlx4_cleanup_counters_table(dev);
 
 err_qp_table_free:
 	mlx4_cleanup_qp_table(dev);
@@ -3201,7 +3210,8 @@ err_port:
 	for (--port; port >= 1; --port)
 		mlx4_cleanup_port_info(&priv->port[port]);
 
-	mlx4_cleanup_counters_table(dev);
+	if (!mlx4_is_slave(dev))
+		mlx4_cleanup_counters_table(dev);
 	mlx4_cleanup_qp_table(dev);
 	mlx4_cleanup_srq_table(dev);
 	mlx4_cleanup_cq_table(dev);
@@ -3499,7 +3509,8 @@ static void mlx4_unload_one(struct pci_dev *pdev)
 		mlx4_free_resource_tracker(dev,
 					   RES_TR_FREE_SLAVES_ONLY);
 
-	mlx4_cleanup_counters_table(dev);
+	if (!mlx4_is_slave(dev))
+		mlx4_cleanup_counters_table(dev);
 	mlx4_cleanup_qp_table(dev);
 	mlx4_cleanup_srq_table(dev);
 	mlx4_cleanup_cq_table(dev);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 05/13] net/mlx4_core: Adjust counter grant policy in the resource tracker
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (3 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 04/13] net/mlx4_core: Remove counters table allocation from VF flow Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 06/13] net/mlx4_core: Add port attribute when tracking counters Or Gerlitz
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Each physical function has a guarantee of two counters per port, one
for a default counter and one for the IB driver.

Each virtual function has a guarantee of one counter per port.
All other counters are free and can be obtained on demand.

This is a preparation step for supporting a get_vf_stats ndo call,
so we can promise a counter for every VF in order to collect their
statistics from the PF context.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  |   35 +++++++++++++++++--
 1 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index ab48386..802eb2a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -48,6 +48,8 @@
 #include "fw.h"
 
 #define MLX4_MAC_VALID		(1ull << 63)
+#define MLX4_PF_COUNTERS_PER_PORT	2
+#define MLX4_VF_COUNTERS_PER_PORT	1
 
 struct mac_res {
 	struct list_head list;
@@ -459,11 +461,21 @@ void mlx4_init_quotas(struct mlx4_dev *dev)
 	dev->quotas.mpt =
 		priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
 }
+
+static int get_max_gauranteed_vfs_counter(struct mlx4_dev *dev)
+{
+	/* reduce the sink counter */
+	return (dev->caps.max_counters - 1 -
+		(MLX4_PF_COUNTERS_PER_PORT * MLX4_MAX_PORTS))
+		/ MLX4_MAX_PORTS;
+}
+
 int mlx4_init_resource_tracker(struct mlx4_dev *dev)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	int i, j;
 	int t;
+	int max_vfs_guarantee_counter = get_max_gauranteed_vfs_counter(dev);
 
 	priv->mfunc.master.res_tracker.slave_list =
 		kzalloc(dev->num_slaves * sizeof(struct slave_list),
@@ -499,6 +511,9 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
 			res_alloc->allocated = kzalloc((dev->persist->
 							num_vfs + 1) *
 						       sizeof(int), GFP_KERNEL);
+		/* Reduce the sink counter */
+		if (i == RES_COUNTER)
+			res_alloc->res_free = dev->caps.max_counters - 1;
 
 		if (!res_alloc->quota || !res_alloc->guaranteed ||
 		    !res_alloc->allocated)
@@ -577,9 +592,17 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
 				break;
 			case RES_COUNTER:
 				res_alloc->quota[t] = dev->caps.max_counters;
-				res_alloc->guaranteed[t] = 0;
 				if (t == mlx4_master_func_num(dev))
-					res_alloc->res_free = res_alloc->quota[t];
+					res_alloc->guaranteed[t] =
+						MLX4_PF_COUNTERS_PER_PORT *
+						MLX4_MAX_PORTS;
+				else if (t <= max_vfs_guarantee_counter)
+					res_alloc->guaranteed[t] =
+						MLX4_VF_COUNTERS_PER_PORT *
+						MLX4_MAX_PORTS;
+				else
+					res_alloc->guaranteed[t] = 0;
+				res_alloc->res_free -= res_alloc->guaranteed[t];
 				break;
 			default:
 				break;
@@ -952,7 +975,7 @@ static struct res_common *alloc_srq_tr(int id)
 	return &ret->com;
 }
 
-static struct res_common *alloc_counter_tr(int id)
+static struct res_common *alloc_counter_tr(int id, int port)
 {
 	struct res_counter *ret;
 
@@ -962,6 +985,7 @@ static struct res_common *alloc_counter_tr(int id)
 
 	ret->com.res_id = id;
 	ret->com.state = RES_COUNTER_ALLOCATED;
+	ret->port = port;
 
 	return &ret->com;
 }
@@ -1022,7 +1046,7 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
 		pr_err("implementation missing\n");
 		return NULL;
 	case RES_COUNTER:
-		ret = alloc_counter_tr(id);
+		ret = alloc_counter_tr(id, extra);
 		break;
 	case RES_XRCD:
 		ret = alloc_xrcdn_tr(id);
@@ -2335,6 +2359,9 @@ static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
 		return -EINVAL;
 
 	index = get_param_l(&in_param);
+	if (index == MLX4_SINK_COUNTER_INDEX(dev))
+		return 0;
+
 	err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0);
 	if (err)
 		return err;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 06/13] net/mlx4_core: Add port attribute when tracking counters
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (4 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 05/13] net/mlx4_core: Adjust counter grant policy in the resource tracker Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 07/13] net/mlx4_core: Allocate default counter per port Or Gerlitz
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Counter will get its port attribute within the resource tracker when
the first QP attached to it is modified to RTR. If a QP is counter-less,
an attempt to create a new counter with assigned port will be made.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  |   90 +++++++++++++++++++-
 1 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 802eb2a..73db584 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -723,6 +723,9 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
 	}
 }
 
+static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
+			  u8 slave, int port);
+
 static int update_vport_qp_param(struct mlx4_dev *dev,
 				 struct mlx4_cmd_mailbox *inbox,
 				 u8 slave, u32 qpn)
@@ -738,6 +741,10 @@ static int update_vport_qp_param(struct mlx4_dev *dev,
 	vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
 	qp_type	= (be32_to_cpu(qpc->flags) >> 16) & 0xff;
 
+	err = handle_counter(dev, qpc, slave, port);
+	if (err)
+		goto out;
+
 	if (MLX4_VGT != vp_oper->state.default_vlan) {
 		/* the reserved QPs (special, proxy, tunnel)
 		 * do not operate over vlans
@@ -882,6 +889,83 @@ static void put_res(struct mlx4_dev *dev, int slave, u64 res_id,
 	spin_unlock_irq(mlx4_tlock(dev));
 }
 
+static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
+			     u64 in_param, u64 *out_param, int port);
+
+static int handle_existing_counter(struct mlx4_dev *dev, u8 slave, int port,
+				   int counter_index)
+{
+	struct res_common *r;
+	struct res_counter *counter;
+	int ret = 0;
+
+	if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
+		return ret;
+
+	spin_lock_irq(mlx4_tlock(dev));
+	r = find_res(dev, counter_index, RES_COUNTER);
+	if (!r || r->owner != slave)
+		ret = -EINVAL;
+	counter = container_of(r, struct res_counter, com);
+	if (!counter->port)
+		counter->port = port;
+
+	spin_unlock_irq(mlx4_tlock(dev));
+	return ret;
+}
+
+static int handle_unexisting_counter(struct mlx4_dev *dev,
+				     struct mlx4_qp_context *qpc, u8 slave,
+				     int port)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
+	struct res_common *tmp;
+	struct res_counter *counter;
+	u64 counter_idx = MLX4_SINK_COUNTER_INDEX(dev);
+	int err = 0;
+
+	spin_lock_irq(mlx4_tlock(dev));
+	list_for_each_entry(tmp,
+			    &tracker->slave_list[slave].res_list[RES_COUNTER],
+			    list) {
+		counter = container_of(tmp, struct res_counter, com);
+		if (port == counter->port) {
+			qpc->pri_path.counter_index  = counter->com.res_id;
+			spin_unlock_irq(mlx4_tlock(dev));
+			return 0;
+		}
+	}
+	spin_unlock_irq(mlx4_tlock(dev));
+
+	/* No existing counter, need to allocate a new counter */
+	err = counter_alloc_res(dev, slave, RES_OP_RESERVE, 0, 0, &counter_idx,
+				port);
+	if (err == -ENOENT) {
+		err = 0;
+	} else if (err && err != -ENOSPC) {
+		mlx4_err(dev, "%s: failed to create new counter for slave %d err %d\n",
+			 __func__, slave, err);
+	} else {
+		qpc->pri_path.counter_index = counter_idx;
+		mlx4_dbg(dev, "%s: alloc new counter for slave %d index %d\n",
+			 __func__, slave, qpc->pri_path.counter_index);
+		err = 0;
+	}
+
+	return err;
+}
+
+static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
+			  u8 slave, int port)
+{
+	if (qpc->pri_path.counter_index != MLX4_SINK_COUNTER_INDEX(dev))
+		return handle_existing_counter(dev, slave, port,
+					       qpc->pri_path.counter_index);
+
+	return handle_unexisting_counter(dev, qpc, slave, port);
+}
+
 static struct res_common *alloc_qp_tr(int id)
 {
 	struct res_qp *ret;
@@ -2025,7 +2109,7 @@ static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
 }
 
 static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
-			     u64 in_param, u64 *out_param)
+			     u64 in_param, u64 *out_param, int port)
 {
 	u32 index;
 	int err;
@@ -2043,7 +2127,7 @@ static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
 		return err;
 	}
 
-	err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0);
+	err = add_res_range(dev, slave, index, 1, RES_COUNTER, port);
 	if (err) {
 		__mlx4_counter_free(dev, index);
 		mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
@@ -2125,7 +2209,7 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
 
 	case RES_COUNTER:
 		err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop,
-					vhcr->in_param, &vhcr->out_param);
+					vhcr->in_param, &vhcr->out_param, 0);
 		break;
 
 	case RES_XRCD:
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 07/13] net/mlx4_core: Allocate default counter per port
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (5 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 06/13] net/mlx4_core: Add port attribute when tracking counters Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 08/13] IB/mlx4: Add RoCE/IB dedicated counters Or Gerlitz
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Default counter per port will be allocated at the mlx4 core driver load.

Every QP opened by the Ethernet driver will be attached to the port's default
counter.  This is an infrastructure step to collect VF statistics from the PF.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c    |    5 ++
 drivers/net/ethernet/mellanox/mlx4/en_resources.c |    2 +-
 drivers/net/ethernet/mellanox/mlx4/main.c         |   71 ++++++++++++++++++++-
 drivers/net/ethernet/mellanox/mlx4/mlx4.h         |    1 +
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h      |    1 +
 include/linux/mlx4/device.h                       |    1 +
 6 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 98efb58..048fca0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1597,6 +1597,9 @@ int mlx4_en_start_port(struct net_device *dev)
 	}
 	mdev->mac_removed[priv->port] = 0;
 
+	priv->counter_index =
+			mlx4_get_default_counter_index(mdev->dev, priv->port);
+
 	err = mlx4_en_config_rss_steer(priv);
 	if (err) {
 		en_err(priv, "Failed configuring rss steering\n");
@@ -1755,6 +1758,7 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
 
 	/* Set port as not active */
 	priv->port_up = false;
+	priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
 
 	/* Promsicuous mode */
 	if (mdev->dev->caps.steering_mode ==
@@ -2778,6 +2782,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 
 	priv = netdev_priv(dev);
 	memset(priv, 0, sizeof(struct mlx4_en_priv));
+	priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
 	spin_lock_init(&priv->stats_lock);
 	INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
 	INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
index 97bcb91..e482fa1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -66,7 +66,7 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 		context->pri_path.sched_queue |= user_prio << 3;
 		context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP;
 	}
-	context->pri_path.counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev);
+	context->pri_path.counter_index = priv->counter_index;
 	context->cqn_send = cpu_to_be32(cqn);
 	context->cqn_recv = cpu_to_be32(cqn);
 	context->db_rec_addr = cpu_to_be64(priv->res.db.dma << 2);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index c3fe49e..3d0de27 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2219,6 +2219,47 @@ static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
 	mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
 }
 
+static void mlx4_cleanup_default_counters(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int port;
+
+	for (port = 0; port < dev->caps.num_ports; port++)
+		if (priv->def_counter[port] != -1)
+			mlx4_counter_free(dev,  priv->def_counter[port]);
+}
+
+static int mlx4_allocate_default_counters(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int port, err = 0;
+	u32 idx;
+
+	for (port = 0; port < dev->caps.num_ports; port++)
+		priv->def_counter[port] = -1;
+
+	for (port = 0; port < dev->caps.num_ports; port++) {
+		err = mlx4_counter_alloc(dev, &idx);
+
+		if (!err || err == -ENOSPC) {
+			priv->def_counter[port] = idx;
+		} else if (err == -ENOENT) {
+			err = 0;
+			continue;
+		} else {
+			mlx4_err(dev, "%s: failed to allocate default counter port %d err %d\n",
+				 __func__, port + 1, err);
+			mlx4_cleanup_default_counters(dev);
+			return err;
+		}
+
+		mlx4_dbg(dev, "%s: default counter index %d for port %d\n",
+			 __func__, priv->def_counter[port], port + 1);
+	}
+
+	return err;
+}
+
 int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
@@ -2227,8 +2268,10 @@ int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
 		return -ENOENT;
 
 	*idx = mlx4_bitmap_alloc(&priv->counters_bitmap);
-	if (*idx == -1)
-		return -ENOMEM;
+	if (*idx == -1) {
+		*idx = MLX4_SINK_COUNTER_INDEX(dev);
+		return -ENOSPC;
+	}
 
 	return 0;
 }
@@ -2275,6 +2318,9 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 	if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS))
 		return;
 
+	if (idx == MLX4_SINK_COUNTER_INDEX(dev))
+		return;
+
 	__mlx4_clear_if_stat(dev, idx);
 
 	mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx, MLX4_USE_RR);
@@ -2296,6 +2342,14 @@ void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 }
 EXPORT_SYMBOL_GPL(mlx4_counter_free);
 
+int mlx4_get_default_counter_index(struct mlx4_dev *dev, int port)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+
+	return priv->def_counter[port - 1];
+}
+EXPORT_SYMBOL_GPL(mlx4_get_default_counter_index);
+
 void mlx4_set_admin_guid(struct mlx4_dev *dev, __be64 guid, int entry, int port)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
@@ -2439,6 +2493,12 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 		}
 	}
 
+	err = mlx4_allocate_default_counters(dev);
+	if (err) {
+		mlx4_err(dev, "Failed to allocate default counters, aborting\n");
+		goto err_counters_table_free;
+	}
+
 	if (!mlx4_is_slave(dev)) {
 		for (port = 1; port <= dev->caps.num_ports; port++) {
 			ib_port_default_caps = 0;
@@ -2470,13 +2530,16 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 			if (err) {
 				mlx4_err(dev, "Failed to set port %d, aborting\n",
 					 port);
-				goto err_counters_table_free;
+				goto err_default_countes_free;
 			}
 		}
 	}
 
 	return 0;
 
+err_default_countes_free:
+	mlx4_cleanup_default_counters(dev);
+
 err_counters_table_free:
 	if (!mlx4_is_slave(dev))
 		mlx4_cleanup_counters_table(dev);
@@ -3210,6 +3273,7 @@ err_port:
 	for (--port; port >= 1; --port)
 		mlx4_cleanup_port_info(&priv->port[port]);
 
+	mlx4_cleanup_default_counters(dev);
 	if (!mlx4_is_slave(dev))
 		mlx4_cleanup_counters_table(dev);
 	mlx4_cleanup_qp_table(dev);
@@ -3509,6 +3573,7 @@ static void mlx4_unload_one(struct pci_dev *pdev)
 		mlx4_free_resource_tracker(dev,
 					   RES_TR_FREE_SLAVES_ONLY);
 
+	mlx4_cleanup_default_counters(dev);
 	if (!mlx4_is_slave(dev))
 		mlx4_cleanup_counters_table(dev);
 	mlx4_cleanup_qp_table(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 8d2d359..e9e94bc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -876,6 +876,7 @@ struct mlx4_priv {
 	struct mlx4_qp_table	qp_table;
 	struct mlx4_mcg_table	mcg_table;
 	struct mlx4_bitmap	counters_bitmap;
+	int			def_counter[MLX4_MAX_PORTS];
 
 	struct mlx4_catas_err	catas_err;
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index edd8fd6..f6c3e12 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -582,6 +582,7 @@ struct mlx4_en_priv {
 	int base_tx_qpn;
 	struct hlist_head mac_hash[MLX4_EN_MAC_HASH_SIZE];
 	struct hwtstamp_config hwtstamp_config;
+	u32 counter_index;
 
 #ifdef CONFIG_MLX4_EN_DCB
 	struct ieee_ets ets;
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 312c504..4820080 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1348,6 +1348,7 @@ int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port);
 
 int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
 void mlx4_counter_free(struct mlx4_dev *dev, u32 idx);
+int mlx4_get_default_counter_index(struct mlx4_dev *dev, int port);
 
 void mlx4_set_admin_guid(struct mlx4_dev *dev, __be64 guid, int entry,
 			 int port);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 08/13] IB/mlx4: Add RoCE/IB dedicated counters
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (6 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 07/13] net/mlx4_core: Allocate default counter per port Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 09/13] IB/mlx4: Set VF to read from QP counters Or Gerlitz
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

This is an infrastructure step to attach all the QPs opened from the
IB driver to a counter in order to collect VF stats from the PF using
those counters.

If the port's type is Ethernet, the counter policy demands two counters
per port (one for RoCE and one for Ethernet). The port default counter
(allocated in mlx4_core) is used for the Ethernet netdev QPs and we
allocate another counter for RoCE.

If the port's traffic is Infiniband, the counter policy demands
one counter per port, so it can use the port's default counter.

Also, Add 'allocated' flag for each counter in order to clean it at
unload.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/infiniband/hw/mlx4/mad.c     |    2 +-
 drivers/infiniband/hw/mlx4/main.c    |   43 +++++++++++++++++++++++----------
 drivers/infiniband/hw/mlx4/mlx4_ib.h |    7 ++++-
 drivers/infiniband/hw/mlx4/qp.c      |    4 +-
 4 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index ad6a881..74ca13f 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -831,7 +831,7 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_ib_dev *dev = to_mdev(ibdev);
 	int err;
-	u32 inmod = dev->counters[port_num - 1] & 0xffff;
+	u32 inmod = dev->counters[port_num - 1].index & 0xffff;
 	u8 mode;
 
 	if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 024b0f7..b6bd217 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -2098,6 +2098,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
 	struct mlx4_ib_iboe *iboe;
 	int ib_num_ports = 0;
 	int num_req_counters;
+	int allocated;
+	u32 counter_index;
 
 	pr_info_once("%s", mlx4_ib_version);
 
@@ -2263,19 +2265,31 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
 	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]);
+		allocated = 0;
 		if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
 						IB_LINK_LAYER_ETHERNET) {
-			err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]);
+			err = mlx4_counter_alloc(ibdev->dev, &counter_index);
+			/* if failed to allocate a new counter, use default */
 			if (err)
-				ibdev->counters[i] = -1;
-		} else {
-			ibdev->counters[i] = -1;
+				counter_index =
+					mlx4_get_default_counter_index(dev,
+								       i + 1);
+			else
+				allocated = 1;
+		} else { /* IB_LINK_LAYER_INFINIBAND use the default counter */
+			counter_index = mlx4_get_default_counter_index(dev,
+								       i + 1);
 		}
+		ibdev->counters[i].index = counter_index;
+		ibdev->counters[i].allocated = allocated;
+		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] = ibdev->counters[0];
-
+		for (i = 1; i < ibdev->num_ports ; ++i) {
+			ibdev->counters[i].index = ibdev->counters[0].index;
+			ibdev->counters[i].allocated = 0;
+		}
 
 	mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
 		ib_num_ports++;
@@ -2415,10 +2429,12 @@ err_steer_qp_release:
 		mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
 				      ibdev->steer_qpn_count);
 err_counter:
-	for (; i; --i)
-		if (ibdev->counters[i - 1] != -1)
-			mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]);
-
+	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);
+	}
 err_map:
 	iounmap(ibdev->uar_map);
 
@@ -2535,8 +2551,9 @@ 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] != -1)
-			mlx4_counter_free(ibdev->dev, ibdev->counters[p]);
+		if (ibdev->counters[p].index != -1 &&
+		    ibdev->counters[p].allocated)
+			mlx4_counter_free(ibdev->dev, ibdev->counters[p].index);
 	mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
 		mlx4_CLOSE_PORT(dev, p);
 
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index ef80e6c..b3912d1 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -503,6 +503,11 @@ struct mlx4_ib_iov_port {
 	struct mlx4_ib_iov_sysfs_attr mcg_dentry;
 };
 
+struct counter_index {
+	u32		index;
+	u8		allocated;
+};
+
 struct mlx4_ib_dev {
 	struct ib_device	ib_dev;
 	struct mlx4_dev	       *dev;
@@ -521,7 +526,7 @@ struct mlx4_ib_dev {
 	struct mutex		cap_mask_mutex;
 	bool			ib_active;
 	struct mlx4_ib_iboe	iboe;
-	int			counters[MLX4_MAX_PORTS];
+	struct counter_index    counters[MLX4_MAX_PORTS];
 	int		       *eq_table;
 	struct kobject	       *iov_parent;
 	struct kobject	       *ports_parent;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index c7d916f..c5a3a5f 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1539,9 +1539,9 @@ 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) {
+		if (dev->counters[qp->port - 1].index != -1) {
 			context->pri_path.counter_index =
-						dev->counters[qp->port - 1];
+					dev->counters[qp->port - 1].index;
 			optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
 		} else
 			context->pri_path.counter_index =
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 09/13] IB/mlx4: Set VF to read from QP counters
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (7 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 08/13] IB/mlx4: Add RoCE/IB dedicated counters Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 10/13] net/mlx4_core: Add helper to query counters Or Gerlitz
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

As IB VFs are not capable to read the port counters through MADs,
move there to read their own QP counters to gather statistics.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/infiniband/hw/mlx4/mad.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 74ca13f..bc698b1 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -869,10 +869,12 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
 			struct ib_wc *in_wc, struct ib_grh *in_grh,
 			struct ib_mad *in_mad, struct ib_mad *out_mad)
 {
+	struct mlx4_ib_dev *dev = to_mdev(ibdev);
 	switch (rdma_port_get_link_layer(ibdev, port_num)) {
 	case IB_LINK_LAYER_INFINIBAND:
-		return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
-				      in_grh, in_mad, out_mad);
+		if (!mlx4_is_slave(dev->dev))
+			return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
+					      in_grh, in_mad, out_mad);
 	case IB_LINK_LAYER_ETHERNET:
 		return iboe_process_mad(ibdev, mad_flags, port_num, in_wc,
 					  in_grh, in_mad, out_mad);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 10/13] net/mlx4_core: Add helper to query counters
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (8 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 09/13] IB/mlx4: Set VF to read from QP counters Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 11/13] net/mlx4_en: Show PF own statistics via ethtool Or Gerlitz
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

This is an infrastructure step for querying VF and PF counters.

This code was in the IB driver, move it to the mlx4 core driver
so it will be accessible for more use cases.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/infiniband/hw/mlx4/mad.c         |   32 ++++------------
 drivers/net/ethernet/mellanox/mlx4/cmd.c |   57 ++++++++++++++++++++++++++++++
 include/linux/mlx4/cmd.h                 |    3 ++
 include/linux/mlx4/device.h              |    8 ++++
 4 files changed, 76 insertions(+), 24 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index bc698b1..bc09b4e 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -64,14 +64,6 @@ enum {
 #define GUID_TBL_BLK_NUM_ENTRIES 8
 #define GUID_TBL_BLK_SIZE (GUID_TBL_ENTRY_SIZE * GUID_TBL_BLK_NUM_ENTRIES)
 
-/* Counters should be saturate once they reach their maximum value */
-#define ASSIGN_32BIT_COUNTER(counter, value) do {\
-	if ((value) > U32_MAX)			 \
-		counter = cpu_to_be32(U32_MAX); \
-	else					 \
-		counter = cpu_to_be32(value);	 \
-} while (0)
-
 struct mlx4_mad_rcv_buf {
 	struct ib_grh grh;
 	u8 payload[256];
@@ -828,31 +820,25 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
 			struct ib_wc *in_wc, struct ib_grh *in_grh,
 			struct ib_mad *in_mad, struct ib_mad *out_mad)
 {
-	struct mlx4_cmd_mailbox *mailbox;
+	struct mlx4_counter counter_stats;
 	struct mlx4_ib_dev *dev = to_mdev(ibdev);
 	int err;
-	u32 inmod = dev->counters[port_num - 1].index & 0xffff;
-	u8 mode;
 
 	if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
 		return -EINVAL;
 
-	mailbox = mlx4_alloc_cmd_mailbox(dev->dev);
-	if (IS_ERR(mailbox))
-		return IB_MAD_RESULT_FAILURE;
-
-	err = mlx4_cmd_box(dev->dev, 0, mailbox->dma, inmod, 0,
-			   MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C,
-			   MLX4_CMD_WRAPPED);
+	memset(&counter_stats, 0, sizeof(counter_stats));
+	err = mlx4_get_counter_stats(dev->dev,
+				     dev->counters[port_num - 1].index,
+				     &counter_stats, 0);
 	if (err)
 		err = IB_MAD_RESULT_FAILURE;
 	else {
 		memset(out_mad->data, 0, sizeof out_mad->data);
-		mode = ((struct mlx4_counter *)mailbox->buf)->counter_mode;
-		switch (mode & 0xf) {
+		switch (counter_stats.counter_mode & 0xf) {
 		case 0:
-			edit_counter(mailbox->buf,
-						(void *)(out_mad->data + 40));
+			edit_counter(&counter_stats,
+				     (void *)(out_mad->data + 40));
 			err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
 			break;
 		default:
@@ -860,8 +846,6 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
 		}
 	}
 
-	mlx4_free_cmd_mailbox(dev->dev, mailbox);
-
 	return err;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 91d8344..4495bbd 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -49,6 +49,7 @@
 #include "mlx4.h"
 #include "fw.h"
 #include "fw_qos.h"
+#include "mlx4_stats.h"
 
 #define CMD_POLL_TOKEN 0xffff
 #define INBOX_MASK	0xffffffffffffff00ULL
@@ -3166,6 +3167,62 @@ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_stat
 }
 EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
 
+int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
+			   struct mlx4_counter *counter_stats, int reset)
+{
+	struct mlx4_cmd_mailbox *mailbox = NULL;
+	struct mlx4_counter *tmp_counter;
+	int err;
+	u32 if_stat_in_mod;
+
+	if (!counter_stats)
+		return -EINVAL;
+
+	if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
+		return 0;
+
+	mailbox = mlx4_alloc_cmd_mailbox(dev);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+
+	memset(mailbox->buf, 0, sizeof(struct mlx4_counter));
+	if_stat_in_mod = counter_index;
+	if (reset)
+		if_stat_in_mod |= MLX4_QUERY_IF_STAT_RESET;
+	err = mlx4_cmd_box(dev, 0, mailbox->dma,
+			   if_stat_in_mod, 0,
+			   MLX4_CMD_QUERY_IF_STAT,
+			   MLX4_CMD_TIME_CLASS_C,
+			   MLX4_CMD_NATIVE);
+	if (err) {
+		mlx4_dbg(dev, "%s: failed to read statistics for counter index %d\n",
+			 __func__, counter_index);
+		goto if_stat_out;
+	}
+	tmp_counter = (struct mlx4_counter *)mailbox->buf;
+	counter_stats->counter_mode = tmp_counter->counter_mode;
+	if (counter_stats->counter_mode == 0) {
+		counter_stats->rx_frames =
+			cpu_to_be64(be64_to_cpu(counter_stats->rx_frames) +
+				    be64_to_cpu(tmp_counter->rx_frames));
+		counter_stats->tx_frames =
+			cpu_to_be64(be64_to_cpu(counter_stats->tx_frames) +
+				    be64_to_cpu(tmp_counter->tx_frames));
+		counter_stats->rx_bytes =
+			cpu_to_be64(be64_to_cpu(counter_stats->rx_bytes) +
+				    be64_to_cpu(tmp_counter->rx_bytes));
+		counter_stats->tx_bytes =
+			cpu_to_be64(be64_to_cpu(counter_stats->tx_bytes) +
+				    be64_to_cpu(tmp_counter->tx_bytes));
+	}
+
+if_stat_out:
+	mlx4_free_cmd_mailbox(dev, mailbox);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
+
 int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index f62e7cf..5dffc86 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -35,6 +35,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/if_link.h>
+#include <linux/mlx4/device.h>
 
 enum {
 	/* initialization and general commands */
@@ -300,6 +301,8 @@ static inline int mlx4_cmd_imm(struct mlx4_dev *dev, u64 in_param, u64 *out_para
 struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev);
 void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox);
 
+int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
+			   struct mlx4_counter *counter_stats, int reset);
 u32 mlx4_comm_get_version(void);
 int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
 int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 4820080..efe80c7 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -771,6 +771,14 @@ union mlx4_ext_av {
 	struct mlx4_eth_av	eth;
 };
 
+/* Counters should be saturate once they reach their maximum value */
+#define ASSIGN_32BIT_COUNTER(counter, value) do {	\
+	if ((value) > U32_MAX)				\
+		counter = cpu_to_be32(U32_MAX);		\
+	else						\
+		counter = cpu_to_be32(value);		\
+} while (0)
+
 struct mlx4_counter {
 	u8	reserved1[3];
 	u8	counter_mode;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 11/13] net/mlx4_en: Show PF own statistics via ethtool
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (9 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 10/13] net/mlx4_core: Add helper to query counters Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice Or Gerlitz
  2015-06-10 14:59 ` [PATCH net-next 13/13] net/mlx4_en: Support ndo_get_vf_stats Or Gerlitz
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Allow the user to observe the PF own statistics using ethtool with pf_
prefixed counter names.

Those counters are the PF statistics out of the overall port statistics.
Every PF QP is attached to a counter and the summary of those counters
is the PF statistics.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c |   17 ++++++++++++++++
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c  |    8 ++++++-
 drivers/net/ethernet/mellanox/mlx4/en_port.c    |   24 ++++++++++++++++++++++-
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h    |    1 +
 drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h |   11 +++++++++-
 5 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index a2ddf3d..99ba1c5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -119,6 +119,12 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
 	"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
 	"rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload",
 
+	/* pf statistics */
+	"pf_rx_packets",
+	"pf_rx_bytes",
+	"pf_tx_packets",
+	"pf_tx_bytes",
+
 	/* priority flow control statistics rx */
 	"rx_pause_prio_0", "rx_pause_duration_prio_0",
 	"rx_pause_transition_prio_0",
@@ -368,6 +374,11 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
 		if (bitmap_iterator_test(&it))
 			data[index++] = ((unsigned long *)&priv->port_stats)[i];
 
+	for (i = 0; i < NUM_PF_STATS; i++, bitmap_iterator_inc(&it))
+		if (bitmap_iterator_test(&it))
+			data[index++] =
+				((unsigned long *)&priv->pf_stats)[i];
+
 	for (i = 0; i < NUM_FLOW_PRIORITY_STATS_RX;
 	     i++, bitmap_iterator_inc(&it))
 		if (bitmap_iterator_test(&it))
@@ -448,6 +459,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
 				strcpy(data + (index++) * ETH_GSTRING_LEN,
 				       main_strings[strings]);
 
+		for (i = 0; i < NUM_PF_STATS; i++, strings++,
+		     bitmap_iterator_inc(&it))
+			if (bitmap_iterator_test(&it))
+				strcpy(data + (index++) * ETH_GSTRING_LEN,
+				       main_strings[strings]);
+
 		for (i = 0; i < NUM_FLOW_STATS; i++, strings++,
 		     bitmap_iterator_inc(&it))
 			if (bitmap_iterator_test(&it))
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 048fca0..f9142f2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1895,6 +1895,7 @@ static void mlx4_en_clear_stats(struct net_device *dev)
 	       sizeof(priv->rx_priority_flowstats));
 	memset(&priv->tx_priority_flowstats, 0,
 	       sizeof(priv->tx_priority_flowstats));
+	memset(&priv->pf_stats, 0, sizeof(priv->pf_stats));
 
 	for (i = 0; i < priv->tx_ring_num; i++) {
 		priv->tx_ring[i]->bytes = 0;
@@ -2685,7 +2686,7 @@ void mlx4_en_update_pfc_stats_bitmap(struct mlx4_dev *dev,
 				     u8 rx_ppp, u8 rx_pause,
 				     u8 tx_ppp, u8 tx_pause)
 {
-	int last_i = NUM_MAIN_STATS + NUM_PORT_STATS;
+	int last_i = NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PF_STATS;
 
 	if (!mlx4_is_slave(dev) &&
 	    (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN)) {
@@ -2747,6 +2748,11 @@ void mlx4_en_set_stats_bitmap(struct mlx4_dev *dev,
 	bitmap_set(stats_bitmap->bitmap, last_i, NUM_PORT_STATS);
 	last_i += NUM_PORT_STATS;
 
+	if (mlx4_is_master(dev))
+		bitmap_set(stats_bitmap->bitmap, last_i,
+			   NUM_PF_STATS);
+	last_i += NUM_PF_STATS;
+
 	mlx4_en_update_pfc_stats_bitmap(dev, stats_bitmap,
 					rx_ppp, rx_pause,
 					tx_ppp, tx_pause);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
index 0a56f01..df1236c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -149,14 +149,16 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num)
 
 int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 {
+	struct mlx4_counter tmp_counter_stats;
 	struct mlx4_en_stat_out_mbox *mlx4_en_stats;
 	struct mlx4_en_stat_out_flow_control_mbox *flowstats;
 	struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]);
 	struct net_device_stats *stats = &priv->stats;
 	struct mlx4_cmd_mailbox *mailbox;
 	u64 in_mod = reset << 8 | port;
+	__be32 tmp_stat;
 	int err;
-	int i;
+	int i, counter_index;
 
 	mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
 	if (IS_ERR(mailbox))
@@ -296,6 +298,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 
 	spin_unlock_bh(&priv->stats_lock);
 
+	memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats));
+	counter_index = mlx4_get_default_counter_index(mdev->dev, port);
+	err = mlx4_get_counter_stats(mdev->dev, counter_index,
+				     &tmp_counter_stats, reset);
+
 	/* 0xffs indicates invalid value */
 	memset(mailbox->buf, 0xff, sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
 
@@ -314,6 +321,21 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
 
 	spin_lock_bh(&priv->stats_lock);
 
+	if (tmp_counter_stats.counter_mode == 0) {
+		ASSIGN_32BIT_COUNTER(tmp_stat,
+				     be64_to_cpu(tmp_counter_stats.rx_bytes));
+		priv->pf_stats.rx_bytes = be32_to_cpu(tmp_stat);
+		ASSIGN_32BIT_COUNTER(tmp_stat,
+				     be64_to_cpu(tmp_counter_stats.tx_bytes));
+		priv->pf_stats.tx_bytes = be32_to_cpu(tmp_stat);
+		ASSIGN_32BIT_COUNTER(tmp_stat,
+				     be64_to_cpu(tmp_counter_stats.rx_frames));
+		priv->pf_stats.rx_packets = be32_to_cpu(tmp_stat);
+		ASSIGN_32BIT_COUNTER(tmp_stat,
+				     be64_to_cpu(tmp_counter_stats.tx_frames));
+		priv->pf_stats.tx_packets = be32_to_cpu(tmp_stat);
+	}
+
 	for (i = 0; i < MLX4_NUM_PRIORITIES; i++)	{
 		priv->rx_priority_flowstats[i].rx_pause =
 			be64_to_cpu(flowstats[i].rx_pause);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index f6c3e12..d5f9adb 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -566,6 +566,7 @@ struct mlx4_en_priv {
 #endif
 	struct mlx4_en_perf_stats pstats;
 	struct mlx4_en_pkt_stats pkstats;
+	struct mlx4_en_counter_stats pf_stats;
 	struct mlx4_en_flow_stats_rx rx_priority_flowstats[MLX4_NUM_PRIORITIES];
 	struct mlx4_en_flow_stats_tx tx_priority_flowstats[MLX4_NUM_PRIORITIES];
 	struct mlx4_en_flow_stats_rx rx_flowstats;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
index 0055583..c5c1de9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h
@@ -23,6 +23,14 @@ struct mlx4_en_pkt_stats {
 #define NUM_PKT_STATS		43
 };
 
+struct mlx4_en_counter_stats {
+	unsigned long rx_packets;
+	unsigned long rx_bytes;
+	unsigned long tx_packets;
+	unsigned long tx_bytes;
+#define NUM_PF_STATS      4
+};
+
 struct mlx4_en_port_stats {
 	unsigned long tso_packets;
 	unsigned long xmit_more;
@@ -71,7 +79,8 @@ struct mlx4_en_flow_stats_tx {
 
 #define NUM_FLOW_STATS (NUM_FLOW_STATS_RX + NUM_FLOW_STATS_TX + \
 			NUM_FLOW_PRIORITY_STATS_TX + \
-			NUM_FLOW_PRIORITY_STATS_RX)
+			NUM_FLOW_PRIORITY_STATS_RX + \
+			NUM_PF_STATS)
 
 struct mlx4_en_stat_out_flow_control_mbox {
 	/* Total number of PAUSE frames received from the far-end port */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (10 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 11/13] net/mlx4_en: Show PF own statistics via ethtool Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  2015-06-10 15:23   ` John Fastabend
  2015-06-10 14:59 ` [PATCH net-next 13/13] net/mlx4_en: Support ndo_get_vf_stats Or Gerlitz
  12 siblings, 1 reply; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz, Greg Rose, Mitch Williams

From: Eran Ben Elisha <eranbe@mellanox.com>

Add ndo_get_vf_stats where the PF retrieves and fills the VFs traffic
statistics. Add rtnl_link_vf_stats64 for passing the VF statistics from
the PF to user-space.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 include/linux/netdevice.h    |    4 ++++
 include/uapi/linux/if_link.h |   11 +++++++++++
 net/core/rtnetlink.c         |   12 ++++++++++--
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6f5f71f..b1d3b88 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1100,6 +1100,10 @@ struct net_device_ops {
 						     struct ifla_vf_info *ivf);
 	int			(*ndo_set_vf_link_state)(struct net_device *dev,
 							 int vf, int link_state);
+	int			(*ndo_get_vf_stats)(struct net_device *dev,
+						    int vf,
+						    struct rtnl_link_vf_stats64
+						    *vf_stats);
 	int			(*ndo_set_vf_port)(struct net_device *dev,
 						   int vf,
 						   struct nlattr *port[]);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 1737b7a..9c25aeb 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -70,6 +70,16 @@ struct rtnl_link_stats64 {
 	__u64	tx_compressed;
 };
 
+/* VF statistics structure */
+struct rtnl_link_vf_stats64 {
+	__u64	rx_packets;		/* total packets received	*/
+	__u64	tx_packets;		/* total packets transmitted	*/
+	__u64	rx_bytes;		/* total bytes received		*/
+	__u64	tx_bytes;		/* total bytes transmitted	*/
+	__u64	broadcast;		/* broadcast packets received	*/
+	__u64	multicast;		/* multicast packets received	*/
+};
+
 /* The struct should be in sync with struct ifmap */
 struct rtnl_link_ifmap {
 	__u64	mem_start;
@@ -482,6 +492,7 @@ enum {
 	IFLA_VF_RSS_QUERY_EN,	/* RSS Redirection Table and Hash Key query
 				 * on/off switch
 				 */
+	IFLA_VF_STATS,		/* network device statistics */
 	__IFLA_VF_MAX,
 };
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 077b6d2..6d7c939 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -819,7 +819,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
 			 nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
 			 nla_total_size(sizeof(struct ifla_vf_rate)) +
 			 nla_total_size(sizeof(struct ifla_vf_link_state)) +
-			 nla_total_size(sizeof(struct ifla_vf_rss_query_en)));
+			 nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
+			 nla_total_size(sizeof(struct rtnl_link_vf_stats64)));
 		return size;
 	} else
 		return 0;
@@ -1138,6 +1139,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 			struct ifla_vf_spoofchk vf_spoofchk;
 			struct ifla_vf_link_state vf_linkstate;
 			struct ifla_vf_rss_query_en vf_rss_query_en;
+			struct rtnl_link_vf_stats64 vf_stats;
 
 			/*
 			 * Not all SR-IOV capable drivers support the
@@ -1176,6 +1178,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 				nla_nest_cancel(skb, vfinfo);
 				goto nla_put_failure;
 			}
+			memset(&vf_stats, 0, sizeof(vf_stats));
+			if (dev->netdev_ops->ndo_get_vf_stats)
+				dev->netdev_ops->ndo_get_vf_stats(dev, i,
+								  &vf_stats);
 			if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
 			    nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
 			    nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
@@ -1188,7 +1194,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 				    &vf_linkstate) ||
 			    nla_put(skb, IFLA_VF_RSS_QUERY_EN,
 				    sizeof(vf_rss_query_en),
-				    &vf_rss_query_en))
+				    &vf_rss_query_en) ||
+			    nla_put(skb, IFLA_VF_STATS, sizeof(vf_stats),
+				    &vf_stats))
 				goto nla_put_failure;
 			nla_nest_end(skb, vf);
 		}
-- 
1.7.1

Cc: Greg Rose <gregory.v.rose@intel.com>
Cc: Mitch Williams <mitch.a.williams@intel.com>

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH net-next 13/13] net/mlx4_en: Support ndo_get_vf_stats
  2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
                   ` (11 preceding siblings ...)
  2015-06-10 14:59 ` [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice Or Gerlitz
@ 2015-06-10 14:59 ` Or Gerlitz
  12 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-10 14:59 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Amir Vadai, Tal Alon, Eran Ben Elisha, Hadar Hen Zion,
	Or Gerlitz

From: Eran Ben Elisha <eranbe@mellanox.com>

Implement function to gather vf statistics through the PF. The function
is provided in the master net device ops.

All VFs counters are stored in list per slave, run over the slave's list
and collect all statistics.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/cmd.c           |   29 ++++++++++++
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |   10 ++++
 drivers/net/ethernet/mellanox/mlx4/mlx4.h          |    2 +
 .../net/ethernet/mellanox/mlx4/resource_tracker.c  |   48 ++++++++++++++++++++
 include/linux/mlx4/cmd.h                           |    3 +
 5 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 4495bbd..c438e56 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -3223,6 +3223,35 @@ if_stat_out:
 }
 EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
 
+int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+		      struct rtnl_link_vf_stats64 *vf_stats)
+{
+	struct mlx4_counter tmp_vf_stats;
+	int slave;
+	int err = 0;
+
+	if (!vf_stats)
+		return -EINVAL;
+
+	if (!mlx4_is_master(dev))
+		return -EPROTONOSUPPORT;
+
+	slave = mlx4_get_slave_indx(dev, vf_idx);
+	if (slave < 0)
+		return -EINVAL;
+
+	err = mlx4_calc_vf_counters(dev, slave, port, &tmp_vf_stats);
+	if (!err && tmp_vf_stats.counter_mode == 0) {
+		vf_stats->rx_packets = be64_to_cpu(tmp_vf_stats.rx_frames);
+		vf_stats->tx_packets = be64_to_cpu(tmp_vf_stats.tx_frames);
+		vf_stats->rx_bytes = be64_to_cpu(tmp_vf_stats.rx_bytes);
+		vf_stats->tx_bytes = be64_to_cpu(tmp_vf_stats.tx_bytes);
+	}
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_vf_stats);
+
 int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index f9142f2..6b816aa 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2292,6 +2292,15 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
 	return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
 }
 
+static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
+				struct rtnl_link_vf_stats64 *vf_stats)
+{
+	struct mlx4_en_priv *en_priv = netdev_priv(dev);
+	struct mlx4_en_dev *mdev = en_priv->mdev;
+
+	return mlx4_get_vf_stats(mdev->dev, en_priv->port, vf, vf_stats);
+}
+
 #define PORT_ID_BYTE_LEN 8
 static int mlx4_en_get_phys_port_id(struct net_device *dev,
 				    struct netdev_phys_item_id *ppid)
@@ -2489,6 +2498,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
 	.ndo_set_vf_rate	= mlx4_en_set_vf_rate,
 	.ndo_set_vf_spoofchk	= mlx4_en_set_vf_spoofchk,
 	.ndo_set_vf_link_state	= mlx4_en_set_vf_link_state,
+	.ndo_get_vf_stats       = mlx4_en_get_vf_stats,
 	.ndo_get_vf_config	= mlx4_en_get_vf_config,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= mlx4_en_netpoll,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index e9e94bc..a092c5c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1010,6 +1010,8 @@ int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
 		     int start_index, int npages, u64 *page_list);
 int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
 void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx);
+int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
+			  struct mlx4_counter *data);
 int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn);
 void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn);
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 73db584..731423c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -46,6 +46,7 @@
 
 #include "mlx4.h"
 #include "fw.h"
+#include "mlx4_stats.h"
 
 #define MLX4_MAC_VALID		(1ull << 63)
 #define MLX4_PF_COUNTERS_PER_PORT	2
@@ -1147,6 +1148,53 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
 	return ret;
 }
 
+int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
+			  struct mlx4_counter *data)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
+	struct res_common *tmp;
+	struct res_counter *counter;
+	int *counters_arr;
+	int i = 0, err = 0;
+
+	memset(data, 0, sizeof(*data));
+
+	counters_arr = kmalloc_array(dev->caps.max_counters,
+				     sizeof(*counters_arr), GFP_KERNEL);
+	if (!counters_arr)
+		return -ENOMEM;
+
+	spin_lock_irq(mlx4_tlock(dev));
+	list_for_each_entry(tmp,
+			    &tracker->slave_list[slave].res_list[RES_COUNTER],
+			    list) {
+		counter = container_of(tmp, struct res_counter, com);
+		if (counter->port == port) {
+			counters_arr[i] = (int)tmp->res_id;
+			i++;
+		}
+	}
+	spin_unlock_irq(mlx4_tlock(dev));
+	counters_arr[i] = -1;
+
+	i = 0;
+
+	while (counters_arr[i] != -1) {
+		err = mlx4_get_counter_stats(dev, counters_arr[i], data,
+					     0);
+		if (err) {
+			memset(data, 0, sizeof(*data));
+			goto table_changed;
+		}
+		i++;
+	}
+
+table_changed:
+	kfree(counters_arr);
+	return 0;
+}
+
 static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
 			 enum mlx4_resource type, int extra)
 {
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 5dffc86..53b9023 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -36,6 +36,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/if_link.h>
 #include <linux/mlx4/device.h>
+#include <linux/netdevice.h>
 
 enum {
 	/* initialization and general commands */
@@ -303,6 +304,8 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbo
 
 int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
 			   struct mlx4_counter *counter_stats, int reset);
+int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
+		      struct rtnl_link_vf_stats64 *vf_stats);
 u32 mlx4_comm_get_version(void);
 int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
 int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice
  2015-06-10 14:59 ` [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice Or Gerlitz
@ 2015-06-10 15:23   ` John Fastabend
  2015-06-11 17:37     ` Or Gerlitz
  0 siblings, 1 reply; 16+ messages in thread
From: John Fastabend @ 2015-06-10 15:23 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: David S. Miller, netdev, Amir Vadai, Tal Alon, Eran Ben Elisha,
	Hadar Hen Zion, Greg Rose, Mitch Williams

On 06/10/2015 07:59 AM, Or Gerlitz wrote:
> From: Eran Ben Elisha <eranbe@mellanox.com>
>
> Add ndo_get_vf_stats where the PF retrieves and fills the VFs traffic
> statistics. Add rtnl_link_vf_stats64 for passing the VF statistics from
> the PF to user-space.
>
> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
> Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
> ---
>   include/linux/netdevice.h    |    4 ++++
>   include/uapi/linux/if_link.h |   11 +++++++++++
>   net/core/rtnetlink.c         |   12 ++++++++++--
>   3 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 6f5f71f..b1d3b88 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1100,6 +1100,10 @@ struct net_device_ops {
>   						     struct ifla_vf_info *ivf);
>   	int			(*ndo_set_vf_link_state)(struct net_device *dev,
>   							 int vf, int link_state);
> +	int			(*ndo_get_vf_stats)(struct net_device *dev,
> +						    int vf,
> +						    struct rtnl_link_vf_stats64
> +						    *vf_stats);
>   	int			(*ndo_set_vf_port)(struct net_device *dev,
>   						   int vf,
>   						   struct nlattr *port[]);
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 1737b7a..9c25aeb 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -70,6 +70,16 @@ struct rtnl_link_stats64 {
>   	__u64	tx_compressed;
>   };
>
> +/* VF statistics structure */
> +struct rtnl_link_vf_stats64 {
> +	__u64	rx_packets;		/* total packets received	*/
> +	__u64	tx_packets;		/* total packets transmitted	*/
> +	__u64	rx_bytes;		/* total bytes received		*/
> +	__u64	tx_bytes;		/* total bytes transmitted	*/
> +	__u64	broadcast;		/* broadcast packets received	*/
> +	__u64	multicast;		/* multicast packets received	*/
> +};

Can we encode this in a nested netlink structure when its passed
up to userspace? I have more stats I would like to export in the
future such as dropped packets and if we put the structure in the UAPI
we wont be able to easily extend this.

The structure could be moved into ./include/linux/if_link.h though.

> +
>   /* The struct should be in sync with struct ifmap */
>   struct rtnl_link_ifmap {
>   	__u64	mem_start;
> @@ -482,6 +492,7 @@ enum {
>   	IFLA_VF_RSS_QUERY_EN,	/* RSS Redirection Table and Hash Key query
>   				 * on/off switch
>   				 */
> +	IFLA_VF_STATS,		/* network device statistics */
>   	__IFLA_VF_MAX,
>   };
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 077b6d2..6d7c939 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -819,7 +819,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
>   			 nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
>   			 nla_total_size(sizeof(struct ifla_vf_rate)) +
>   			 nla_total_size(sizeof(struct ifla_vf_link_state)) +
> -			 nla_total_size(sizeof(struct ifla_vf_rss_query_en)));
> +			 nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
> +			 nla_total_size(sizeof(struct rtnl_link_vf_stats64)));
>   		return size;
>   	} else
>   		return 0;
> @@ -1138,6 +1139,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
>   			struct ifla_vf_spoofchk vf_spoofchk;
>   			struct ifla_vf_link_state vf_linkstate;
>   			struct ifla_vf_rss_query_en vf_rss_query_en;
> +			struct rtnl_link_vf_stats64 vf_stats;
>
>   			/*
>   			 * Not all SR-IOV capable drivers support the
> @@ -1176,6 +1178,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
>   				nla_nest_cancel(skb, vfinfo);
>   				goto nla_put_failure;
>   			}
> +			memset(&vf_stats, 0, sizeof(vf_stats));
> +			if (dev->netdev_ops->ndo_get_vf_stats)
> +				dev->netdev_ops->ndo_get_vf_stats(dev, i,
> +								  &vf_stats);
>   			if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
>   			    nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
>   			    nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
> @@ -1188,7 +1194,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
>   				    &vf_linkstate) ||
>   			    nla_put(skb, IFLA_VF_RSS_QUERY_EN,
>   				    sizeof(vf_rss_query_en),
> -				    &vf_rss_query_en))
> +				    &vf_rss_query_en) ||
> +			    nla_put(skb, IFLA_VF_STATS, sizeof(vf_stats),
> +				    &vf_stats))
>   				goto nla_put_failure;
>   			nla_nest_end(skb, vf);
>   		}
>


-- 
John Fastabend         Intel Corporation

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice
  2015-06-10 15:23   ` John Fastabend
@ 2015-06-11 17:37     ` Or Gerlitz
  0 siblings, 0 replies; 16+ messages in thread
From: Or Gerlitz @ 2015-06-11 17:37 UTC (permalink / raw)
  To: John Fastabend
  Cc: Or Gerlitz, David S. Miller, Linux Netdev List, Amir Vadai,
	Tal Alon, Eran Ben Elisha, Hadar Hen Zion, Greg Rose,
	Mitch Williams

On Wed, Jun 10, 2015 at 6:23 PM, John Fastabend
<john.fastabend@gmail.com> wrote:
> On 06/10/2015 07:59 AM, Or Gerlitz wrote:
>>
>> From: Eran Ben Elisha <eranbe@mellanox.com>
>>
>> Add ndo_get_vf_stats where the PF retrieves and fills the VFs traffic
>> statistics. Add rtnl_link_vf_stats64 for passing the VF statistics from
>> the PF to user-space.
>>
>> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
>> Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
>> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
>> ---
>>   include/linux/netdevice.h    |    4 ++++
>>   include/uapi/linux/if_link.h |   11 +++++++++++
>>   net/core/rtnetlink.c         |   12 ++++++++++--
>>   3 files changed, 25 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 6f5f71f..b1d3b88 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -1100,6 +1100,10 @@ struct net_device_ops {
>>                                                      struct ifla_vf_info
>> *ivf);
>>         int                     (*ndo_set_vf_link_state)(struct net_device
>> *dev,
>>                                                          int vf, int
>> link_state);
>> +       int                     (*ndo_get_vf_stats)(struct net_device
>> *dev,
>> +                                                   int vf,
>> +                                                   struct
>> rtnl_link_vf_stats64
>> +                                                   *vf_stats);
>>         int                     (*ndo_set_vf_port)(struct net_device *dev,
>>                                                    int vf,
>>                                                    struct nlattr *port[]);
>> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
>> index 1737b7a..9c25aeb 100644
>> --- a/include/uapi/linux/if_link.h
>> +++ b/include/uapi/linux/if_link.h
>> @@ -70,6 +70,16 @@ struct rtnl_link_stats64 {
>>         __u64   tx_compressed;
>>   };
>>
>> +/* VF statistics structure */
>> +struct rtnl_link_vf_stats64 {
>> +       __u64   rx_packets;             /* total packets received       */
>> +       __u64   tx_packets;             /* total packets transmitted    */
>> +       __u64   rx_bytes;               /* total bytes received         */
>> +       __u64   tx_bytes;               /* total bytes transmitted      */
>> +       __u64   broadcast;              /* broadcast packets received   */
>> +       __u64   multicast;              /* multicast packets received   */
>> +};
>
>
> Can we encode this in a nested netlink structure when its passed
> up to userspace? I have more stats I would like to export in the
> future such as dropped packets and if we put the structure in the UAPI
> we wont be able to easily extend this.

Yep, makes sense, I asked Eran to look on doing so.

> The structure could be moved into ./include/linux/if_link.h though.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-06-11 17:37 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-10 14:59 [PATCH net-next 00/13] mlx4 driver update (+ new VF ndo) Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 01/13] net/mlx4_core: Check before cleaning counters bitmap Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 02/13] net/mlx4_core: Reset counters data when freed Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 03/13] net/mlx4_core: Add sink counter Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 04/13] net/mlx4_core: Remove counters table allocation from VF flow Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 05/13] net/mlx4_core: Adjust counter grant policy in the resource tracker Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 06/13] net/mlx4_core: Add port attribute when tracking counters Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 07/13] net/mlx4_core: Allocate default counter per port Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 08/13] IB/mlx4: Add RoCE/IB dedicated counters Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 09/13] IB/mlx4: Set VF to read from QP counters Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 10/13] net/mlx4_core: Add helper to query counters Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 11/13] net/mlx4_en: Show PF own statistics via ethtool Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 12/13] net/core: Add reading VF statistics through the PF netdevice Or Gerlitz
2015-06-10 15:23   ` John Fastabend
2015-06-11 17:37     ` Or Gerlitz
2015-06-10 14:59 ` [PATCH net-next 13/13] net/mlx4_en: Support ndo_get_vf_stats Or Gerlitz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.