Skip to content

Commit

Permalink
Merge branch 'mlx5e-next'
Browse files Browse the repository at this point in the history
Amir Vadai says:

====================
net/mlx5e: Driver updates 04-Aug-2015

This patchset introduces two features to the ConnectX-4 driver: Patch 8/8
("Support physical port counters") exposes some hardware counters through
ethtool. Rest of the patches are preparation and usage of what we call
light-weight netdev open/close. Some flows that used to be in the ndo_open/stop
are moved to the PCI probe/remove flows - i.e. we will make the netdev
open/close operations more "light-weight".

The benefits of this change are:
1) Reduce the execution time of the stop/open operations.
2) Avoid saving SW shadows of resource configurations that must
   persist through stop/open operations (e.g flow table steering
   rules), and avoid deleting/applying them from/to the device upon
   netdev stop/open.
3) Avoid synchronizing threads that access those resources with the
   netdev stop/open threads.

Instead of create/destroy the resource during netdev open/stop, This patchset
changes the behavior such that upon netdev stop, traffic is redirected to a
"Drop RQ" (a RQ that silently drops, at the NIC HW level all incoming traffic).
After redirecting the traffic, RX/TX software resources could be destroyed.
During netdev open, the RX/TX rings are created and traffic is redirected to
the RX rings.

Patchset was applied and tested over commit ba7591d ("ebpf: add skb->hash to
offset map for usage in {cls, act}_bpf or filters")
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 7, 2015
2 parents adc4cc9 + efea389 commit c71b5ad
Show file tree
Hide file tree
Showing 9 changed files with 675 additions and 348 deletions.
97 changes: 86 additions & 11 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,80 @@ struct mlx5e_vport_stats {
#define NUM_VPORT_COUNTERS 31
};

static const char pport_strings[][ETH_GSTRING_LEN] = {
/* IEEE802.3 counters */
"frames_tx",
"frames_rx",
"check_seq_err",
"alignment_err",
"octets_tx",
"octets_received",
"multicast_xmitted",
"broadcast_xmitted",
"multicast_rx",
"broadcast_rx",
"in_range_len_errors",
"out_of_range_len",
"too_long_errors",
"symbol_err",
"mac_control_tx",
"mac_control_rx",
"unsupported_op_rx",
"pause_ctrl_rx",
"pause_ctrl_tx",

/* RFC2863 counters */
"in_octets",
"in_ucast_pkts",
"in_discards",
"in_errors",
"in_unknown_protos",
"out_octets",
"out_ucast_pkts",
"out_discards",
"out_errors",
"in_multicast_pkts",
"in_broadcast_pkts",
"out_multicast_pkts",
"out_broadcast_pkts",

/* RFC2819 counters */
"drop_events",
"octets",
"pkts",
"broadcast_pkts",
"multicast_pkts",
"crc_align_errors",
"undersize_pkts",
"oversize_pkts",
"fragments",
"jabbers",
"collisions",
"p64octets",
"p65to127octets",
"p128to255octets",
"p256to511octets",
"p512to1023octets",
"p1024to1518octets",
"p1519to2047octets",
"p2048to4095octets",
"p4096to8191octets",
"p8192to10239octets",
};

#define NUM_IEEE_802_3_COUNTERS 19
#define NUM_RFC_2863_COUNTERS 13
#define NUM_RFC_2819_COUNTERS 21
#define NUM_PPORT_COUNTERS (NUM_IEEE_802_3_COUNTERS + \
NUM_RFC_2863_COUNTERS + \
NUM_RFC_2819_COUNTERS)

struct mlx5e_pport_stats {
__be64 IEEE_802_3_counters[NUM_IEEE_802_3_COUNTERS];
__be64 RFC_2863_counters[NUM_RFC_2863_COUNTERS];
__be64 RFC_2819_counters[NUM_RFC_2819_COUNTERS];
};

