* [net-next 05/11] ice: Avoid nested RTNL locking in ice_dis_vsi
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Dave Ertman, netdev, nhorman, sassmann, Anirudh Venkataramanan,
Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Dave Ertman <david.m.ertman@intel.com>
ice_dis_vsi() performs an rtnl_lock() if it detects a netdev that is
running on the VSI. In cases where the RTNL lock has already been
acquired, a deadlock results. Add a boolean to pass to ice_dis_vsi to
tell it if the RTNL lock is already held.
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_main.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index ea79e5e1f589..089b0f0b2e71 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3137,8 +3137,9 @@ static void ice_vsi_release_all(struct ice_pf *pf)
/**
* ice_dis_vsi - pause a VSI
* @vsi: the VSI being paused
+ * @locked: is the rtnl_lock already held
*/
-static void ice_dis_vsi(struct ice_vsi *vsi)
+static void ice_dis_vsi(struct ice_vsi *vsi, bool locked)
{
if (test_bit(__ICE_DOWN, vsi->state))
return;
@@ -3147,9 +3148,13 @@ static void ice_dis_vsi(struct ice_vsi *vsi)
if (vsi->type == ICE_VSI_PF && vsi->netdev) {
if (netif_running(vsi->netdev)) {
- rtnl_lock();
- vsi->netdev->netdev_ops->ndo_stop(vsi->netdev);
- rtnl_unlock();
+ if (!locked) {
+ rtnl_lock();
+ vsi->netdev->netdev_ops->ndo_stop(vsi->netdev);
+ rtnl_unlock();
+ } else {
+ vsi->netdev->netdev_ops->ndo_stop(vsi->netdev);
+ }
} else {
ice_vsi_close(vsi);
}
@@ -3188,7 +3193,7 @@ static void ice_pf_dis_all_vsi(struct ice_pf *pf)
ice_for_each_vsi(pf, v)
if (pf->vsi[v])
- ice_dis_vsi(pf->vsi[v]);
+ ice_dis_vsi(pf->vsi[v], false);
}
/**
--
2.19.1
^ permalink raw reply related
* [net-next 04/11] ice: Calculate guaranteed VSIs per function and use it
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Currently we are setting the guar_num_vsi to equal to ICE_MAX_VSI
which is the device limit of 768. This is incorrect and could have
unintended consequences. To fix this use the valid_function's 8-bit
bitmap returned from discovering device capabilities to determine the
guar_num_vsi per function. guar_num_vsi value is then passed on to
pf->num_alloc_vsi.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice.h | 1 -
.../net/ethernet/intel/ice/ice_adminq_cmd.h | 1 +
drivers/net/ethernet/intel/ice/ice_common.c | 31 +++++++++++++++++--
drivers/net/ethernet/intel/ice/ice_main.c | 3 +-
drivers/net/ethernet/intel/ice/ice_type.h | 4 ++-
5 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index b8548370f1c7..ba03cbd3638e 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -52,7 +52,6 @@ extern const char ice_drv_ver[];
#define ICE_MBXQ_LEN 64
#define ICE_MIN_MSIX 2
#define ICE_NO_VSI 0xffff
-#define ICE_MAX_VSI_ALLOC 130
#define ICE_MAX_TXQS 2048
#define ICE_MAX_RXQS 2048
#define ICE_VSI_MAP_CONTIG 0
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 6653555f55dd..602f02a0a2d1 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -87,6 +87,7 @@ struct ice_aqc_list_caps {
/* Device/Function buffer entry, repeated per reported capability */
struct ice_aqc_list_caps_elem {
__le16 cap;
+#define ICE_AQC_CAPS_VALID_FUNCTIONS 0x0005
#define ICE_AQC_CAPS_SRIOV 0x0012
#define ICE_AQC_CAPS_VF 0x0013
#define ICE_AQC_CAPS_VSI 0x0017
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 554fd707a6d6..9de5a3aac77d 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -1386,6 +1386,27 @@ void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
}
}
+/**
+ * ice_get_guar_num_vsi - determine number of guar VSI for a PF
+ * @hw: pointer to the hw structure
+ *
+ * Determine the number of valid functions by going through the bitmap returned
+ * from parsing capabilities and use this to calculate the number of VSI per PF.
+ */
+static u32 ice_get_guar_num_vsi(struct ice_hw *hw)
+{
+ u8 funcs;
+
+#define ICE_CAPS_VALID_FUNCS_M 0xFF
+ funcs = hweight8(hw->dev_caps.common_cap.valid_functions &
+ ICE_CAPS_VALID_FUNCS_M);
+
+ if (!funcs)
+ return 0;
+
+ return ICE_MAX_VSI / funcs;
+}
+
/**
* ice_parse_caps - parse function/device capabilities
* @hw: pointer to the hw struct
@@ -1428,6 +1449,12 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
u16 cap = le16_to_cpu(cap_resp->cap);
switch (cap) {
+ case ICE_AQC_CAPS_VALID_FUNCTIONS:
+ caps->valid_functions = number;
+ ice_debug(hw, ICE_DBG_INIT,
+ "HW caps: Valid Functions = %d\n",
+ caps->valid_functions);
+ break;
case ICE_AQC_CAPS_SRIOV:
caps->sr_iov_1_1 = (number == 1);
ice_debug(hw, ICE_DBG_INIT,
@@ -1457,10 +1484,10 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
"HW caps: Dev.VSI cnt = %d\n",
dev_p->num_vsi_allocd_to_host);
} else if (func_p) {
- func_p->guaranteed_num_vsi = number;
+ func_p->guar_num_vsi = ice_get_guar_num_vsi(hw);
ice_debug(hw, ICE_DBG_INIT,
"HW caps: Func.VSI cnt = %d\n",
- func_p->guaranteed_num_vsi);
+ number);
}
break;
case ICE_AQC_CAPS_RSS:
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 8584061e1bc6..ea79e5e1f589 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2091,8 +2091,7 @@ static int ice_probe(struct pci_dev *pdev,
ice_determine_q_usage(pf);
- pf->num_alloc_vsi = min_t(u16, ICE_MAX_VSI_ALLOC,
- hw->func_caps.guaranteed_num_vsi);
+ pf->num_alloc_vsi = hw->func_caps.guar_num_vsi;
if (!pf->num_alloc_vsi) {
err = -EIO;
goto err_init_pf_unroll;
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index f4dbc81c1988..0ea428104215 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -124,6 +124,8 @@ struct ice_phy_info {
/* Common HW capabilities for SW use */
struct ice_hw_common_caps {
+ u32 valid_functions;
+
/* TX/RX queues */
u16 num_rxq; /* Number/Total RX queues */
u16 rxq_first_id; /* First queue ID for RX queues */
@@ -150,7 +152,7 @@ struct ice_hw_func_caps {
struct ice_hw_common_caps common_cap;
u32 num_allocd_vfs; /* Number of allocated VFs */
u32 vf_base_id; /* Logical ID of the first VF */
- u32 guaranteed_num_vsi;
+ u32 guar_num_vsi;
};
/* Device wide capabilities */
--
2.19.1
^ permalink raw reply related
* [net-next 06/11] ice: Fix NVM mask defines
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Lev Faerman, netdev, nhorman, sassmann, Anirudh Venkataramanan,
Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Lev Faerman <lev.faerman@intel.com>
Fixes bad masks that would break compilation when evaluated.
Signed-off-by: Lev Faerman <lev.faerman@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 602f02a0a2d1..4078070881ce 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -1066,10 +1066,10 @@ struct ice_aqc_nvm {
#define ICE_AQC_NVM_LAST_CMD BIT(0)
#define ICE_AQC_NVM_PCIR_REQ BIT(0) /* Used by NVM Update reply */
#define ICE_AQC_NVM_PRESERVATION_S 1
-#define ICE_AQC_NVM_PRESERVATION_M (3 << CSR_AQ_NVM_PRESERVATION_S)
-#define ICE_AQC_NVM_NO_PRESERVATION (0 << CSR_AQ_NVM_PRESERVATION_S)
+#define ICE_AQC_NVM_PRESERVATION_M (3 << ICE_AQC_NVM_PRESERVATION_S)
+#define ICE_AQC_NVM_NO_PRESERVATION (0 << ICE_AQC_NVM_PRESERVATION_S)
#define ICE_AQC_NVM_PRESERVE_ALL BIT(1)
-#define ICE_AQC_NVM_PRESERVE_SELECTED (3 << CSR_AQ_NVM_PRESERVATION_S)
+#define ICE_AQC_NVM_PRESERVE_SELECTED (3 << ICE_AQC_NVM_PRESERVATION_S)
#define ICE_AQC_NVM_FLASH_ONLY BIT(7)
__le16 module_typeid;
__le16 length;
--
2.19.1
^ permalink raw reply related
* [net-next 08/11] ice: Call pci_disable_sriov before stopping queues for VF
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Brett Creeley, netdev, nhorman, sassmann, Anirudh Venkataramanan,
Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Brett Creeley <brett.creeley@intel.com>
Previous to this commit the driver was immediately stopping Tx/Rx
queues when doing the following "echo 0 > sriov_numvfs" and then it was
calling pci_disable_sriov if the VFs are not assigned. This was causing
the VIRTCHNL_OP_DISABLE_QUEUES to fail because it was trying to stop
the queues for a second time.
Fix this by calling pci_disable_sriov before stopping the Tx/Rx queues.
This allows the VIRTCHNL_OP_DISABLE_QUEUES to get processed before the
driver tries to stop the Rx/Tx queues in ice_free_vfs.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
index e71065f9d391..20b94dee0036 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
@@ -215,6 +215,15 @@ void ice_free_vfs(struct ice_pf *pf)
while (test_and_set_bit(__ICE_VF_DIS, pf->state))
usleep_range(1000, 2000);
+ /* Disable IOV before freeing resources. This lets any VF drivers
+ * running in the host get themselves cleaned up before we yank
+ * the carpet out from underneath their feet.
+ */
+ if (!pci_vfs_assigned(pf->pdev))
+ pci_disable_sriov(pf->pdev);
+ else
+ dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n");
+
/* Avoid wait time by stopping all VFs at the same time */
for (i = 0; i < pf->num_alloc_vfs; i++) {
if (!test_bit(ICE_VF_STATE_ENA, pf->vf[i].vf_states))
@@ -228,15 +237,6 @@ void ice_free_vfs(struct ice_pf *pf)
clear_bit(ICE_VF_STATE_ENA, pf->vf[i].vf_states);
}
- /* Disable IOV before freeing resources. This lets any VF drivers
- * running in the host get themselves cleaned up before we yank
- * the carpet out from underneath their feet.
- */
- if (!pci_vfs_assigned(pf->pdev))
- pci_disable_sriov(pf->pdev);
- else
- dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n");
-
tmp = pf->num_alloc_vfs;
pf->num_vf_qps = 0;
pf->num_alloc_vfs = 0;
--
2.19.1
^ permalink raw reply related
* [net-next 10/11] ice: Destroy scheduler tree in reset path
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Henry Tieman, netdev, nhorman, sassmann, Anirudh Venkataramanan,
Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Henry Tieman <henry.w.tieman@intel.com>
The scheduler tree is is always rebuilt during reset. The existing code
adds new scheduler nodes for queues but may not clean up earlier nodes.
This patch removed the old scheduler tree during reset before it is
rebuilt.
Signed-off-by: Henry Tieman <henry.w.tieman@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 597005f39919..53685a66125b 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2551,6 +2551,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
return -EINVAL;
pf = vsi->back;
+ ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
ice_vsi_free_q_vectors(vsi);
ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
--
2.19.1
^ permalink raw reply related
* [net-next 11/11] ice: Remove ICE_MAX_TXQ_PER_TXQG check when configuring Tx queue
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Md Fahad Iqbal Polash, netdev, nhorman, sassmann,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Md Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
This patch removes the condition checking of VSI TX queue number to
ICE_MAX_TXQ_PER_TXQG. This is an unnecessary check and causes a driver
load error on hosts that have more than 128 cores.
Signed-off-by: Md Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 53685a66125b..a5961a8fe73c 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1633,10 +1633,6 @@ int ice_vsi_cfg_txqs(struct ice_vsi *vsi)
if (!qg_buf)
return -ENOMEM;
- if (vsi->num_txq > ICE_MAX_TXQ_PER_TXQG) {
- err = -EINVAL;
- goto err_cfg_txqs;
- }
qg_buf->num_txqs = 1;
num_q_grps = 1;
--
2.19.1
^ permalink raw reply related
* [net-next 09/11] ice: Fix to make VLAN priority tagged traffic to appear on all TCs
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Usha Ketineni, netdev, nhorman, sassmann, Anirudh Venkataramanan,
Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Usha Ketineni <usha.k.ketineni@intel.com>
This patch includes below changes to resolve the issue of ETS bandwidth
shaping to work.
1. Allocation of Tx queues is accounted for based on the enabled TC's
in ice_vsi_setup_q_map() and enabled the Tx queues on those TC's via
ice_vsi_cfg_txqs()
2. Get the mapped netdev TC # for the user priority and set the priority
to TC mapping for the VSI.
Signed-off-by: Usha Ketineni <usha.k.ketineni@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice.h | 4 +-
drivers/net/ethernet/intel/ice/ice_lib.c | 121 +++++++++++++--------
drivers/net/ethernet/intel/ice/ice_main.c | 4 +-
drivers/net/ethernet/intel/ice/ice_sched.c | 2 +-
drivers/net/ethernet/intel/ice/ice_sched.h | 1 +
5 files changed, 81 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index ba03cbd3638e..7d8575d11786 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -112,7 +112,9 @@ extern const char ice_drv_ver[];
struct ice_tc_info {
u16 qoffset;
- u16 qcount;
+ u16 qcount_tx;
+ u16 qcount_rx;
+ u8 netdev_tc;
};
struct ice_tc_cfg {
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index f6e21363c8d6..597005f39919 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -774,11 +774,13 @@ static void ice_set_dflt_vsi_ctx(struct ice_vsi_ctx *ctxt)
*/
static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
{
- u16 offset = 0, qmap = 0, numq_tc;
- u16 pow = 0, max_rss = 0, qcount;
+ u16 offset = 0, qmap = 0, tx_count = 0;
u16 qcount_tx = vsi->alloc_txq;
u16 qcount_rx = vsi->alloc_rxq;
+ u16 tx_numq_tc, rx_numq_tc;
+ u16 pow = 0, max_rss = 0;
bool ena_tc0 = false;
+ u8 netdev_tc = 0;
int i;
/* at least TC0 should be enabled by default */
@@ -794,7 +796,12 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
vsi->tc_cfg.ena_tc |= 1;
}
- numq_tc = qcount_rx / vsi->tc_cfg.numtc;
+ rx_numq_tc = qcount_rx / vsi->tc_cfg.numtc;
+ if (!rx_numq_tc)
+ rx_numq_tc = 1;
+ tx_numq_tc = qcount_tx / vsi->tc_cfg.numtc;
+ if (!tx_numq_tc)
+ tx_numq_tc = 1;
/* TC mapping is a function of the number of Rx queues assigned to the
* VSI for each traffic class and the offset of these queues.
@@ -808,7 +815,8 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
* Setup number and offset of Rx queues for all TCs for the VSI
*/
- qcount = numq_tc;
+ qcount_rx = rx_numq_tc;
+
/* qcount will change if RSS is enabled */
if (test_bit(ICE_FLAG_RSS_ENA, vsi->back->flags)) {
if (vsi->type == ICE_VSI_PF || vsi->type == ICE_VSI_VF) {
@@ -816,37 +824,41 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
max_rss = ICE_MAX_LG_RSS_QS;
else
max_rss = ICE_MAX_SMALL_RSS_QS;
- qcount = min_t(int, numq_tc, max_rss);
- qcount = min_t(int, qcount, vsi->rss_size);
+ qcount_rx = min_t(int, rx_numq_tc, max_rss);
+ qcount_rx = min_t(int, qcount_rx, vsi->rss_size);
}
}
/* find the (rounded up) power-of-2 of qcount */
- pow = order_base_2(qcount);
+ pow = order_base_2(qcount_rx);
for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
if (!(vsi->tc_cfg.ena_tc & BIT(i))) {
/* TC is not enabled */
vsi->tc_cfg.tc_info[i].qoffset = 0;
- vsi->tc_cfg.tc_info[i].qcount = 1;
+ vsi->tc_cfg.tc_info[i].qcount_rx = 1;
+ vsi->tc_cfg.tc_info[i].qcount_tx = 1;
+ vsi->tc_cfg.tc_info[i].netdev_tc = 0;
ctxt->info.tc_mapping[i] = 0;
continue;
}
/* TC is enabled */
vsi->tc_cfg.tc_info[i].qoffset = offset;
- vsi->tc_cfg.tc_info[i].qcount = qcount;
+ vsi->tc_cfg.tc_info[i].qcount_rx = qcount_rx;
+ vsi->tc_cfg.tc_info[i].qcount_tx = tx_numq_tc;
+ vsi->tc_cfg.tc_info[i].netdev_tc = netdev_tc++;
qmap = ((offset << ICE_AQ_VSI_TC_Q_OFFSET_S) &
ICE_AQ_VSI_TC_Q_OFFSET_M) |
((pow << ICE_AQ_VSI_TC_Q_NUM_S) &
ICE_AQ_VSI_TC_Q_NUM_M);
- offset += qcount;
+ offset += qcount_rx;
+ tx_count += tx_numq_tc;
ctxt->info.tc_mapping[i] = cpu_to_le16(qmap);
}
-
- vsi->num_txq = qcount_tx;
vsi->num_rxq = offset;
+ vsi->num_txq = tx_count;
if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) {
dev_dbg(&vsi->back->pdev->dev, "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n");
@@ -1611,10 +1623,10 @@ int ice_vsi_cfg_txqs(struct ice_vsi *vsi)
struct ice_aqc_add_tx_qgrp *qg_buf;
struct ice_aqc_add_txqs_perq *txq;
struct ice_pf *pf = vsi->back;
+ u8 num_q_grps, q_idx = 0;
enum ice_status status;
u16 buf_len, i, pf_q;
int err = 0, tc = 0;
- u8 num_q_grps;
buf_len = sizeof(struct ice_aqc_add_tx_qgrp);
qg_buf = devm_kzalloc(&pf->pdev->dev, buf_len, GFP_KERNEL);
@@ -1628,38 +1640,49 @@ int ice_vsi_cfg_txqs(struct ice_vsi *vsi)
qg_buf->num_txqs = 1;
num_q_grps = 1;
- /* set up and configure the Tx queues */
- ice_for_each_txq(vsi, i) {
- struct ice_tlan_ctx tlan_ctx = { 0 };
+ /* set up and configure the Tx queues for each enabled TC */
+ for (tc = 0; tc < ICE_MAX_TRAFFIC_CLASS; tc++) {
+ if (!(vsi->tc_cfg.ena_tc & BIT(tc)))
+ break;
- pf_q = vsi->txq_map[i];
- ice_setup_tx_ctx(vsi->tx_rings[i], &tlan_ctx, pf_q);
- /* copy context contents into the qg_buf */
- qg_buf->txqs[0].txq_id = cpu_to_le16(pf_q);
- ice_set_ctx((u8 *)&tlan_ctx, qg_buf->txqs[0].txq_ctx,
- ice_tlan_ctx_info);
+ for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) {
+ struct ice_tlan_ctx tlan_ctx = { 0 };
+
+ pf_q = vsi->txq_map[q_idx];
+ ice_setup_tx_ctx(vsi->tx_rings[q_idx], &tlan_ctx,
+ pf_q);
+ /* copy context contents into the qg_buf */
+ qg_buf->txqs[0].txq_id = cpu_to_le16(pf_q);
+ ice_set_ctx((u8 *)&tlan_ctx, qg_buf->txqs[0].txq_ctx,
+ ice_tlan_ctx_info);
+
+ /* init queue specific tail reg. It is referred as
+ * transmit comm scheduler queue doorbell.
+ */
+ vsi->tx_rings[q_idx]->tail =
+ pf->hw.hw_addr + QTX_COMM_DBELL(pf_q);
+ status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc,
+ num_q_grps, qg_buf, buf_len,
+ NULL);
+ if (status) {
+ dev_err(&vsi->back->pdev->dev,
+ "Failed to set LAN Tx queue context, error: %d\n",
+ status);
+ err = -ENODEV;
+ goto err_cfg_txqs;
+ }
- /* init queue specific tail reg. It is referred as transmit
- * comm scheduler queue doorbell.
- */
- vsi->tx_rings[i]->tail = pf->hw.hw_addr + QTX_COMM_DBELL(pf_q);
- status = ice_ena_vsi_txq(vsi->port_info, vsi->idx, tc,
- num_q_grps, qg_buf, buf_len, NULL);
- if (status) {
- dev_err(&vsi->back->pdev->dev,
- "Failed to set LAN Tx queue context, error: %d\n",
- status);
- err = -ENODEV;
- goto err_cfg_txqs;
- }
+ /* Add Tx Queue TEID into the VSI Tx ring from the
+ * response. This will complete configuring and
+ * enabling the queue.
+ */
+ txq = &qg_buf->txqs[0];
+ if (pf_q == le16_to_cpu(txq->txq_id))
+ vsi->tx_rings[q_idx]->txq_teid =
+ le32_to_cpu(txq->q_teid);
- /* Add Tx Queue TEID into the VSI Tx ring from the response
- * This will complete configuring and enabling the queue.
- */
- txq = &qg_buf->txqs[0];
- if (pf_q == le16_to_cpu(txq->txq_id))
- vsi->tx_rings[i]->txq_teid =
- le32_to_cpu(txq->q_teid);
+ q_idx++;
+ }
}
err_cfg_txqs:
devm_kfree(&pf->pdev->dev, qg_buf);
@@ -2057,6 +2080,9 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
/* set RSS capabilities */
ice_vsi_set_rss_params(vsi);
+ /* set tc configuration */
+ ice_vsi_set_tc_cfg(vsi);
+
/* create the VSI */
ret = ice_vsi_init(vsi);
if (ret)
@@ -2120,11 +2146,9 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
goto unroll_vsi_init;
}
- ice_vsi_set_tc_cfg(vsi);
-
/* configure VSI nodes based on number of queues and TC's */
for (i = 0; i < vsi->tc_cfg.numtc; i++)
- max_txqs[i] = vsi->num_txq;
+ max_txqs[i] = pf->num_lan_tx;
ret = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
max_txqs);
@@ -2520,11 +2544,13 @@ int ice_vsi_release(struct ice_vsi *vsi)
int ice_vsi_rebuild(struct ice_vsi *vsi)
{
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
+ struct ice_pf *pf;
int ret, i;
if (!vsi)
return -EINVAL;
+ pf = vsi->back;
ice_vsi_free_q_vectors(vsi);
ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
@@ -2534,6 +2560,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
ice_vsi_free_arrays(vsi, false);
ice_dev_onetime_setup(&vsi->back->hw);
ice_vsi_set_num_qs(vsi);
+ ice_vsi_set_tc_cfg(vsi);
/* Initialize VSI struct elements and create VSI in FW */
ret = ice_vsi_init(vsi);
@@ -2580,11 +2607,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
break;
}
- ice_vsi_set_tc_cfg(vsi);
-
/* configure VSI nodes based on number of queues and TC's */
for (i = 0; i < vsi->tc_cfg.numtc; i++)
- max_txqs[i] = vsi->num_txq;
+ max_txqs[i] = pf->num_lan_tx;
ret = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
max_txqs);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 089b0f0b2e71..292d19e65af0 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -349,6 +349,9 @@ ice_prepare_for_reset(struct ice_pf *pf)
/* disable the VSIs and their queues that are not already DOWN */
ice_pf_dis_all_vsi(pf);
+ if (hw->port_info)
+ ice_sched_clear_port(hw->port_info);
+
ice_shutdown_all_ctrlq(hw);
set_bit(__ICE_PREPARED_FOR_RESET, pf->state);
@@ -2543,7 +2546,6 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)
if (err)
return err;
}
-
err = ice_vsi_cfg_txqs(vsi);
if (!err)
err = ice_vsi_cfg_rxqs(vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
index 7e807b0e7514..7293e4f4d758 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.c
+++ b/drivers/net/ethernet/intel/ice/ice_sched.c
@@ -630,7 +630,7 @@ static void ice_sched_clear_tx_topo(struct ice_port_info *pi)
*
* Cleanup scheduling elements from SW DB
*/
-static void ice_sched_clear_port(struct ice_port_info *pi)
+void ice_sched_clear_port(struct ice_port_info *pi)
{
if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
return;
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.h b/drivers/net/ethernet/intel/ice/ice_sched.h
index dc59fbac7dde..da5b4c166da8 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.h
+++ b/drivers/net/ethernet/intel/ice/ice_sched.h
@@ -26,6 +26,7 @@ struct ice_sched_agg_info {
/* FW AQ command calls */
enum ice_status ice_sched_init_port(struct ice_port_info *pi);
enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw);
+void ice_sched_clear_port(struct ice_port_info *pi);
void ice_sched_cleanup_all(struct ice_hw *hw);
struct ice_sched_node *
ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);
--
2.19.1
^ permalink raw reply related
* [net-next 07/11] ice: Increase Rx queue disable timeout
From: Jeff Kirsher @ 2018-11-13 18:32 UTC (permalink / raw)
To: davem
Cc: Piotr Raczynski, netdev, nhorman, sassmann,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181113183239.5861-1-jeffrey.t.kirsher@intel.com>
From: Piotr Raczynski <piotr.raczynski@intel.com>
With much traffic coming into the port, Rx queue disable
procedure can take more time until all pending queue
requests on PCIe finish. Reuse ICE_Q_WAIT_MAX_RETRY macro
and increase the delay itself.
Signed-off-by: Piotr Raczynski <piotr.raczynski@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 1efd760debc2..f6e21363c8d6 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -174,15 +174,15 @@ static int ice_pf_rxq_wait(struct ice_pf *pf, int pf_q, bool ena)
{
int i;
- for (i = 0; i < ICE_Q_WAIT_RETRY_LIMIT; i++) {
+ for (i = 0; i < ICE_Q_WAIT_MAX_RETRY; i++) {
u32 rx_reg = rd32(&pf->hw, QRX_CTRL(pf_q));
if (ena == !!(rx_reg & QRX_CTRL_QENA_STAT_M))
break;
- usleep_range(10, 20);
+ usleep_range(20, 40);
}
- if (i >= ICE_Q_WAIT_RETRY_LIMIT)
+ if (i >= ICE_Q_WAIT_MAX_RETRY)
return -ETIMEDOUT;
return 0;
--
2.19.1
^ permalink raw reply related
* Re: [Patch net-next v2] net: dump more useful information in netdev_rx_csum_fault()
From: Willem de Bruijn @ 2018-11-13 19:13 UTC (permalink / raw)
To: Cong Wang; +Cc: Network Development
In-Reply-To: <CAM_iQpUL8+oY67b+zFyEEkgzGO=msdUmAw5FvsrO0gLcpBJ8kA@mail.gmail.com>
On Tue, Nov 13, 2018 at 10:14 AM Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
> On Tue, Nov 13, 2018 at 10:01 AM Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
> >
> > On Mon, Nov 12, 2018 at 2:49 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > >
> > > Currently netdev_rx_csum_fault() only shows a device name,
> > > we need more information about the skb for debugging csum
> > > failures.
> > >
> > > Sample output:
> > >
> > > ens3: hw csum failure
> > > dev features: 0x0000000000014b89
> > > skb len=84 data_len=0 pkt_type=0 gso_size=0 gso_type=0 nr_frags=0 ip_summed=0 csum=0 csum_complete_sw=0 csum_valid=0 csum_level=0
> >
> > Recent issues were protocol dependent, including whether vlan headers
> > were present. Perhaps also print skb vlan fields and even the first N
> > bytes of data to inspect protocol headers? Also skb_iif, esp. if this
> > differs from dev->ifindex.
>
> Pawel's case seems to be vlan related, however, as I mentioned,
> my case is neither vlan nor RXFCS related.
>
> Ideally, we should dump the whole packet in order to verify the
> correctness of the checksum. :) It is not easy to do so given
> how complex an skb is now. This is why I only select a few skb
> fields to dump. I am pretty sure this can't cover all cases, you
> can always add more for your need in the future.
Sounds good. This patch is definitely useful as is.
Also, instead of adding code to print a (partial) packet header to
the kernel log, it may make more sense to export the skb to a
drop monitor over netlink or a perf buffer.
^ permalink raw reply
* Re: [PATCH net] ipvs: call ip_vs_dst_notifier before ipv6_dev_notf
From: Julian Anastasov @ 2018-11-13 19:51 UTC (permalink / raw)
To: Xin Long
Cc: network dev, netfilter-devel, David S. Miller, pablo,
Hans Schillstrom, Simon Horman
In-Reply-To: <4bfc74f2a94e3721afd5ee4dd3cb60f8e4b68c7c.1542129933.git.lucien.xin@gmail.com>
Hello,
On Wed, 14 Nov 2018, Xin Long wrote:
> ip_vs_dst_event is supposed to clean up all dst used in ipvs'
> destinations when a net dev is going down. But it works only
> when the dst's dev is the same as the dev from the event.
>
> Now with the same priority but late registration,
> ip_vs_dst_notifier is always called after ipv6_dev_notf where
> the dst's dev is set to lo for NETDEV_DOWN event.
>
> As the dst's dev lo is not the same as the dev from the event
> in ip_vs_dst_event(), ipv6_dev_notf can actually never work.
> Also as these dst have to wait for dest_trash_timer to clean
> them up. It would cause some non-permanent kernel warnings:
>
> unregister_netdevice: waiting for br0 to become free. Usage count = 3
>
> To fix it, call ip_vs_dst_notifier before ipv6_dev_notf by
> increasing its priority to ADDRCONF_NOTIFY_PRIORITY + 5.
>
> Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring")
> Reported-by: Li Shuang <shuali@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
OK,
Acked-by: Julian Anastasov <ja@ssi.bg>
But this fix may hide another problem...
Isn't that racy to change dst.dev during NETDEV_DOWN?
IPv4 calls rt_flush_dev() only on NETDEV_UNREGISTER, while
rt6_uncached_list_flush_dev() is called in rt6_disable_ip(),
even on NETDEV_DOWN. How fatal is to call it only on
NETDEV_UNREGISTER? By this way, we rely on synchronize_net()
before the NETDEV_UNREGISTER event to avoid any dst.dev access.
> ---
> net/netfilter/ipvs/ip_vs_ctl.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> index 83395bf6..aded477 100644
> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
> @@ -3980,6 +3980,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs)
>
> static struct notifier_block ip_vs_dst_notifier = {
> .notifier_call = ip_vs_dst_event,
> + .priority = ADDRCONF_NOTIFY_PRIORITY + 5,
> };
>
> int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs)
> --
> 2.1.0
Regards
^ permalink raw reply
* [PATCH v3] net: Add trace events for all receive exit points
From: Geneviève Bastien @ 2018-11-13 20:13 UTC (permalink / raw)
To: gbastien
Cc: netdev, Mathieu Desnoyers, Steven Rostedt, Ingo Molnar,
David S . Miller
Trace events are already present for the receive entry points, to indicate
how the reception entered the stack.
This patch adds the corresponding exit trace events that will bound the
reception such that all events occurring between the entry and the exit
can be considered as part of the reception context. This greatly helps
for dependency and root cause analyses.
Without this, it is not possible with tracepoint instrumentation to
determine whether a sched_wakeup event following a netif_receive_skb
event is the result of the packet reception or a simple coincidence after
further processing by the thread. It is possible using other mechanisms
like kretprobes, but considering the "entry" points are already present,
it would be good to add the matching exit events.
In addition to linking packets with wakeups, the entry/exit event pair
can also be used to perform network stack latency analyses.
Signed-off-by: Geneviève Bastien <gbastien@versatic.net>
CC: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ingo Molnar <mingo@redhat.com>
CC: David S. Miller <davem@davemloft.net>
Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> (tracing
side)
---
Changes in v3:
- Update commit message
- Rename exit template to match the entry one
- Move the similar tracepoints together in the code
---
Changes in v2:
- Add the return value to tracepoints where applicable
- Verify if tracepoint is enabled before walking list in
netif_receive_skb_list
---
include/trace/events/net.h | 71 ++++++++++++++++++++++++++++++++++++++
net/core/dev.c | 38 ++++++++++++++++----
2 files changed, 103 insertions(+), 6 deletions(-)
diff --git a/include/trace/events/net.h b/include/trace/events/net.h
index 00aa72ce0e7c..aa64169c42cb 100644
--- a/include/trace/events/net.h
+++ b/include/trace/events/net.h
@@ -244,6 +244,77 @@ DEFINE_EVENT(net_dev_rx_verbose_template, netif_rx_ni_entry,
TP_ARGS(skb)
);
+DECLARE_EVENT_CLASS(net_dev_rx_exit_template,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret),
+
+ TP_STRUCT__entry(
+ __field(void *, skbaddr)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->skbaddr = skb;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("skbaddr=%p ret=%d", __entry->skbaddr, __entry->ret)
+);
+
+DEFINE_EVENT(net_dev_rx_exit_template, napi_gro_frags_exit,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret)
+);
+
+DEFINE_EVENT(net_dev_rx_exit_template, napi_gro_receive_exit,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret)
+);
+
+DEFINE_EVENT(net_dev_rx_exit_template, netif_receive_skb_exit,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret)
+);
+
+DEFINE_EVENT(net_dev_rx_exit_template, netif_rx_exit,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret)
+);
+
+DEFINE_EVENT(net_dev_rx_exit_template, netif_rx_ni_exit,
+
+ TP_PROTO(struct sk_buff *skb, int ret),
+
+ TP_ARGS(skb, ret)
+);
+
+TRACE_EVENT(netif_receive_skb_list_exit,
+
+ TP_PROTO(struct sk_buff *skb),
+
+ TP_ARGS(skb),
+
+ TP_STRUCT__entry(
+ __field(void *, skbaddr)
+ ),
+
+ TP_fast_assign(
+ __entry->skbaddr = skb;
+ ),
+
+ TP_printk("skbaddr=%p", __entry->skbaddr)
+);
+
#endif /* _TRACE_NET_H */
/* This part must be outside protection */
diff --git a/net/core/dev.c b/net/core/dev.c
index 0ffcbdd55fa9..c4dc5df34abe 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4520,9 +4520,14 @@ static int netif_rx_internal(struct sk_buff *skb)
int netif_rx(struct sk_buff *skb)
{
+ int ret;
+
trace_netif_rx_entry(skb);
- return netif_rx_internal(skb);
+ ret = netif_rx_internal(skb);
+ trace_netif_rx_exit(skb, ret);
+
+ return ret;
}
EXPORT_SYMBOL(netif_rx);
@@ -4537,6 +4542,7 @@ int netif_rx_ni(struct sk_buff *skb)
if (local_softirq_pending())
do_softirq();
preempt_enable();
+ trace_netif_rx_ni_exit(skb, err);
return err;
}
@@ -5222,9 +5228,14 @@ static void netif_receive_skb_list_internal(struct list_head *head)
*/
int netif_receive_skb(struct sk_buff *skb)
{
+ int ret;
+
trace_netif_receive_skb_entry(skb);
- return netif_receive_skb_internal(skb);
+ ret = netif_receive_skb_internal(skb);
+ trace_netif_receive_skb_exit(skb, ret);
+
+ return ret;
}
EXPORT_SYMBOL(netif_receive_skb);
@@ -5244,9 +5255,15 @@ void netif_receive_skb_list(struct list_head *head)
if (list_empty(head))
return;
- list_for_each_entry(skb, head, list)
- trace_netif_receive_skb_list_entry(skb);
+ if (trace_netif_receive_skb_list_entry_enabled()) {
+ list_for_each_entry(skb, head, list)
+ trace_netif_receive_skb_list_entry(skb);
+ }
netif_receive_skb_list_internal(head);
+ if (trace_netif_receive_skb_list_exit_enabled()) {
+ list_for_each_entry(skb, head, list)
+ trace_netif_receive_skb_list_exit(skb);
+ }
}
EXPORT_SYMBOL(netif_receive_skb_list);
@@ -5634,12 +5651,17 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
+ gro_result_t ret;
+
skb_mark_napi_id(skb, napi);
trace_napi_gro_receive_entry(skb);
skb_gro_reset_offset(skb);
- return napi_skb_finish(dev_gro_receive(napi, skb), skb);
+ ret = napi_skb_finish(dev_gro_receive(napi, skb), skb);
+ trace_napi_gro_receive_exit(skb, ret);
+
+ return ret;
}
EXPORT_SYMBOL(napi_gro_receive);
@@ -5753,6 +5775,7 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
gro_result_t napi_gro_frags(struct napi_struct *napi)
{
+ gro_result_t ret;
struct sk_buff *skb = napi_frags_skb(napi);
if (!skb)
@@ -5760,7 +5783,10 @@ gro_result_t napi_gro_frags(struct napi_struct *napi)
trace_napi_gro_frags_entry(skb);
- return napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
+ ret = napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
+ trace_napi_gro_frags_exit(skb, ret);
+
+ return ret;
}
EXPORT_SYMBOL(napi_gro_frags);
--
2.19.1
^ permalink raw reply related
* [PATCH] net: phy: mdio-gpio: fix access that may sleep
From: Martin Schiller @ 2018-11-14 6:17 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: andrew, f.fainelli, davem, Martin Schiller
This commit re-enables support for slow GPIO pins. It was initially
introduced by commit
2d6c9091ab7630dfcf34417c6683ce4764d7d40a
and got lost by commit
7e5fbd1e0700f1bdb94508f84ec2aeb01eed7b12
Also add a warning about slow GPIO pins like it is done in i2c-gpio.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
drivers/net/phy/mdio-gpio.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 33265747bf39..d4430631ca6a 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -63,7 +63,7 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
* assume the pin serves as pull-up. If direction is
* output, the default value is high.
*/
- gpiod_set_value(bitbang->mdo, 1);
+ gpiod_set_value_cansleep(bitbang->mdo, 1);
return;
}
@@ -78,7 +78,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- return gpiod_get_value(bitbang->mdio);
+ return gpiod_get_value_cansleep(bitbang->mdio);
}
static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
@@ -87,9 +87,9 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
container_of(ctrl, struct mdio_gpio_info, ctrl);
if (bitbang->mdo)
- gpiod_set_value(bitbang->mdo, what);
+ gpiod_set_value_cansleep(bitbang->mdo, what);
else
- gpiod_set_value(bitbang->mdio, what);
+ gpiod_set_value_cansleep(bitbang->mdio, what);
}
static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
@@ -97,7 +97,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- gpiod_set_value(bitbang->mdc, what);
+ gpiod_set_value_cansleep(bitbang->mdc, what);
}
static const struct mdiobb_ops mdio_gpio_ops = {
@@ -162,6 +162,11 @@ static int mdio_gpio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (gpiod_cansleep(bitbang->mdc) || gpiod_cansleep(bitbang->mdio)
+ || gpiod_cansleep(bitbang->mdo))
+ dev_warn(&pdev->dev, "Slow GPIO pins might wreak havoc into"
+ "I2C/SMBus bus timing");
+
if (pdev->dev.of_node) {
bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
if (bus_id < 0) {
--
2.11.0
^ permalink raw reply related
* [PATCH v2] net: phy: mdio-gpio: fix access that may sleep
From: Martin Schiller @ 2018-11-14 6:37 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: andrew, f.fainelli, davem, Martin Schiller
In-Reply-To: <20181114061703.11026-1-ms@dev.tdt.de>
This commit re-enables support for slow GPIO pins. It was initially
introduced by commit
2d6c9091ab7630dfcf34417c6683ce4764d7d40a
and got lost by commit
7e5fbd1e0700f1bdb94508f84ec2aeb01eed7b12
Also add a warning about slow GPIO pins like it is done in i2c-gpio.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
v2:
- fixed copy/paste bug in warning about slow GPIO pins
---
drivers/net/phy/mdio-gpio.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 33265747bf39..6c1cca14689b 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -63,7 +63,7 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
* assume the pin serves as pull-up. If direction is
* output, the default value is high.
*/
- gpiod_set_value(bitbang->mdo, 1);
+ gpiod_set_value_cansleep(bitbang->mdo, 1);
return;
}
@@ -78,7 +78,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- return gpiod_get_value(bitbang->mdio);
+ return gpiod_get_value_cansleep(bitbang->mdio);
}
static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
@@ -87,9 +87,9 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
container_of(ctrl, struct mdio_gpio_info, ctrl);
if (bitbang->mdo)
- gpiod_set_value(bitbang->mdo, what);
+ gpiod_set_value_cansleep(bitbang->mdo, what);
else
- gpiod_set_value(bitbang->mdio, what);
+ gpiod_set_value_cansleep(bitbang->mdio, what);
}
static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
@@ -97,7 +97,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
struct mdio_gpio_info *bitbang =
container_of(ctrl, struct mdio_gpio_info, ctrl);
- gpiod_set_value(bitbang->mdc, what);
+ gpiod_set_value_cansleep(bitbang->mdc, what);
}
static const struct mdiobb_ops mdio_gpio_ops = {
@@ -162,6 +162,11 @@ static int mdio_gpio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (gpiod_cansleep(bitbang->mdc) || gpiod_cansleep(bitbang->mdio)
+ || gpiod_cansleep(bitbang->mdo))
+ dev_warn(&pdev->dev, "Slow GPIO pins might wreak havoc into"
+ "MDIO bus timing");
+
if (pdev->dev.of_node) {
bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
if (bus_id < 0) {
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 net-next 18/21] net: usb: aqc111: Implement get/set_link_ksettings callbacks
From: Andrew Lunn @ 2018-11-13 20:50 UTC (permalink / raw)
To: Igor Russkikh
Cc: David S . Miller, linux-usb@vger.kernel.org,
netdev@vger.kernel.org, Dmitry Bezrukov
In-Reply-To: <d1c116dba2a3362efccb56d402f03618fb961706.1542119058.git.igor.russkikh@aquantia.com>
On Tue, Nov 13, 2018 at 02:45:13PM +0000, Igor Russkikh wrote:
> +static int aqc111_get_link_ksettings(struct net_device *net,
> + struct ethtool_link_ksettings *elk)
> +{
> + struct usbnet *dev = netdev_priv(net);
> + struct aqc111_data *aqc111_data = dev->driver_priv;
> + enum usb_device_speed usb_speed = dev->udev->speed;
> + u32 speed = SPEED_UNKNOWN;
> +
> + ethtool_link_ksettings_zero_link_mode(elk, supported);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> + 100baseT_Full);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> + 1000baseT_Full);
> + if (usb_speed == USB_SPEED_SUPER) {
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> + 2500baseT_Full);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> + 5000baseT_Full);
> + }
Hi Igor
We discussed this with the first version of the patches. I think you
should add a comment explaining why 2.5G and 5G is disabled unless
Super speed is available.
> + if (aqc111_data->autoneg)
> + bitmap_copy(elk->link_modes.advertising,
> + elk->link_modes.supported,
> + __ETHTOOL_LINK_MODE_MASK_NBITS);
linkmode_copy(). It is quite new, so you probably don't know about it.
Andrew
^ permalink raw reply
* Re: [PATCH v2 net-next 06/21] net: usb: aqc111: Introduce link management
From: Andrew Lunn @ 2018-11-13 20:58 UTC (permalink / raw)
To: Igor Russkikh
Cc: David S . Miller, linux-usb@vger.kernel.org,
netdev@vger.kernel.org, Dmitry Bezrukov
In-Reply-To: <cb00d2c12713bd3973f36b4ad46e4574fa26a774.1542119058.git.igor.russkikh@aquantia.com>
On Tue, Nov 13, 2018 at 02:44:45PM +0000, Igor Russkikh wrote:
> From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
>
> Add full hardware initialization sequence and link configuration logic
Hi Igor
I'm still not convinced the PHY driver should be embedded in the MAC
driver, rather than using phylink.
If i remember correctly, it was because the MAC is involved in
determining if the link is up? That is nothing new. phylink expects
this. The MAC driver should call phylink_mac_change() when the MACs
SERDES goes up/down.
Andrew
^ permalink raw reply
* Re: [PATCH v2 net-next 19/21] net: usb: aqc111: Add support for wake on LAN by MAGIC packet
From: Andrew Lunn @ 2018-11-13 21:02 UTC (permalink / raw)
To: Igor Russkikh
Cc: David S . Miller, linux-usb@vger.kernel.org,
netdev@vger.kernel.org, Dmitry Bezrukov
In-Reply-To: <ba4572f1eae5c93fa643520647ea214bcef79b1e.1542119058.git.igor.russkikh@aquantia.com>
> +static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
> +{
> +
> + if (aqc111_data->dpa) {
> + aqc111_set_phy_speed(dev, AUTONEG_ENABLE, SPEED_100);
So this is better, you leave auto-neg enabled. But you really should
be taking the link partners capabilities into account.
Andrew
^ permalink raw reply
* Re: [PATCH v2] net: phy: mdio-gpio: fix access that may sleep
From: Andrew Lunn @ 2018-11-14 7:05 UTC (permalink / raw)
To: Martin Schiller; +Cc: netdev, linux-kernel, f.fainelli, davem
In-Reply-To: <20181114063703.13379-1-ms@dev.tdt.de>
On Wed, Nov 14, 2018 at 07:37:03AM +0100, Martin Schiller wrote:
> This commit re-enables support for slow GPIO pins. It was initially
> introduced by commit
> 2d6c9091ab7630dfcf34417c6683ce4764d7d40a
> and got lost by commit
> 7e5fbd1e0700f1bdb94508f84ec2aeb01eed7b12
Hi Martin
Was it really lost? It looks like _cansleep() just adds an extra check
might_sleep_if(extra_checks), but it does not change any
functionality.
So the change itself is O.K, i'm just not too sure about the commit
message.
Andrew
^ permalink raw reply
* Re: [PATCH] brcmfmac: Use standard SKB list accessors in brcmf_sdiod_sglist_rw.
From: Arend van Spriel @ 2018-11-13 21:07 UTC (permalink / raw)
To: Kalle Valo, David Miller; +Cc: netdev, linux-wireless
In-Reply-To: <87pnv99qdh.fsf@purkki.adurom.net>
On 11/13/2018 12:19 PM, Kalle Valo wrote:
> David Miller <davem@davemloft.net> writes:
>
>> [ As I am trying to remove direct SKB list pointer accesses I am
>> committing this to net-next. If this causes a lot of grief I
>> can and will revert, just let me know. ]
>>
>> Instead of direct SKB list pointer accesses.
>>
>> The loops in this function had to be rewritten to accommodate this
>> more easily.
>>
>> The first loop iterates now over the target list in the outer loop,
>> and triggers an mmc data operation when the per-operation limits are
>> hit.
>>
>> Then after the loops, if we have any residue, we trigger the last
>> and final operation.
>>
>> For the page aligned workaround, where we have to copy the read data
>> back into the original list of SKBs, we use a two-tiered loop. The
>> outer loop stays the same and iterates over pktlist, and then we have
>> an inner loop which uses skb_peek_next(). The break logic has been
>> simplified because we know that the aggregate length of the SKBs in
>> the source and destination lists are the same.
>>
>> This change also ends up fixing a bug, having to do with the
>> maintainance of the seg_sz variable and how it drove the outermost
>> loop. It begins as:
>>
>> seg_sz = target_list->qlen;
>>
>> ie. the number of packets in the target_list queue. The loop
>> structure was then:
>>
>> while (seq_sz) {
>> ...
>> while (not at end of target_list) {
>> ...
>> sg_cnt++
>> ...
>> }
>> ...
>> seg_sz -= sg_cnt;
>>
>> The assumption built into that last statement is that sg_cnt counts
>> how many packets from target_list have been fully processed by the
>> inner loop. But this not true.
>>
>> If we hit one of the limits, such as the max segment size or the max
>> request size, we will break and copy a partial packet then contine
>> back up to the top of the outermost loop.
>>
>> With the new loops we don't have this problem as we don't guard the
>> loop exit with a packet count, but instead use the progression of the
>> pkt_next SKB through the list to the end. The general structure is:
>>
>> sg_cnt = 0;
>> skb_queue_walk(target_list, pkt_next) {
>> pkt_offset = 0;
>> ...
>> sg_cnt++;
>> ...
>> while (pkt_offset < pkt_next->len) {
>> pkt_offset += sg_data_size;
>> if (queued up max per request)
>> mmc_submit_one();
>> }
>> }
>> if (sg_cnt)
>> mmc_submit_one();
>>
>> The variables that maintain where we are in the MMC command state such
>> as req_sz, sg_cnt, and sgl are reset when we emit one of these full
>> sized requests.
>>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> Looks good to me, thanks.
Looks good to me too. However, I currently do not have the hardware at
hands to give it a run for its money. I would prefer to have a tested-by
tag. May take me a couple of days to revive a setup.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH ipsec-next 00/11] xfrm: policy: add inexact policy search tree
From: Steffen Klassert @ 2018-11-13 21:41 UTC (permalink / raw)
To: David Miller; +Cc: fw, netdev
In-Reply-To: <20181108.190014.1425864633966867348.davem@davemloft.net>
On Thu, Nov 08, 2018 at 07:00:14PM -0800, David Miller wrote:
> From: Florian Westphal <fw@strlen.de>
> Date: Wed, 7 Nov 2018 23:00:30 +0100
>
> > This series attempts to improve xfrm policy lookup performance when
> > a lot of (several hundred or even thousands) inexact policies exist
> > on a system.
> >
> > On insert, a policy is either placed in hash table (all direct (/32 for
> > ipv4, /128 policies, or all policies matching a user-configured threshold).
> > All other policies get inserted into inexact list as per priority.
> >
> > Lookup then scans inexact list for first matching entry.
> >
> > This series instead makes it so that inexact policy is added to exactly
> > one of four different search list classes.
> >
> > 1. "Any:Any" list, containing policies where both saddr and daddr are
> > wildcards or have very coarse prefixes, e.g. 10.0.0.0/8 and the like.
> > 2. "saddr:any" list, containing policies with a fixed saddr/prefixlen,
> > but without destination restrictions.
> > These lists are stored in rbtree nodes; each node contains those
> > policies matching saddr/prefixlen.
> > 3. "Any:daddr" list. Similar to 2), except for policies where only the
> > destinations are specified.
> > 4. "saddr:daddr" lists, containing policies that match the given
> > source/destination network.
> >
> > The root of the saddr/daddr tree is stored in the nodes of the
> > 'daddr' tree.
> ...
> > Comments or questions welcome.
>
> Acked-by: David S. Miller <davem@davemloft.net>
This is now applied to ipsec-next, thanks a lot
for your work Florian!
^ permalink raw reply
* Re: [PATCH v2] net: phy: mdio-gpio: fix access that may sleep
From: Martin Schiller @ 2018-11-14 7:43 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, linux-kernel, f.fainelli, davem
In-Reply-To: <20181114070528.GD17052@lunn.ch>
On 2018-11-14 08:05, Andrew Lunn wrote:
> On Wed, Nov 14, 2018 at 07:37:03AM +0100, Martin Schiller wrote:
>> This commit re-enables support for slow GPIO pins. It was initially
>> introduced by commit
>> 2d6c9091ab7630dfcf34417c6683ce4764d7d40a
>> and got lost by commit
>> 7e5fbd1e0700f1bdb94508f84ec2aeb01eed7b12
>
> Hi Martin
>
> Was it really lost? It looks like _cansleep() just adds an extra check
> might_sleep_if(extra_checks), but it does not change any
> functionality.
Well, you are right, the functionality itself is not broken, but using
the NON _cansleep() functions on GPIOs that have the cansleep flag set,
this leads to a lot of kernel warnings/backtraces which makes the system
in fact useless.
Thats the WARN_ON() here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?h=v4.20-rc2#n2992
and here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpio/gpiolib.c?h=v4.20-rc2#n3304
>
> So the change itself is O.K, i'm just not too sure about the commit
> message.
>
> Andrew
Hmm, ok. What would you suggest for a better commit message?
I thought it would be helpful to know that this was already in there
and got (inadvertently?) removed by another commit.
Martin
^ permalink raw reply
* Re: [RFC PATCH 0/6] Armada 38x comphy driver to support 2.5Gbps networking
From: Kishon Vijay Abraham I @ 2018-11-14 8:09 UTC (permalink / raw)
To: Russell King - ARM Linux, devicetree, linux-arm-kernel, netdev
Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Gregory Clement,
Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Sebastian Hesselbarth
In-Reply-To: <20181112122933.GD30658@n2100.armlinux.org.uk>
Hi,
On 12/11/18 5:59 PM, Russell King - ARM Linux wrote:
> Hi,
>
> This series adds support for dynamically switching between 1Gbps
> and 2.5Gbps networking for the Marvell Armada 38x SoCs, tested on
> Armada 388 on the Clearfog platform.
>
> This is necessary to be able to connect (eg) a Clearfog platform
> with a Macchiatobin platform via the SFP sockets, as Clearfog
> currently only supports 1Gbps networking via the SFP socket and
> Macchiatobin defaults to 2.5Gbps when using Fiberchannel SFPs.
>
> In order to allow dynamic switching, we need to implement a common
> phy driver to switch the ethernet serdes lane speed - 2.5Gbps is
> just 1Gbps up-clocked by 2.5x. We implement a simple comphy
> driver to achieve this, which only supports networking.
>
> With this, we are able to support both Fiberchannel SFPs operating
> at 2.5Gbps or 1Gbps, and 1G ethernet SFPs plugged into the Clearfog
> platform, dynamically selecting according to the SFPs abilities.
>
> I'm aware of the proposed changes to the PHY layer, changing
> phy_set_mode() to take the ethernet phy interface type, hence why
> this is RFC - there's also the question about how this will be
> merged. This series is currently based on 4.20-rc1, but will
> likely need to be rebased when the PHY layer changes hit.
For this case, I'd prefer the phy_set_mode series and the phy and net changes
here (after rebasing) go via linux-phy tree.
Thanks
Kishon
^ permalink raw reply
* [patch net-next] net: 8021q: move vlan offload registrations into vlan_core
From: Jiri Pirko @ 2018-11-13 22:22 UTC (permalink / raw)
To: netdev
Cc: davem, michaelsh86, ktkhai, sbrivio, sd, xiyou.wangcong, dcaratti,
dsahern, weiyongjun1, ivan.khoronzhuk, grygorii.strashko, tariqt,
makita.toshiaki, mirq-linux, mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Currently, the vlan packet offloads are registered only upon 8021q module
load. However, even without this module loaded, the offloads could be
utilized, for example by openvswitch datapath. As reported by Michael,
that causes 2x to 5x performance improvement, depending on a testcase.
So move the vlan offload registrations into vlan_core and make this
available even without 8021q module loaded.
Reported-by: Michael Shteinbok <michaelsh86@gmail.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Tested-by: Michael Shteinbok <michaelsh86@gmail.com>
---
net/8021q/vlan.c | 96 -----------------------------------------
net/8021q/vlan_core.c | 99 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 96 deletions(-)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 1b7a375c6616..aef1a977279c 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -648,93 +648,6 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
return err;
}
-static struct sk_buff *vlan_gro_receive(struct list_head *head,
- struct sk_buff *skb)
-{
- const struct packet_offload *ptype;
- unsigned int hlen, off_vlan;
- struct sk_buff *pp = NULL;
- struct vlan_hdr *vhdr;
- struct sk_buff *p;
- __be16 type;
- int flush = 1;
-
- off_vlan = skb_gro_offset(skb);
- hlen = off_vlan + sizeof(*vhdr);
- vhdr = skb_gro_header_fast(skb, off_vlan);
- if (skb_gro_header_hard(skb, hlen)) {
- vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
- if (unlikely(!vhdr))
- goto out;
- }
-
- type = vhdr->h_vlan_encapsulated_proto;
-
- rcu_read_lock();
- ptype = gro_find_receive_by_type(type);
- if (!ptype)
- goto out_unlock;
-
- flush = 0;
-
- list_for_each_entry(p, head, list) {
- struct vlan_hdr *vhdr2;
-
- if (!NAPI_GRO_CB(p)->same_flow)
- continue;
-
- vhdr2 = (struct vlan_hdr *)(p->data + off_vlan);
- if (compare_vlan_header(vhdr, vhdr2))
- NAPI_GRO_CB(p)->same_flow = 0;
- }
-
- skb_gro_pull(skb, sizeof(*vhdr));
- skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
- pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
-
-out_unlock:
- rcu_read_unlock();
-out:
- skb_gro_flush_final(skb, pp, flush);
-
- return pp;
-}
-
-static int vlan_gro_complete(struct sk_buff *skb, int nhoff)
-{
- struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data + nhoff);
- __be16 type = vhdr->h_vlan_encapsulated_proto;
- struct packet_offload *ptype;
- int err = -ENOENT;
-
- rcu_read_lock();
- ptype = gro_find_complete_by_type(type);
- if (ptype)
- err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(*vhdr));
-
- rcu_read_unlock();
- return err;
-}
-
-static struct packet_offload vlan_packet_offloads[] __read_mostly = {
- {
- .type = cpu_to_be16(ETH_P_8021Q),
- .priority = 10,
- .callbacks = {
- .gro_receive = vlan_gro_receive,
- .gro_complete = vlan_gro_complete,
- },
- },
- {
- .type = cpu_to_be16(ETH_P_8021AD),
- .priority = 10,
- .callbacks = {
- .gro_receive = vlan_gro_receive,
- .gro_complete = vlan_gro_complete,
- },
- },
-};
-
static int __net_init vlan_init_net(struct net *net)
{
struct vlan_net *vn = net_generic(net, vlan_net_id);
@@ -762,7 +675,6 @@ static struct pernet_operations vlan_net_ops = {
static int __init vlan_proto_init(void)
{
int err;
- unsigned int i;
pr_info("%s v%s\n", vlan_fullname, vlan_version);
@@ -786,9 +698,6 @@ static int __init vlan_proto_init(void)
if (err < 0)
goto err5;
- for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
- dev_add_offload(&vlan_packet_offloads[i]);
-
vlan_ioctl_set(vlan_ioctl_handler);
return 0;
@@ -806,13 +715,8 @@ static int __init vlan_proto_init(void)
static void __exit vlan_cleanup_module(void)
{
- unsigned int i;
-
vlan_ioctl_set(NULL);
- for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
- dev_remove_offload(&vlan_packet_offloads[i]);
-
vlan_netlink_fini();
unregister_netdevice_notifier(&vlan_notifier_block);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 57425049faf2..a313165e7a67 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -453,3 +453,102 @@ bool vlan_uses_dev(const struct net_device *dev)
return vlan_info->grp.nr_vlan_devs ? true : false;
}
EXPORT_SYMBOL(vlan_uses_dev);
+
+static struct sk_buff *vlan_gro_receive(struct list_head *head,
+ struct sk_buff *skb)
+{
+ const struct packet_offload *ptype;
+ unsigned int hlen, off_vlan;
+ struct sk_buff *pp = NULL;
+ struct vlan_hdr *vhdr;
+ struct sk_buff *p;
+ __be16 type;
+ int flush = 1;
+
+ off_vlan = skb_gro_offset(skb);
+ hlen = off_vlan + sizeof(*vhdr);
+ vhdr = skb_gro_header_fast(skb, off_vlan);
+ if (skb_gro_header_hard(skb, hlen)) {
+ vhdr = skb_gro_header_slow(skb, hlen, off_vlan);
+ if (unlikely(!vhdr))
+ goto out;
+ }
+
+ type = vhdr->h_vlan_encapsulated_proto;
+
+ rcu_read_lock();
+ ptype = gro_find_receive_by_type(type);
+ if (!ptype)
+ goto out_unlock;
+
+ flush = 0;
+
+ list_for_each_entry(p, head, list) {
+ struct vlan_hdr *vhdr2;
+
+ if (!NAPI_GRO_CB(p)->same_flow)
+ continue;
+
+ vhdr2 = (struct vlan_hdr *)(p->data + off_vlan);
+ if (compare_vlan_header(vhdr, vhdr2))
+ NAPI_GRO_CB(p)->same_flow = 0;
+ }
+
+ skb_gro_pull(skb, sizeof(*vhdr));
+ skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
+ pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+
+out_unlock:
+ rcu_read_unlock();
+out:
+ skb_gro_flush_final(skb, pp, flush);
+
+ return pp;
+}
+
+static int vlan_gro_complete(struct sk_buff *skb, int nhoff)
+{
+ struct vlan_hdr *vhdr = (struct vlan_hdr *)(skb->data + nhoff);
+ __be16 type = vhdr->h_vlan_encapsulated_proto;
+ struct packet_offload *ptype;
+ int err = -ENOENT;
+
+ rcu_read_lock();
+ ptype = gro_find_complete_by_type(type);
+ if (ptype)
+ err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(*vhdr));
+
+ rcu_read_unlock();
+ return err;
+}
+
+static struct packet_offload vlan_packet_offloads[] __read_mostly = {
+ {
+ .type = cpu_to_be16(ETH_P_8021Q),
+ .priority = 10,
+ .callbacks = {
+ .gro_receive = vlan_gro_receive,
+ .gro_complete = vlan_gro_complete,
+ },
+ },
+ {
+ .type = cpu_to_be16(ETH_P_8021AD),
+ .priority = 10,
+ .callbacks = {
+ .gro_receive = vlan_gro_receive,
+ .gro_complete = vlan_gro_complete,
+ },
+ },
+};
+
+static int __init vlan_offload_init(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(vlan_packet_offloads); i++)
+ dev_add_offload(&vlan_packet_offloads[i]);
+
+ return 0;
+}
+
+fs_initcall(vlan_offload_init);
--
2.17.0
^ permalink raw reply related
* Re: [RFC PATCH 2/6] phy: armada38x: add common phy support
From: Kishon Vijay Abraham I @ 2018-11-14 8:42 UTC (permalink / raw)
To: Russell King, devicetree, linux-arm-kernel, netdev
Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Gregory Clement,
Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Sebastian Hesselbarth
In-Reply-To: <E1gMBMi-00089Q-7S@rmk-PC.armlinux.org.uk>
Hi,
On 12/11/18 6:00 PM, Russell King wrote:
> Add support for the Armada 38x common phy to allow us to change the
> speed of the Ethernet serdes lane. This driver only supports
> manipulation of the speed, it does not support configuration of the
> common phy.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> drivers/phy/marvell/Kconfig | 10 ++
> drivers/phy/marvell/Makefile | 1 +
> drivers/phy/marvell/phy-armada38x-comphy.c | 236 +++++++++++++++++++++++++++++
> 3 files changed, 247 insertions(+)
> create mode 100644 drivers/phy/marvell/phy-armada38x-comphy.c
>
> diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig
> index 6fb4b56e4c14..224ea4e6a46d 100644
> --- a/drivers/phy/marvell/Kconfig
> +++ b/drivers/phy/marvell/Kconfig
> @@ -21,6 +21,16 @@ config PHY_BERLIN_USB
> help
> Enable this to support the USB PHY on Marvell Berlin SoCs.
>
> +config PHY_MVEBU_A38X_COMPHY
> + tristate "Marvell Armada 38x comphy driver"
> + depends on ARCH_MVEBU || COMPILE_TEST
> + depends on OF
> + select GENERIC_PHY
> + help
> + This driver allows to control the comphy, an hardware block providing
> + shared serdes PHYs on Marvell Armada 38x. Its serdes lanes can be
> + used by various controllers (Ethernet, sata, usb, PCIe...).
> +
> config PHY_MVEBU_CP110_COMPHY
> tristate "Marvell CP110 comphy driver"
> depends on ARCH_MVEBU || COMPILE_TEST
> diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile
> index 3975b144f8ec..59b6c03ef756 100644
> --- a/drivers/phy/marvell/Makefile
> +++ b/drivers/phy/marvell/Makefile
> @@ -2,6 +2,7 @@
> obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
> obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
> obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
> +obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o
> obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o
> obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
> obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
> diff --git a/drivers/phy/marvell/phy-armada38x-comphy.c b/drivers/phy/marvell/phy-armada38x-comphy.c
> new file mode 100644
> index 000000000000..61d1965e1cf6
> --- /dev/null
> +++ b/drivers/phy/marvell/phy-armada38x-comphy.c
> @@ -0,0 +1,236 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Russell King, Deep Blue Solutions Ltd.
> + *
> + * Partly derived from CP110 comphy driver by Antoine Tenart
> + * <antoine.tenart@bootlin.com>
> + */
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +
> +#define MAX_A38X_COMPHY 6
> +#define MAX_A38X_PORTS 3
> +
> +#define COMPHY_CFG1 0x00
> +#define COMPHY_CFG1_GEN_TX(x) ((x) << 26)
> +#define COMPHY_CFG1_GEN_TX_MSK COMPHY_CFG1_GEN_TX(15)
> +#define COMPHY_CFG1_GEN_RX(x) ((x) << 22)
> +#define COMPHY_CFG1_GEN_RX_MSK COMPHY_CFG1_GEN_RX(15)
> +#define GEN_SGMII_1_25GBPS 6
> +#define GEN_SGMII_3_125GBPS 8
> +
> +#define COMPHY_STAT1 0x18
> +#define COMPHY_STAT1_PLL_RDY_TX BIT(3)
> +#define COMPHY_STAT1_PLL_RDY_RX BIT(2)
> +
> +#define COMPHY_SELECTOR 0xfc
> +
> +struct a38x_comphy;
> +
> +struct a38x_comphy_lane {
> + void __iomem *base;
> + struct a38x_comphy *priv;
> + unsigned int n;
> +
> + int port;
> +};
> +
> +struct a38x_comphy {
> + void __iomem *base;
> + struct device *dev;
> + struct a38x_comphy_lane lane[MAX_A38X_COMPHY];
> +};
> +
> +static const u8 gbe_mux[MAX_A38X_COMPHY][MAX_A38X_PORTS] = {
> + { 0, 0, 0 },
> + { 4, 5, 0 },
> + { 0, 4, 0 },
> + { 0, 0, 4 },
> + { 0, 3, 0 },
> + { 0, 0, 3 },
> +};
> +
> +static void a38x_comphy_set_reg(struct a38x_comphy_lane *lane,
> + unsigned int offset, u32 mask, u32 value)
> +{
> + u32 val;
> +
> + val = readl_relaxed(lane->base + offset) & ~mask;
> + writel(val | value, lane->base + offset);
> +}
> +
> +static void a38x_comphy_set_speed(struct a38x_comphy_lane *lane,
> + unsigned int gen_tx, unsigned int gen_rx)
> +{
> + a38x_comphy_set_reg(lane, COMPHY_CFG1,
> + COMPHY_CFG1_GEN_TX_MSK | COMPHY_CFG1_GEN_RX_MSK,
> + COMPHY_CFG1_GEN_TX(gen_tx) |
> + COMPHY_CFG1_GEN_RX(gen_rx));
> +}
> +
> +static int a38x_comphy_poll(struct a38x_comphy_lane *lane,
> + unsigned int offset, u32 mask, u32 value)
> +{
> + unsigned int timeout = 10;
> + u32 val;
> +
> + while (1) {
> + val = readl_relaxed(lane->base + offset);
> + if ((val & mask) == value)
> + return 0;
> + if (!timeout--)
> + break;
> + udelay(10);
> + }
> +
> + dev_err(lane->priv->dev, "comphy%u: timed out waiting for status\n",
> + lane->n);
> +
> + return -ETIMEDOUT;
> +}
> +
> +/*
> + * We only support changing the speed for comphys configured for GBE.
> + * Since that is all we do, we only poll for PLL ready status.
> + */
> +static int a38x_comphy_set_mode(struct phy *phy, enum phy_mode mode)
> +{
> + struct a38x_comphy_lane *lane = phy_get_drvdata(phy);
> + unsigned int gen;
> + u32 val;
> +
> + val = readl_relaxed(lane->priv->base + COMPHY_SELECTOR);
> + val = (val >> (4 * lane->n)) & 0xf;
> +
> + if (!gbe_mux[lane->n][lane->port] ||
> + val != gbe_mux[lane->n][lane->port]) {
> + dev_warn(lane->priv->dev,
> + "comphy%u: not configured for GBE\n", lane->n);
> + return -EINVAL;
> + }
Any reason for not doing this check in a38x_comphy_xlate? We could fail during
phy_get if comphy is not configured for GBE then.
Thanks
Kishon
^ permalink raw reply
* Re: [RFC PATCH 5/6] net: marvell: neta: add support for 2500base-X
From: Kishon Vijay Abraham I @ 2018-11-14 8:48 UTC (permalink / raw)
To: Russell King, devicetree, linux-arm-kernel, netdev
Cc: Mark Rutland, Andrew Lunn, Jason Cooper, Gregory Clement,
Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Sebastian Hesselbarth
In-Reply-To: <E1gMBMx-0008A9-Jb@rmk-PC.armlinux.org.uk>
Hi,
On 12/11/18 6:01 PM, Russell King wrote:
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
> drivers/net/ethernet/marvell/mvneta.c | 58 ++++++++++++++++++++++++++++++-----
> 1 file changed, 51 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index 5bfd349bf41a..7305d4cc0630 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -27,6 +27,7 @@
> #include <linux/of_irq.h>
> #include <linux/of_mdio.h>
> #include <linux/of_net.h>
> +#include <linux/phy/phy.h>
> #include <linux/phy.h>
> #include <linux/phylink.h>
> #include <linux/platform_device.h>
> @@ -437,6 +438,7 @@ struct mvneta_port {
> struct device_node *dn;
> unsigned int tx_csum_limit;
> struct phylink *phylink;
> + struct phy *comphy;
>
> struct mvneta_bm *bm_priv;
> struct mvneta_bm_pool *pool_long;
> @@ -3150,6 +3152,8 @@ static void mvneta_start_dev(struct mvneta_port *pp)
> {
> int cpu;
>
> + WARN_ON(phy_power_on(pp->comphy));
> +
> mvneta_max_rx_size_set(pp, pp->pkt_size);
> mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
>
> @@ -3212,6 +3216,8 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
>
> mvneta_tx_reset(pp);
> mvneta_rx_reset(pp);
> +
> + WARN_ON(phy_power_off(pp->comphy));
> }
>
> static void mvneta_percpu_enable(void *arg)
> @@ -3337,6 +3343,7 @@ static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
> static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
> struct phylink_link_state *state)
> {
> + struct mvneta_port *pp = netdev_priv(ndev);
> __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
>
> /* We only support QSGMII, SGMII, 802.3z and RGMII modes */
> @@ -3357,14 +3364,14 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
> /* Asymmetric pause is unsupported */
> phylink_set(mask, Pause);
>
> - /* We cannot use 1Gbps when using the 2.5G interface. */
> - if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
> - phylink_set(mask, 2500baseT_Full);
> - phylink_set(mask, 2500baseX_Full);
> - } else {
> + /* Half-duplex at speeds higher than 100Mbit is unsupported */
> + if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) {
> phylink_set(mask, 1000baseT_Full);
> phylink_set(mask, 1000baseX_Full);
> }
> + if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) {
> + phylink_set(mask, 2500baseX_Full);
> + }
>
> if (!phy_interface_mode_is_8023z(state->interface)) {
> /* 10M and 100M are only supported in non-802.3z mode */
> @@ -3378,6 +3385,11 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
> __ETHTOOL_LINK_MODE_MASK_NBITS);
> bitmap_and(state->advertising, state->advertising, mask,
> __ETHTOOL_LINK_MODE_MASK_NBITS);
> +
> + /* We can only operate at 2500BaseX or 1000BaseX. If requested
> + * to advertise both, only report advertising at 2500BaseX.
> + */
> + phylink_helper_basex_speed(state);
> }
>
> static int mvneta_mac_link_state(struct net_device *ndev,
> @@ -3389,7 +3401,9 @@ static int mvneta_mac_link_state(struct net_device *ndev,
> gmac_stat = mvreg_read(pp, MVNETA_GMAC_STATUS);
>
> if (gmac_stat & MVNETA_GMAC_SPEED_1000)
> - state->speed = SPEED_1000;
> + state->speed =
> + state->interface == PHY_INTERFACE_MODE_2500BASEX ?
> + SPEED_2500 : SPEED_1000;
> else if (gmac_stat & MVNETA_GMAC_SPEED_100)
> state->speed = SPEED_100;
> else
> @@ -3504,12 +3518,32 @@ static void mvneta_mac_config(struct net_device *ndev, unsigned int mode,
> MVNETA_GMAC_FORCE_LINK_DOWN);
> }
>
> +
> /* When at 2.5G, the link partner can send frames with shortened
> * preambles.
> */
> if (state->speed == SPEED_2500)
> new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE;
>
> + if (pp->comphy) {
> + enum phy_mode mode = PHY_MODE_INVALID;
> +
> + switch (state->interface) {
> + case PHY_INTERFACE_MODE_SGMII:
> + case PHY_INTERFACE_MODE_1000BASEX:
> + mode = PHY_MODE_SGMII;
> + break;
> + case PHY_INTERFACE_MODE_2500BASEX:
> + mode = PHY_MODE_2500SGMII;
> + break;
> + default:
> + break;
> + }
> +
> + if (mode != PHY_MODE_INVALID)
> + WARN_ON(phy_set_mode(pp->comphy, mode));
> + }
> +
> if (new_ctrl0 != gmac_ctrl0)
> mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0);
> if (new_ctrl2 != gmac_ctrl2)
> @@ -4411,7 +4445,7 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
> if (phy_mode == PHY_INTERFACE_MODE_QSGMII)
> mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO);
> else if (phy_mode == PHY_INTERFACE_MODE_SGMII ||
> - phy_mode == PHY_INTERFACE_MODE_1000BASEX)
> + phy_interface_mode_is_8023z(phy_mode))
> mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
> else if (!phy_interface_mode_is_rgmii(phy_mode))
> return -EINVAL;
> @@ -4428,6 +4462,7 @@ static int mvneta_probe(struct platform_device *pdev)
> struct mvneta_port *pp;
> struct net_device *dev;
> struct phylink *phylink;
> + struct phy *comphy;
> const char *dt_mac_addr;
> char hw_mac_addr[ETH_ALEN];
> const char *mac_from;
> @@ -4453,6 +4488,14 @@ static int mvneta_probe(struct platform_device *pdev)
> goto err_free_irq;
> }
>
> + comphy = devm_of_phy_get(&pdev->dev, dn, NULL);
> + if (comphy == ERR_PTR(-EPROBE_DEFER)) {
> + err = -EPROBE_DEFER;
> + goto err_free_irq;
> + } else if (IS_ERR(comphy)) {
> + comphy = NULL;
> + }
devm_phy_optional_get can be used here instead.
Thanks
Kishon
^ permalink raw reply
* Re: [iproute PATCH] ip-address: Fix filtering by negated address flags
From: Stephen Hemminger @ 2018-11-13 22:47 UTC (permalink / raw)
To: Phil Sutter; +Cc: netdev
In-Reply-To: <20181113151201.19297-1-phil@nwl.cc>
On Tue, 13 Nov 2018 16:12:01 +0100
Phil Sutter <phil@nwl.cc> wrote:
> + if (arg[0] == '-') {
> + inv = true;
> + arg++;
> + }
The inverse logic needs to be moved into the loop handling filter names.
Otherwise, you get weirdness like "-dynamic" being accepted and not
doing what was expected.
Also, please make sure the man page matches the code.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox