Skip to content

Commit 62a8905

Browse files
Eran Ben Elishadavem330
authored andcommitted
net/mlx4_en: Support ndo_get_vf_stats
Implement the ndo to gather VF statistics through the PF. All counters related to this VF are stored in a per slave list, 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> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3b766cd commit 62a8905

File tree

5 files changed

+93
-0
lines changed

5 files changed

+93
-0
lines changed

drivers/net/ethernet/mellanox/mlx4/cmd.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,6 +3223,36 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
32233223
}
32243224
EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
32253225

3226+
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
3227+
struct ifla_vf_stats *vf_stats)
3228+
{
3229+
struct mlx4_counter tmp_vf_stats;
3230+
int slave;
3231+
int err = 0;
3232+
3233+
if (!vf_stats)
3234+
return -EINVAL;
3235+
3236+
if (!mlx4_is_master(dev))
3237+
return -EPROTONOSUPPORT;
3238+
3239+
slave = mlx4_get_slave_indx(dev, vf_idx);
3240+
if (slave < 0)
3241+
return -EINVAL;
3242+
3243+
port = mlx4_slaves_closest_port(dev, slave, port);
3244+
err = mlx4_calc_vf_counters(dev, slave, port, &tmp_vf_stats);
3245+
if (!err && tmp_vf_stats.counter_mode == 0) {
3246+
vf_stats->rx_packets = be64_to_cpu(tmp_vf_stats.rx_frames);
3247+
vf_stats->tx_packets = be64_to_cpu(tmp_vf_stats.tx_frames);
3248+
vf_stats->rx_bytes = be64_to_cpu(tmp_vf_stats.rx_bytes);
3249+
vf_stats->tx_bytes = be64_to_cpu(tmp_vf_stats.tx_bytes);
3250+
}
3251+
3252+
return err;
3253+
}
3254+
EXPORT_SYMBOL_GPL(mlx4_get_vf_stats);
3255+
32263256
int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
32273257
{
32283258
struct mlx4_priv *priv = mlx4_priv(dev);

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,15 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
22922292
return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
22932293
}
22942294

2295+
static int mlx4_en_get_vf_stats(struct net_device *dev, int vf,
2296+
struct ifla_vf_stats *vf_stats)
2297+
{
2298+
struct mlx4_en_priv *en_priv = netdev_priv(dev);
2299+
struct mlx4_en_dev *mdev = en_priv->mdev;
2300+
2301+
return mlx4_get_vf_stats(mdev->dev, en_priv->port, vf, vf_stats);
2302+
}
2303+
22952304
#define PORT_ID_BYTE_LEN 8
22962305
static int mlx4_en_get_phys_port_id(struct net_device *dev,
22972306
struct netdev_phys_item_id *ppid)
@@ -2489,6 +2498,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
24892498
.ndo_set_vf_rate = mlx4_en_set_vf_rate,
24902499
.ndo_set_vf_spoofchk = mlx4_en_set_vf_spoofchk,
24912500
.ndo_set_vf_link_state = mlx4_en_set_vf_link_state,
2501+
.ndo_get_vf_stats = mlx4_en_get_vf_stats,
24922502
.ndo_get_vf_config = mlx4_en_get_vf_config,
24932503
#ifdef CONFIG_NET_POLL_CONTROLLER
24942504
.ndo_poll_controller = mlx4_en_netpoll,

drivers/net/ethernet/mellanox/mlx4/mlx4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,8 @@ int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
10101010
int start_index, int npages, u64 *page_list);
10111011
int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
10121012
void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx);
1013+
int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
1014+
struct mlx4_counter *data);
10131015
int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn);
10141016
void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn);
10151017

drivers/net/ethernet/mellanox/mlx4/resource_tracker.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#include "mlx4.h"
4848
#include "fw.h"
49+
#include "mlx4_stats.h"
4950

5051
#define MLX4_MAC_VALID (1ull << 63)
5152
#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,
11471148
return ret;
11481149
}
11491150

1151+
int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
1152+
struct mlx4_counter *data)
1153+
{
1154+
struct mlx4_priv *priv = mlx4_priv(dev);
1155+
struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1156+
struct res_common *tmp;
1157+
struct res_counter *counter;
1158+
int *counters_arr;
1159+
int i = 0, err = 0;
1160+
1161+
memset(data, 0, sizeof(*data));
1162+
1163+
counters_arr = kmalloc_array(dev->caps.max_counters,
1164+
sizeof(*counters_arr), GFP_KERNEL);
1165+
if (!counters_arr)
1166+
return -ENOMEM;
1167+
1168+
spin_lock_irq(mlx4_tlock(dev));
1169+
list_for_each_entry(tmp,
1170+
&tracker->slave_list[slave].res_list[RES_COUNTER],
1171+
list) {
1172+
counter = container_of(tmp, struct res_counter, com);
1173+
if (counter->port == port) {
1174+
counters_arr[i] = (int)tmp->res_id;
1175+
i++;
1176+
}
1177+
}
1178+
spin_unlock_irq(mlx4_tlock(dev));
1179+
counters_arr[i] = -1;
1180+
1181+
i = 0;
1182+
1183+
while (counters_arr[i] != -1) {
1184+
err = mlx4_get_counter_stats(dev, counters_arr[i], data,
1185+
0);
1186+
if (err) {
1187+
memset(data, 0, sizeof(*data));
1188+
goto table_changed;
1189+
}
1190+
i++;
1191+
}
1192+
1193+
table_changed:
1194+
kfree(counters_arr);
1195+
return 0;
1196+
}
1197+
11501198
static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
11511199
enum mlx4_resource type, int extra)
11521200
{

include/linux/mlx4/cmd.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/dma-mapping.h>
3737
#include <linux/if_link.h>
3838
#include <linux/mlx4/device.h>
39+
#include <linux/netdevice.h>
3940

4041
enum {
4142
/* initialization and general commands */
@@ -303,6 +304,8 @@ void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbo
303304

304305
int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
305306
struct mlx4_counter *counter_stats, int reset);
307+
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
308+
struct ifla_vf_stats *vf_stats);
306309
u32 mlx4_comm_get_version(void);
307310
int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
308311
int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);

0 commit comments

Comments
 (0)