Skip to content

Commit

Permalink
net/mlx4_en: Support ndo_get_vf_stats
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eran Ben Elisha authored and David S. Miller committed Jun 16, 2015
1 parent 3b766cd commit 62a8905
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 0 deletions.
30 changes: 30 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3223,6 +3223,36 @@ int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
}
EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);

int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
struct ifla_vf_stats *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;

port = mlx4_slaves_closest_port(dev, slave, port);
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);
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ifla_vf_stats *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)
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/mlx4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
48 changes: 48 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down
3 changes: 3 additions & 0 deletions include/linux/mlx4/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 ifla_vf_stats *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);
Expand Down

0 comments on commit 62a8905

Please sign in to comment.