Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2018-05-14

This series contains updates to virtchnl, i40e and i40evf.

Bruce cleans up whitespace and unnecessary parentheses in virtchnl.

Jake does a number of stat cleanups in the i40e driver, including
cleanup of code indentation, whitespace issues, remove duplicate stats,
fix grammar in code comment and general spring cleaning of the
statistics code.

Patryk fixes an issue where we recalculate vectors left and vectors
wanted but do not take into account the reduced number of queue pairs
per VSI.

Harshitha adds tx_busy stat to ethtool stats to track the number of
times we return NETDEV_TX_BUSY to the stack during transmit.

Paweł fixes a potential system crash when unloading the VF driver after
a hardware reset.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2018-05-14 14:28:59 -04:00
commit 23548dab56
7 changed files with 72 additions and 37 deletions

View File

@ -19,13 +19,13 @@ struct i40e_stats {
}
#define I40E_NETDEV_STAT(_net_stat) \
I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
#define I40E_PF_STAT(_name, _stat) \
I40E_STAT(struct i40e_pf, _name, _stat)
I40E_STAT(struct i40e_pf, _name, _stat)
#define I40E_VSI_STAT(_name, _stat) \
I40E_STAT(struct i40e_vsi, _name, _stat)
I40E_STAT(struct i40e_vsi, _name, _stat)
#define I40E_VEB_STAT(_name, _stat) \
I40E_STAT(struct i40e_veb, _name, _stat)
I40E_STAT(struct i40e_veb, _name, _stat)
static const struct i40e_stats i40e_gstrings_net_stats[] = {
I40E_NETDEV_STAT(rx_packets),
@ -66,6 +66,7 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = {
I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
I40E_VSI_STAT("tx_linearize", tx_linearize),
I40E_VSI_STAT("tx_force_wb", tx_force_wb),
I40E_VSI_STAT("tx_busy", tx_busy),
I40E_VSI_STAT("rx_alloc_fail", rx_buf_failed),
I40E_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
};
@ -103,10 +104,6 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
I40E_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
I40E_PF_STAT("link_xon_tx", stats.link_xon_tx),
I40E_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
I40E_PF_STAT("priority_xon_rx", stats.priority_xon_rx),
I40E_PF_STAT("priority_xoff_rx", stats.priority_xoff_rx),
I40E_PF_STAT("priority_xon_tx", stats.priority_xon_tx),
I40E_PF_STAT("priority_xoff_tx", stats.priority_xoff_tx),
I40E_PF_STAT("rx_size_64", stats.rx_size_64),
I40E_PF_STAT("rx_size_127", stats.rx_size_127),
I40E_PF_STAT("rx_size_255", stats.rx_size_255),
@ -148,9 +145,9 @@ static const struct i40e_stats i40e_gstrings_stats[] = {
* 2 /* Tx and Rx together */ \
* (sizeof(struct i40e_queue_stats) / sizeof(u64)))
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
I40E_MISC_STATS_LEN + \
I40E_QUEUE_STATS_LEN((n)))
#define I40E_PFC_STATS_LEN ( \
@ -1658,6 +1655,23 @@ static int i40e_set_ringparam(struct net_device *netdev,
return err;
}
static int i40e_get_stats_count(struct net_device *netdev)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) {
if (pf->lan_veb != I40E_NO_VEB &&
pf->flags & I40E_FLAG_VEB_STATS_ENABLED)
return I40E_PF_STATS_LEN(netdev) + I40E_VEB_STATS_TOTAL;
else
return I40E_PF_STATS_LEN(netdev);
} else {
return I40E_VSI_STATS_LEN(netdev);
}
}
static int i40e_get_sset_count(struct net_device *netdev, int sset)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
@ -1668,16 +1682,7 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_TEST:
return I40E_TEST_LEN;
case ETH_SS_STATS:
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) {
int len = I40E_PF_STATS_LEN(netdev);
if ((pf->lan_veb != I40E_NO_VEB) &&
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED))
len += I40E_VEB_STATS_TOTAL;
return len;
} else {
return I40E_VSI_STATS_LEN(netdev);
}
return i40e_get_stats_count(netdev);
case ETH_SS_PRIV_FLAGS:
return I40E_PRIV_FLAGS_STR_LEN +
(pf->hw.pf_id == 0 ? I40E_GL_PRIV_FLAGS_STR_LEN : 0);

View File

@ -2840,6 +2840,23 @@ static int i40e_vlan_rx_add_vid(struct net_device *netdev,
return ret;
}
/**
* i40e_vlan_rx_add_vid_up - Add a vlan id filter to HW offload in UP path
* @netdev: network interface to be adjusted
* @proto: unused protocol value
* @vid: vlan id to be added
**/
static void i40e_vlan_rx_add_vid_up(struct net_device *netdev,
__always_unused __be16 proto, u16 vid)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
if (vid >= VLAN_N_VID)
return;
set_bit(vid, vsi->active_vlans);
}
/**
* i40e_vlan_rx_kill_vid - Remove a vlan id filter from HW offload
* @netdev: network interface to be adjusted
@ -2882,8 +2899,8 @@ static void i40e_restore_vlan(struct i40e_vsi *vsi)
i40e_vlan_stripping_disable(vsi);
for_each_set_bit(vid, vsi->active_vlans, VLAN_N_VID)
i40e_vlan_rx_add_vid(vsi->netdev, htons(ETH_P_8021Q),
vid);
i40e_vlan_rx_add_vid_up(vsi->netdev, htons(ETH_P_8021Q),
vid);
}
/**
@ -10309,21 +10326,28 @@ static int i40e_init_msix(struct i40e_pf *pf)
/* any vectors left over go for VMDq support */
if (pf->flags & I40E_FLAG_VMDQ_ENABLED) {
int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps;
int vmdq_vecs = min_t(int, vectors_left, vmdq_vecs_wanted);
if (!vectors_left) {
pf->num_vmdq_msix = 0;
pf->num_vmdq_qps = 0;
} else {
int vmdq_vecs_wanted =
pf->num_vmdq_vsis * pf->num_vmdq_qps;
int vmdq_vecs =
min_t(int, vectors_left, vmdq_vecs_wanted);
/* if we're short on vectors for what's desired, we limit
* the queues per vmdq. If this is still more than are
* available, the user will need to change the number of
* queues/vectors used by the PF later with the ethtool
* channels command
*/
if (vmdq_vecs < vmdq_vecs_wanted)
if (vectors_left < vmdq_vecs_wanted) {
pf->num_vmdq_qps = 1;
vmdq_vecs_wanted = pf->num_vmdq_vsis;
vmdq_vecs = min_t(int,
vectors_left,
vmdq_vecs_wanted);
}
pf->num_vmdq_msix = pf->num_vmdq_qps;
v_budget += vmdq_vecs;

View File

@ -317,10 +317,12 @@ void i40e_ptp_rx_hang(struct i40e_pf *pf)
* This watchdog task is run periodically to make sure that we clear the Tx
* timestamp logic if we don't obtain a timestamp in a reasonable amount of
* time. It is unexpected in the normal case but if it occurs it results in
* permanently prevent timestamps of future packets
* permanently preventing timestamps of future packets.
**/
void i40e_ptp_tx_hang(struct i40e_pf *pf)
{
struct sk_buff *skb;
if (!(pf->flags & I40E_FLAG_PTP) || !pf->ptp_tx)
return;
@ -333,9 +335,12 @@ void i40e_ptp_tx_hang(struct i40e_pf *pf)
* within a second it is reasonable to assume that we never will.
*/
if (time_is_before_jiffies(pf->ptp_tx_start + HZ)) {
dev_kfree_skb_any(pf->ptp_tx_skb);
skb = pf->ptp_tx_skb;
pf->ptp_tx_skb = NULL;
clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, pf->state);
/* Free the skb after we clear the bitlock */
dev_kfree_skb_any(skb);
pf->tx_hwtstamp_timeouts++;
}
}

View File

@ -81,7 +81,6 @@ struct i40e_vsi {
#define I40E_TX_DESC(R, i) (&(((struct i40e_tx_desc *)((R)->desc))[i]))
#define I40E_TX_CTXTDESC(R, i) \
(&(((struct i40e_tx_context_desc *)((R)->desc))[i]))
#define MAX_QUEUES 16
#define I40EVF_MAX_REQ_QUEUES 4
#define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX + 1) * 4)

View File

@ -1,8 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2013 - 2018 Intel Corporation. */
#ifndef _I40E_CLIENT_H_
#define _I40E_CLIENT_H_
#ifndef _I40EVF_CLIENT_H_
#define _I40EVF_CLIENT_H_
#define I40EVF_CLIENT_STR_LENGTH 10
@ -166,4 +166,4 @@ struct i40e_client {
/* used by clients */
int i40evf_register_client(struct i40e_client *client);
int i40evf_unregister_client(struct i40e_client *client);
#endif /* _I40E_CLIENT_H_ */
#endif /* _I40EVF_CLIENT_H_ */

View File

@ -1925,7 +1925,8 @@ static void i40evf_reset_task(struct work_struct *work)
* ndo_open() returning, so we can't assume it means all our open
* tasks have finished, since we're not holding the rtnl_lock here.
*/
running = (adapter->state == __I40EVF_RUNNING);
running = ((adapter->state == __I40EVF_RUNNING) ||
(adapter->state == __I40EVF_RESETTING));
if (running) {
netif_carrier_off(netdev);
@ -2331,7 +2332,7 @@ static int i40evf_validate_ch_config(struct i40evf_adapter *adapter,
total_max_rate += tx_rate;
num_qps += mqprio_qopt->qopt.count[i];
}
if (num_qps > MAX_QUEUES)
if (num_qps > I40EVF_MAX_REQ_QUEUES)
return -EINVAL;
ret = i40evf_validate_tx_bandwidth(adapter, total_max_rate);
@ -3689,7 +3690,8 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
netdev = alloc_etherdev_mq(sizeof(struct i40evf_adapter), MAX_QUEUES);
netdev = alloc_etherdev_mq(sizeof(struct i40evf_adapter),
I40EVF_MAX_REQ_QUEUES);
if (!netdev) {
err = -ENOMEM;
goto err_alloc_etherdev;

View File

@ -485,7 +485,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);
struct virtchnl_rss_lut {
u16 vsi_id;
u16 lut_entries;
u8 lut[1]; /* RSS lookup table*/
u8 lut[1]; /* RSS lookup table */
};
VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);
@ -819,7 +819,7 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
return VIRTCHNL_ERR_PARAM;
}
/* few more checks */
if ((valid_len != msglen) || (err_msg_format))
if (err_msg_format || valid_len != msglen)
return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;
return 0;