Skip to content

Commit

Permalink
net/mlx4_core: Allocate default counter per port
Browse files Browse the repository at this point in the history
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>
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 6823024 commit 6de5f7f
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 4 deletions.
5 changes: 5 additions & 0 deletions drivers/net/ethernet/mellanox/mlx4/en_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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 ==
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx4/en_resources.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
71 changes: 68 additions & 3 deletions drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3212,6 +3275,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
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);
Expand Down Expand Up @@ -3511,6 +3575,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);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx4/mlx4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/linux/mlx4/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 6de5f7f

Please sign in to comment.