static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
"packets",
"csum_none",
Expand Down Expand Up @@ -180,6 +254,7 @@ struct mlx5e_sq_stats {

struct mlx5e_stats {
struct mlx5e_vport_stats vport;
struct mlx5e_pport_stats pport;
};

struct mlx5e_params {
Expand Down Expand Up @@ -217,6 +292,7 @@ struct mlx5e_cq {
struct napi_struct *napi;
struct mlx5_core_cq mcq;
struct mlx5e_channel *channel;
struct mlx5e_priv *priv;

/* control */
struct mlx5_wq_ctrl wq_ctrl;
Expand All @@ -240,6 +316,7 @@ struct mlx5e_rq {
struct mlx5_wq_ctrl wq_ctrl;
u32 rqn;
struct mlx5e_channel *channel;
struct mlx5e_priv *priv;
} ____cacheline_aligned_in_smp;

struct mlx5e_tx_skb_cb {
Expand Down Expand Up @@ -344,10 +421,10 @@ enum mlx5e_traffic_types {
MLX5E_NUM_TT,
};

enum {
MLX5E_RQT_SPREADING = 0,
MLX5E_RQT_DEFAULT_RQ = 1,
MLX5E_NUM_RQT = 2,
enum mlx5e_rqt_ix {
MLX5E_INDIRECTION_RQT,
MLX5E_SINGLE_RQ_RQT,
MLX5E_NUM_RQT,
};

struct mlx5e_eth_addr_info {
Expand All @@ -372,10 +449,10 @@ struct mlx5e_eth_addr_db {
enum {
MLX5E_STATE_ASYNC_EVENTS_ENABLE,
MLX5E_STATE_OPENED,
MLX5E_STATE_DESTROYING,
};

struct mlx5e_vlan_db {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u32 active_vlans_ft_ix[VLAN_N_VID];
u32 untagged_rule_ft_ix;
u32 any_vlan_rule_ft_ix;
Expand All @@ -399,10 +476,11 @@ struct mlx5e_priv {
u32 pdn;
u32 tdn;
struct mlx5_core_mr mr;
struct mlx5e_rq drop_rq;

struct mlx5e_channel **channel;
u32 tisn[MLX5E_MAX_NUM_TC];
u32 rqtn;
u32 rqtn[MLX5E_NUM_RQT];
u32 tirn[MLX5E_NUM_TT];

struct mlx5e_flow_table ft;
Expand Down Expand Up @@ -479,10 +557,9 @@ struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);

void mlx5e_update_stats(struct mlx5e_priv *priv);

int mlx5e_open_flow_table(struct mlx5e_priv *priv);
void mlx5e_close_flow_table(struct mlx5e_priv *priv);
int mlx5e_create_flow_tables(struct mlx5e_priv *priv);
void mlx5e_destroy_flow_tables(struct mlx5e_priv *priv);
void mlx5e_init_eth_addr(struct mlx5e_priv *priv);
void mlx5e_set_rx_mode_core(struct mlx5e_priv *priv);
void mlx5e_set_rx_mode_work(struct work_struct *work);

int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
Expand All @@ -491,8 +568,6 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
u16 vid);
void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv);
int mlx5e_add_all_vlan_rules(struct mlx5e_priv *priv);
void mlx5e_del_all_vlan_rules(struct mlx5e_priv *priv);

int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev);
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)

switch (sset) {
case ETH_SS_STATS:
return NUM_VPORT_COUNTERS +
return NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
priv->params.num_channels * NUM_RQ_STATS +
priv->params.num_channels * priv->params.num_tc *
NUM_SQ_STATS;
Expand Down Expand Up @@ -200,6 +200,11 @@ static void mlx5e_get_strings(struct net_device *dev,
strcpy(data + (idx++) * ETH_GSTRING_LEN,
vport_strings[i]);

/* PPORT counters */
for (i = 0; i < NUM_PPORT_COUNTERS; i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
pport_strings[i]);

/* per channel counters */
for (i = 0; i < priv->params.num_channels; i++)
for (j = 0; j < NUM_RQ_STATS; j++)
Expand Down Expand Up @@ -234,6 +239,9 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
for (i = 0; i < NUM_VPORT_COUNTERS; i++)
data[idx++] = ((u64 *)&priv->stats.vport)[i];

for (i = 0; i < NUM_PPORT_COUNTERS; i++)
data[idx++] = be64_to_cpu(((__be64 *)&priv->stats.pport)[i]);

/* per channel counters */
for (i = 0; i < priv->params.num_channels; i++)
for (j = 0; j < NUM_RQ_STATS; j++)
Expand Down
113 changes: 26 additions & 87 deletions drivers/net/ethernet/mellanox/mlx5/core/en_flow_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,101 +594,40 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,

void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
{
WARN_ON(!mutex_is_locked(&priv->state_lock));
if (!priv->vlan.filter_disabled)
return;

if (priv->vlan.filter_disabled) {
priv->vlan.filter_disabled = false;
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
0);
}
priv->vlan.filter_disabled = false;
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
}

void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
{
WARN_ON(!mutex_is_locked(&priv->state_lock));
if (priv->vlan.filter_disabled)
return;

if (!priv->vlan.filter_disabled) {
priv->vlan.filter_disabled = true;
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
0);
}
priv->vlan.filter_disabled = true;
mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
}

int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
u16 vid)
{
struct mlx5e_priv *priv = netdev_priv(dev);
int err = 0;

mutex_lock(&priv->state_lock);

set_bit(vid, priv->vlan.active_vlans);
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID,
vid);

mutex_unlock(&priv->state_lock);

return err;
return mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);
}

int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
u16 vid)
{
struct mlx5e_priv *priv = netdev_priv(dev);

mutex_lock(&priv->state_lock);

clear_bit(vid, priv->vlan.active_vlans);
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);

mutex_unlock(&priv->state_lock);

return 0;
}

int mlx5e_add_all_vlan_rules(struct mlx5e_priv *priv)
{
u16 vid;
int err;

for_each_set_bit(vid, priv->vlan.active_vlans, VLAN_N_VID) {
err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID,
vid);
if (err)
return err;
}

err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
if (err)
return err;

if (priv->vlan.filter_disabled) {
err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
0);
if (err)
return err;
}
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);

return 0;
}

void mlx5e_del_all_vlan_rules(struct mlx5e_priv *priv)
{
u16 vid;

if (priv->vlan.filter_disabled)
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);

mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);

for_each_set_bit(vid, priv->vlan.active_vlans, VLAN_N_VID)
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid);
}

#define mlx5e_for_each_hash_node(hn, tmp, hash, i) \
for (i = 0; i < MLX5E_ETH_ADDR_HASH_SIZE; i++) \
hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
Expand Down Expand Up @@ -752,18 +691,21 @@ static void mlx5e_handle_netdev_addr(struct mlx5e_priv *priv)
mlx5e_for_each_hash_node(hn, tmp, priv->eth_addr.netdev_mc, i)
hn->action = MLX5E_ACTION_DEL;

if (test_bit(MLX5E_STATE_OPENED, &priv->state))
if (!test_bit(MLX5E_STATE_DESTROYING, &priv->state))
mlx5e_sync_netdev_addr(priv);

mlx5e_apply_netdev_addr(priv);
}

void mlx5e_set_rx_mode_core(struct mlx5e_priv *priv)
void mlx5e_set_rx_mode_work(struct work_struct *work)
{
struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
set_rx_mode_work);

struct mlx5e_eth_addr_db *ea = &priv->eth_addr;
struct net_device *ndev = priv->netdev;

bool rx_mode_enable = test_bit(MLX5E_STATE_OPENED, &priv->state);
bool rx_mode_enable = !test_bit(MLX5E_STATE_DESTROYING, &priv->state);
bool promisc_enabled = rx_mode_enable && (ndev->flags & IFF_PROMISC);
bool allmulti_enabled = rx_mode_enable && (ndev->flags & IFF_ALLMULTI);
bool broadcast_enabled = rx_mode_enable;
Expand Down Expand Up @@ -796,17 +738,6 @@ void mlx5e_set_rx_mode_core(struct mlx5e_priv *priv)
ea->broadcast_enabled = broadcast_enabled;
}

void mlx5e_set_rx_mode_work(struct work_struct *work)
{
struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
set_rx_mode_work);

mutex_lock(&priv->state_lock);
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
mlx5e_set_rx_mode_core(priv);
mutex_unlock(&priv->state_lock);
}

void mlx5e_init_eth_addr(struct mlx5e_priv *priv)
{
ether_addr_copy(priv->eth_addr.broadcast.addr, priv->netdev->broadcast);
Expand Down Expand Up @@ -929,7 +860,7 @@ static void mlx5e_destroy_vlan_flow_table(struct mlx5e_priv *priv)
mlx5_destroy_flow_table(priv->ft.vlan);
}

int mlx5e_open_flow_table(struct mlx5e_priv *priv)
int mlx5e_create_flow_tables(struct mlx5e_priv *priv)
{
int err;

Expand All @@ -941,16 +872,24 @@ int mlx5e_open_flow_table(struct mlx5e_priv *priv)
if (err)
goto err_destroy_main_flow_table;

err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
if (err)
goto err_destroy_vlan_flow_table;

return 0;

err_destroy_vlan_flow_table:
mlx5e_destroy_vlan_flow_table(priv);

err_destroy_main_flow_table:
mlx5e_destroy_main_flow_table(priv);

return err;
}

void mlx5e_close_flow_table(struct mlx5e_priv *priv)
void mlx5e_destroy_flow_tables(struct mlx5e_priv *priv)
{
mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
mlx5e_destroy_vlan_flow_table(priv);
mlx5e_destroy_main_flow_table(priv);
}
Loading

0 comments on commit c71b5ad

Please sign in to comment.