* [PATCH net-next v3 3/5] net: aquantia: Implement rx/tx flow control ethtools callback
From: Igor Russkikh @ 2018-07-02 14:03 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, David Arcari, Pavel Belous, Igor Russkikh
In-Reply-To: <cover.1530537192.git.igor.russkikh@aquantia.com>
Runtime change of pause frame configuration (rx/tx flow control)
via ethtool.
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
.../net/ethernet/aquantia/atlantic/aq_ethtool.c | 42 ++++++++++++++++++++++
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 6 +++-
.../aquantia/atlantic/hw_atl/hw_atl_utils.c | 1 +
.../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 26 ++++++++++++++
4 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 0624215..37f8460 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -285,6 +285,46 @@ static int aq_ethtool_set_coalesce(struct net_device *ndev,
return aq_nic_update_interrupt_moderation_settings(aq_nic);
}
+static void aq_ethtool_get_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+
+ pause->autoneg = 0;
+
+ if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
+ pause->rx_pause = 1;
+ if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
+ pause->tx_pause = 1;
+}
+
+static int aq_ethtool_set_pauseparam(struct net_device *ndev,
+ struct ethtool_pauseparam *pause)
+{
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+ int err = 0;
+
+ if (!aq_nic->aq_fw_ops->set_flow_control)
+ return -EOPNOTSUPP;
+
+ if (pause->autoneg == AUTONEG_ENABLE)
+ return -EOPNOTSUPP;
+
+ if (pause->rx_pause)
+ aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
+ else
+ aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
+
+ if (pause->tx_pause)
+ aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
+ else
+ aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
+
+ err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
+
+ return err;
+}
+
static void aq_get_ringparam(struct net_device *ndev,
struct ethtool_ringparam *ring)
{
@@ -352,6 +392,8 @@ const struct ethtool_ops aq_ethtool_ops = {
.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
.get_ringparam = aq_get_ringparam,
.set_ringparam = aq_set_ringparam,
+ .get_pauseparam = aq_ethtool_get_pauseparam,
+ .set_pauseparam = aq_ethtool_set_pauseparam,
.get_rxfh_key_size = aq_ethtool_get_rss_key_size,
.get_rxfh = aq_ethtool_get_rss,
.get_rxnfc = aq_ethtool_get_rxnfc,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index e8cf93a..21cfb32 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -761,10 +761,14 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
ethtool_link_ksettings_add_link_mode(cmd, advertising,
100baseT_Full);
- if (self->aq_nic_cfg.flow_control)
+ if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX)
ethtool_link_ksettings_add_link_mode(cmd, advertising,
Pause);
+ if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX)
+ ethtool_link_ksettings_add_link_mode(cmd, advertising,
+ Asym_Pause);
+
if (self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_FIBRE)
ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
else
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index 9d0a96d..e1feba5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -834,4 +834,5 @@ const struct aq_fw_ops aq_fw_1x_ops = {
.set_state = hw_atl_utils_mpi_set_state,
.update_link_status = hw_atl_utils_mpi_get_link_status,
.update_stats = hw_atl_utils_update_stats,
+ .set_flow_control = NULL,
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index a3e95f0..c1b671e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -87,6 +87,19 @@ static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
return 0;
}
+static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state)
+{
+ if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
+ *mpi_state |= BIT(CAPS_HI_PAUSE);
+ else
+ *mpi_state &= ~BIT(CAPS_HI_PAUSE);
+
+ if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
+ *mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE);
+ else
+ *mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE);
+}
+
static int aq_fw2x_set_state(struct aq_hw_s *self,
enum hal_atl_utils_fw_state_e state)
{
@@ -95,6 +108,7 @@ static int aq_fw2x_set_state(struct aq_hw_s *self,
switch (state) {
case MPI_INIT:
mpi_state &= ~BIT(CAPS_HI_LINK_DROP);
+ aq_fw2x_set_mpi_flow_control(self, &mpi_state);
break;
case MPI_DEINIT:
mpi_state |= BIT(CAPS_HI_LINK_DROP);
@@ -201,6 +215,17 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
return hw_atl_utils_update_stats(self);
}
+static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
+{
+ u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+
+ aq_fw2x_set_mpi_flow_control(self, &mpi_state);
+
+ aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
+
+ return 0;
+}
+
const struct aq_fw_ops aq_fw_2x_ops = {
.init = aq_fw2x_init,
.deinit = aq_fw2x_deinit,
@@ -210,4 +235,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.set_state = aq_fw2x_set_state,
.update_link_status = aq_fw2x_update_link_status,
.update_stats = aq_fw2x_update_stats,
+ .set_flow_control = aq_fw2x_set_flow_control,
};
--
2.7.4
^ permalink raw reply related
* [PATCH net-next v3 4/5] net: aquantia: Add renegotiate ethtool operation support
From: Igor Russkikh @ 2018-07-02 14:03 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, David Arcari, Pavel Belous, Igor Russkikh, Anton Mikaev
In-Reply-To: <cover.1530537192.git.igor.russkikh@aquantia.com>
From: Anton Mikaev <amikaev@aquantia.com>
Adds ethtool -r|--negotiate operation support. It triggers special
control bit on FW interface causing FW to restart link negotiation.
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Anton Mikaev <amikaev@aquantia.com>
---
.../net/ethernet/aquantia/atlantic/aq_ethtool.c | 14 +++++++++
drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 2 ++
.../aquantia/atlantic/hw_atl/hw_atl_utils.h | 35 ++++++++++++++++++++++
.../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 12 ++++++++
4 files changed, 63 insertions(+)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 37f8460..08c9fa6 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -285,6 +285,19 @@ static int aq_ethtool_set_coalesce(struct net_device *ndev,
return aq_nic_update_interrupt_moderation_settings(aq_nic);
}
+static int aq_ethtool_nway_reset(struct net_device *ndev)
+{
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
+
+ if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
+ return -EOPNOTSUPP;
+
+ if (netif_running(ndev))
+ return aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
+
+ return 0;
+}
+
static void aq_ethtool_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
@@ -390,6 +403,7 @@ const struct ethtool_ops aq_ethtool_ops = {
.get_drvinfo = aq_ethtool_get_drvinfo,
.get_strings = aq_ethtool_get_strings,
.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
+ .nway_reset = aq_ethtool_nway_reset,
.get_ringparam = aq_get_ringparam,
.set_ringparam = aq_set_ringparam,
.get_pauseparam = aq_ethtool_get_pauseparam,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 3aa36d5..1a51152 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -212,6 +212,8 @@ struct aq_fw_ops {
int (*reset)(struct aq_hw_s *self);
+ int (*renegotiate)(struct aq_hw_s *self);
+
int (*get_mac_permanent)(struct aq_hw_s *self, u8 *mac);
int (*set_link_speed)(struct aq_hw_s *self, u32 speed);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index cd8f18f..b875590 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -239,6 +239,41 @@ enum hw_atl_fw2x_caps_hi {
CAPS_HI_TRANSACTION_ID,
};
+enum hw_atl_fw2x_ctrl {
+ CTRL_RESERVED1 = 0x00,
+ CTRL_RESERVED2,
+ CTRL_RESERVED3,
+ CTRL_PAUSE,
+ CTRL_ASYMMETRIC_PAUSE,
+ CTRL_RESERVED4,
+ CTRL_RESERVED5,
+ CTRL_RESERVED6,
+ CTRL_1GBASET_FD_EEE,
+ CTRL_2P5GBASET_FD_EEE,
+ CTRL_5GBASET_FD_EEE,
+ CTRL_10GBASET_FD_EEE,
+ CTRL_THERMAL_SHUTDOWN,
+ CTRL_PHY_LOGS,
+ CTRL_EEE_AUTO_DISABLE,
+ CTRL_PFC,
+ CTRL_WAKE_ON_LINK,
+ CTRL_CABLE_DIAG,
+ CTRL_TEMPERATURE,
+ CTRL_DOWNSHIFT,
+ CTRL_PTP_AVB,
+ CTRL_RESERVED7,
+ CTRL_LINK_DROP,
+ CTRL_SLEEP_PROXY,
+ CTRL_WOL,
+ CTRL_MAC_STOP,
+ CTRL_EXT_LOOPBACK,
+ CTRL_INT_LOOPBACK,
+ CTRL_RESERVED8,
+ CTRL_WOL_TIMER,
+ CTRL_STATISTICS,
+ CTRL_FORCE_RECONNECT,
+};
+
struct aq_hw_s;
struct aq_fw_ops;
struct aq_hw_caps_s;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index c1b671e..e379437 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -215,6 +215,17 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
return hw_atl_utils_update_stats(self);
}
+static int aq_fw2x_renegotiate(struct aq_hw_s *self)
+{
+ u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+
+ mpi_opts |= BIT(CTRL_FORCE_RECONNECT);
+
+ aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+ return 0;
+}
+
static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
{
u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
@@ -230,6 +241,7 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.init = aq_fw2x_init,
.deinit = aq_fw2x_deinit,
.reset = NULL,
+ .renegotiate = aq_fw2x_renegotiate,
.get_mac_permanent = aq_fw2x_get_mac_permanent,
.set_link_speed = aq_fw2x_set_link_speed,
.set_state = aq_fw2x_set_state,
--
2.7.4
^ permalink raw reply related
* [PATCH net-next v3 5/5] net: aquantia: bump driver version
From: Igor Russkikh @ 2018-07-02 14:03 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, David Arcari, Pavel Belous, Igor Russkikh
In-Reply-To: <cover.1530537192.git.igor.russkikh@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
drivers/net/ethernet/aquantia/atlantic/ver.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h b/drivers/net/ethernet/aquantia/atlantic/ver.h
index a445de6..94efc64 100644
--- a/drivers/net/ethernet/aquantia/atlantic/ver.h
+++ b/drivers/net/ethernet/aquantia/atlantic/ver.h
@@ -12,8 +12,8 @@
#define NIC_MAJOR_DRIVER_VERSION 2
#define NIC_MINOR_DRIVER_VERSION 0
-#define NIC_BUILD_DRIVER_VERSION 2
-#define NIC_REVISION_DRIVER_VERSION 1
+#define NIC_BUILD_DRIVER_VERSION 3
+#define NIC_REVISION_DRIVER_VERSION 0
#define AQ_CFG_DRV_VERSION_SUFFIX "-kern"
--
2.7.4
^ permalink raw reply related
* Re: [1/3] ath10k: sdio: use same endpoint id for all packets in a bundle
From: Kalle Valo @ 2018-07-02 14:23 UTC (permalink / raw)
To: Niklas Cassel
Cc: David S. Miller, alagusankar, Niklas Cassel, ath10k,
linux-wireless, netdev, linux-kernel
In-Reply-To: <20180620084222.3521-2-niklas.cassel@linaro.org>
Niklas Cassel <niklas.cassel@linaro.org> wrote:
> All packets in a bundle should use the same endpoint id as the
> first lookahead.
>
> This matches how things are done is ath6kl, however,
> this patch can theoretically handle several bundles
> in ath10k_sdio_mbox_rx_process_packets().
>
> Without this patch we get lots of errors about invalid endpoint id:
>
> ath10k_sdio mmc2:0001:1: invalid endpoint in look-ahead: 224
> ath10k_sdio mmc2:0001:1: failed to get pending recv messages: -12
> ath10k_sdio mmc2:0001:1: failed to process pending SDIO interrupts: -12
>
> Co-Developed-by: Niklas Cassel <niklas.cassel@linaro.org>
> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
> Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
3 patches applied to ath-next branch of ath.git, thanks.
679e1f07c862 ath10k: sdio: use same endpoint id for all packets in a bundle
d1d061b1395a ath10k: sdio: allocate correct size for RECV_1MORE_BLOCK rx packets
8530b4e7b22b ath10k: sdio: set skb len for all rx packets
--
https://patchwork.kernel.org/patch/10476637/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [1/3] ath10k: sdio: use same endpoint id for all packets in a bundle
From: Kalle Valo @ 2018-07-02 14:23 UTC (permalink / raw)
To: Niklas Cassel
Cc: alagusankar, netdev, linux-wireless, linux-kernel, ath10k,
Niklas Cassel, David S. Miller
In-Reply-To: <20180620084222.3521-2-niklas.cassel@linaro.org>
Niklas Cassel <niklas.cassel@linaro.org> wrote:
> All packets in a bundle should use the same endpoint id as the
> first lookahead.
>
> This matches how things are done is ath6kl, however,
> this patch can theoretically handle several bundles
> in ath10k_sdio_mbox_rx_process_packets().
>
> Without this patch we get lots of errors about invalid endpoint id:
>
> ath10k_sdio mmc2:0001:1: invalid endpoint in look-ahead: 224
> ath10k_sdio mmc2:0001:1: failed to get pending recv messages: -12
> ath10k_sdio mmc2:0001:1: failed to process pending SDIO interrupts: -12
>
> Co-Developed-by: Niklas Cassel <niklas.cassel@linaro.org>
> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
> Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
3 patches applied to ath-next branch of ath.git, thanks.
679e1f07c862 ath10k: sdio: use same endpoint id for all packets in a bundle
d1d061b1395a ath10k: sdio: allocate correct size for RECV_1MORE_BLOCK rx packets
8530b4e7b22b ath10k: sdio: set skb len for all rx packets
--
https://patchwork.kernel.org/patch/10476637/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v2] atmel: using strlcpy() to avoid possible buffer overflows
From: Kalle Valo @ 2018-07-02 14:40 UTC (permalink / raw)
To: YueHaibing
Cc: simon, linux-kernel, netdev, linux-wireless, davem,
andy.shevchenko
In-Reply-To: <20180630063341.9900-1-yuehaibing@huawei.com>
YueHaibing <yuehaibing@huawei.com> writes:
> 'firmware' is a module param which may been longer than firmware_id,
> so using strlcpy() to guard against overflows. Also priv is allocated
> with zeroed memory,no need to set firmware_id[0] to '\0'.
>
> v1 -> v2: remove priv->firmware_id[0] = '\0';
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/net/wireless/atmel/atmel.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
The changelog should be after "---" line. I can fix it this time, but in
the future please use the correct location.
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#changelog_missing
--
Kalle Valo
^ permalink raw reply
* Re: [net-next 01/12] net/mlx5e: Add UDP GSO support
From: Willem de Bruijn @ 2018-07-02 14:45 UTC (permalink / raw)
To: borisp
Cc: Alexander Duyck, David Miller, Network Development,
Saeed Mahameed, ogerlitz, yossiku
In-Reply-To: <CAF=yD-L2WsXmQ--8CAKrxRkZs5cuBufr3mHQ0+rbn_StOYAczQ@mail.gmail.com>
On Mon, Jul 2, 2018 at 9:34 AM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> On Mon, Jul 2, 2018 at 1:30 AM Boris Pismenny <borisp@mellanox.com> wrote:
> >
> >
> >
> > On 7/2/2018 4:45 AM, Willem de Bruijn wrote:
> > >>> I've noticed that we could get cleaner code in our driver if we remove
> > >>> these two lines from net/ipv4/udp_offload.c:
> > >>> if (skb_is_gso(segs))
> > >>> mss *= skb_shinfo(segs)->gso_segs;
> > >>>
> > >>> I think that this is correct in case of GSO_PARTIAL segmentation for the
> > >>> following reasons:
> > >>> 1. After this change the UDP payload field is consistent with the IP
> > >>> header payload length field. Currently, IPv4 length is 1500 and UDP
> > >>> total length is the full unsegmented length.
> > >
> > > How does this simplify the driver? Does it currently have to
> > > change the udph->length field to the mss on the wire, because the
> > > device only splits + replicates the headers + computes the csum?
> >
> > Yes, this is the code I have at the moment.
> >
> > The device's limitation is more subtle than this. It could adjust the
> > length, but then the checksum would be wrong.
>
> I see. We do have to keep in mind other devices. Alexander's ixgbe
> RFC patch does not have this logic, so that device must update the
> field directly.
>
> https://patchwork.ozlabs.org/patch/908396/
To be clear, I think it's fine to remove these two lines if it does not cause
problems for the ixgbe. It's quite possible that that device sets the udp
length field unconditionally, ignoring the previous value. In which case both
devices will work after this change without additional driver logic.
^ permalink raw reply
* 答复: [PATCH][net-next] net: increase MAX_GRO_SKBS to 64
From: Li,Rongqing @ 2018-07-02 14:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org, eric.dumazet@gmail.com
In-Reply-To: <20180702.204428.903903223700362229.davem@davemloft.net>
________________________________________
发件人: David Miller [davem@davemloft.net]
发送时间: 2018年7月2日 19:44
收件人: Li,Rongqing
抄送: netdev@vger.kernel.org; eric.dumazet@gmail.com
主题: Re: [PATCH][net-next] net: increase MAX_GRO_SKBS to 64
From: Li RongQing <lirongqing@baidu.com>
Date: Mon, 2 Jul 2018 19:41:43 +0800
>> After 07d78363dcffd [net: Convert NAPI gro list into a small hash table]
> > there is 8 hash buckets, which allow more flows to be held for merging.
> >
> > keep each as original list length, so increase MAX_GRO_SKBS to 64
> >
> > Signed-off-by: Li RongQing <lirongqing@baidu.com>
> I would like to hear some feedback from Eric, 64 might be too big.
I think we should limit each list length to 8 skb , insteading of this change
if there is only one flow, changing MAX_GRO_SKBS to 64 maybe generate
large delay.
if keep total 8 skb, for multiple flow, hash table maybe unable to improve the performance
-RongQing
^ permalink raw reply
* Re: [PATCH net-next 2/2] tcp: ack immediately when a cwr packet arrives
From: Neal Cardwell @ 2018-07-02 14:57 UTC (permalink / raw)
To: Lawrence Brakmo
Cc: Netdev, Kernel Team, bmatheny, ast, Yuchung Cheng, Steve Ibanez,
Eric Dumazet
In-Reply-To: <F0021757-1A97-47BE-A4CC-3F7B65AD80E5@fb.com>
On Sat, Jun 30, 2018 at 9:47 PM Lawrence Brakmo <brakmo@fb.com> wrote:
> I see two issues, one is that entering quickack mode as you
> mentioned does not insure that it will still be on when the CWR
> arrives. The second issue is that the problem occurs right after the
> receiver sends a small reply which results in entering pingpong mode
> right before the sender starts the new request by sending just one
> packet (i.e. forces delayed ack).
>
> I compiled and tested your patch. Both 99 and 99.9 percentile
> latencies are around 40ms. Looking at the packet traces shows that
> some CWR marked packets are not being ack immediately (delayed by
> 40ms).
Thanks, Larry! So your tests provide nice, specific evidence that it
is good to force an immediate ACK when a receiver receives a packet
with CWR marked. Given that, I am wondering what the simplest way is
to achieve that goal.
What if, rather than plumbing a new specific signal into
__tcp_ack_snd_check(), we use the existing general quick-ack
mechanism, where various parts of the TCP stack (like
__tcp_ecn_check_ce()) are already using the quick-ack mechanism to
"remotely" signal to __tcp_ack_snd_check() that they want an immediate
ACK.
For example, would it work to do something like:
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c53ae5fc834a5..8168d1938b376 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -262,6 +262,12 @@ static void __tcp_ecn_check_ce(struct sock *sk,
const struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
+ /* If the sender is telling us it has entered CWR, then its cwnd may be
+ * very low (even just 1 packet), so we should ACK immediately.
+ */
+ if (tcp_hdr(skb)->cwr)
+ tcp_enter_quickack_mode(sk, 2);
+
switch (TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK) {
case INET_ECN_NOT_ECT:
/* Insure that GCN will not continue to mark packets. */
And then since that broadens the mission of this function beyond
checking just the ECT/CE bits, I supposed we could rename the
__tcp_ecn_check_ce() and tcp_ecn_check_ce() functions to
__tcp_ecn_check() and tcp_ecn_check(), or something like that.
Would that work for this particular issue?
neal
^ permalink raw reply related
* Re: [PATCH v3 net-next 7/9] net: ipv4: listified version of ip_rcv
From: Edward Cree @ 2018-07-02 14:59 UTC (permalink / raw)
To: netdev; +Cc: kbuild test robot, kbuild-all, davem
In-Reply-To: <201806300522.U7RgG0z9%fengguang.wu@intel.com>
On 29/06/18 23:08, kbuild test robot wrote:
> net//ipv4/ip_input.c: In function 'ip_sublist_rcv':
>>> net//ipv4/ip_input.c:524:14: warning: passing argument 6 of 'NF_HOOK_LIST' from incompatible pointer type
> head, dev, NULL, ip_rcv_finish);
> ^
> In file included from include/uapi/linux/netfilter_ipv4.h:9:0,
> from include/linux/netfilter_ipv4.h:7,
> from net//ipv4/ip_input.c:145:
> include/linux/netfilter.h:387:1: note: expected 'struct list_head *' but argument is of type 'struct net_device *'
> NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
> ^
> net//ipv4/ip_input.c:524:25: warning: passing argument 8 of 'NF_HOOK_LIST' from incompatible pointer type
> head, dev, NULL, ip_rcv_finish);
Looks like I forgot to change my stub for the CONFIG_NETFILTER=n case.
Serves me right for not doing a build test in that configuration.
Updated series to follow shortly.
And thanks, kbuild, for catching it.
-Ed
^ permalink raw reply
* Re: [PATCHv2 net-next 1/2] route: add support for directed broadcast forwarding
From: David Ahern @ 2018-07-02 15:05 UTC (permalink / raw)
To: Xin Long, network dev; +Cc: davem, Davide Caratti, idosch
In-Reply-To: <62ecbcf0c905dde3bfde51cd260e2f7c59e21028.1530512974.git.lucien.xin@gmail.com>
On 7/2/18 12:30 AM, Xin Long wrote:
> @@ -2143,6 +2149,10 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
> if ((new_value == 0) && (old_value != 0))
> rt_cache_flush(net);
>
> + if (i == IPV4_DEVCONF_BC_FORWARDING - 1 ||
> + new_value != old_value)
> + rt_cache_flush(net);
> +
Shouldn't that be '&&' instead of '||' otherwise you are bumping the fib
gen id any time the old and new values do not equal regardless of which
setting is changed.
^ permalink raw reply
* [PATCH v4 net-next 0/9] Handle multiple received packets at each stage
From: Edward Cree @ 2018-07-02 15:11 UTC (permalink / raw)
To: davem; +Cc: netdev
This patch series adds the capability for the network stack to receive a
list of packets and process them as a unit, rather than handling each
packet singly in sequence. This is done by factoring out the existing
datapath code at each layer and wrapping it in list handling code.
The motivation for this change is twofold:
* Instruction cache locality. Currently, running the entire network
stack receive path on a packet involves more code than will fit in the
lowest-level icache, meaning that when the next packet is handled, the
code has to be reloaded from more distant caches. By handling packets
in "row-major order", we ensure that the code at each layer is hot for
most of the list. (There is a corresponding downside in _data_ cache
locality, since we are now touching every packet at every layer, but in
practice there is easily enough room in dcache to hold one cacheline of
each of the 64 packets in a NAPI poll.)
* Reduction of indirect calls. Owing to Spectre mitigations, indirect
function calls are now more expensive than ever; they are also heavily
used in the network stack's architecture (see [1]). By replacing 64
indirect calls to the next-layer per-packet function with a single
indirect call to the next-layer list function, we can save CPU cycles.
Drivers pass an SKB list to the stack at the end of the NAPI poll; this
gives a natural batch size (the NAPI poll weight) and avoids waiting at
the software level for further packets to make a larger batch (which
would add latency). It also means that the batch size is automatically
tuned by the existing interrupt moderation mechanism.
The stack then runs each layer of processing over all the packets in the
list before proceeding to the next layer. Where the 'next layer' (or
the context in which it must run) differs among the packets, the stack
splits the list; this 'late demux' means that packets which differ only
in later headers (e.g. same L2/L3 but different L4) can traverse the
early part of the stack together.
Also, where the next layer is not (yet) list-aware, the stack can revert
to calling the rest of the stack in a loop; this allows gradual/creeping
listification, with no 'flag day' patch needed to listify everything.
Patches 1-2 simply place received packets on a list during the event
processing loop on the sfc EF10 architecture, then call the normal stack
for each packet singly at the end of the NAPI poll. (Analogues of patch
#2 for other NIC drivers should be fairly straightforward.)
Patches 3-9 extend the list processing as far as the IP receive handler.
Patches 1-2 alone give about a 10% improvement in packet rate in the
baseline test; adding patches 3-9 raises this to around 25%.
Performance measurements were made with NetPerf UDP_STREAM, using 1-byte
packets and a single core to handle interrupts on the RX side; this was
in order to measure as simply as possible the packet rate handled by a
single core. Figures are in Mbit/s; divide by 8 to obtain Mpps. The
setup was tuned for maximum reproducibility, rather than raw performance.
Full details and more results (both with and without retpolines) from a
previous version of the patch series are presented in [2].
The baseline test uses four streams, and multiple RXQs all bound to a
single CPU (the netperf binary is bound to a neighbouring CPU). These
tests were run with retpolines.
net-next: 6.91 Mb/s (datum)
after 9: 8.46 Mb/s (+22.5%)
Note however that these results are not robust; changes in the parameters
of the test sometimes shrink the gain to single-digit percentages. For
instance, when using only a single RXQ, only a 4% gain was seen.
One test variation was the use of software filtering/firewall rules.
Adding a single iptables rule (UDP port drop on a port range not matching
the test traffic), thus making the netfilter hook have work to do,
reduced baseline performance but showed a similar gain from the patches:
net-next: 5.02 Mb/s (datum)
after 9: 6.78 Mb/s (+35.1%)
Similarly, testing with a set of TC flower filters (kindly supplied by
Cong Wang) gave the following:
net-next: 6.83 Mb/s (datum)
after 9: 8.86 Mb/s (+29.7%)
These data suggest that the batching approach remains effective in the
presence of software switching rules, and perhaps even improves the
performance of those rules by allowing them and their codepaths to stay
in cache between packets.
Changes from v3:
* Fixed build error when CONFIG_NETFILTER=n (thanks kbuild).
Changes from v2:
* Used standard list handling (and skb->list) instead of the skb-queue
functions (that use skb->next, skb->prev).
- As part of this, changed from a "dequeue, process, enqueue" model to
using list_for_each_safe, list_del, and (new) list_cut_before.
* Altered __netif_receive_skb_core() changes in patch 6 as per Willem de
Bruijn's suggestions (separate **ppt_prev from *pt_prev; renaming).
* Removed patches to Generic XDP, since they were producing no benefit.
I may revisit them later.
* Removed RFC tags.
Changes from v1:
* Rebased across 2 years' net-next movement (surprisingly straightforward).
- Added Generic XDP handling to netif_receive_skb_list_internal()
- Dealt with changes to PFMEMALLOC setting APIs
* General cleanup of code and comments.
* Skipped function calls for empty lists at various points in the stack
(patch #9).
* Added listified Generic XDP handling (patches 10-12), though it doesn't
seem to help (see above).
* Extended testing to cover software firewalls / netfilter etc.
[1] http://vger.kernel.org/netconf2018_files/DavidMiller_netconf2018.pdf
[2] http://vger.kernel.org/netconf2018_files/EdwardCree_netconf2018.pdf
Edward Cree (9):
net: core: trivial netif_receive_skb_list() entry point
sfc: batch up RX delivery
net: core: unwrap skb list receive slightly further
net: core: Another step of skb receive list processing
net: core: another layer of lists, around PF_MEMALLOC skb handling
net: core: propagate SKB lists through packet_type lookup
net: ipv4: listified version of ip_rcv
net: ipv4: listify ip_rcv_finish
net: don't bother calling list RX functions on empty lists
drivers/net/ethernet/sfc/efx.c | 12 +++
drivers/net/ethernet/sfc/net_driver.h | 3 +
drivers/net/ethernet/sfc/rx.c | 7 +-
include/linux/list.h | 30 ++++++
include/linux/netdevice.h | 4 +
include/linux/netfilter.h | 22 +++++
include/net/ip.h | 2 +
include/trace/events/net.h | 7 ++
net/core/dev.c | 174 ++++++++++++++++++++++++++++++++--
net/ipv4/af_inet.c | 1 +
net/ipv4/ip_input.c | 114 ++++++++++++++++++++--
11 files changed, 360 insertions(+), 16 deletions(-)
^ permalink raw reply
* Re: [PATCHv2 net-next 2/2] selftests: add a selftest for directed broadcast forwarding
From: David Ahern @ 2018-07-02 15:12 UTC (permalink / raw)
To: Xin Long, network dev; +Cc: davem, Davide Caratti, idosch
In-Reply-To: <03b43b2dbda208510514082b2bd94643c3a6580c.1530512974.git.lucien.xin@gmail.com>
On 7/2/18 12:30 AM, Xin Long wrote:
> +ping_ipv4()
> +{
> + sysctl_set net.ipv4.icmp_echo_ignore_broadcasts 0
> + bc_forwarding_disable
> + ping_test $h1 198.51.100.255
> +
> + iptables -A INPUT -i vrf-r1 -p icmp -j DROP
> + bc_forwarding_restore
> + bc_forwarding_enable
> + ping_test $h1 198.51.100.255
> +
> + bc_forwarding_restore
> + iptables -D INPUT -i vrf-r1 -p icmp -j DROP
> + sysctl_restore net.ipv4.icmp_echo_ignore_broadcasts
> +}
Both tests fail for me:
TEST: ping [FAIL]
TEST: ping [FAIL]
Why the need for the iptables rule?
And, PAUSE_ON_FAIL is not working to take a look at why tests are
failing. e.g.,
PAUSE_ON_FAIL=yes ./router_broadcast.sh
just continues on. Might be something with the infrastructure scripts.
^ permalink raw reply
* [PATCH v4 net-next 1/9] net: core: trivial netif_receive_skb_list() entry point
From: Edward Cree @ 2018-07-02 15:12 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
Just calls netif_receive_skb() in a loop.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/netdevice.h | 1 +
net/core/dev.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c6b377a15869..e104b2e4a735 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3365,6 +3365,7 @@ int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb(struct sk_buff *skb);
int netif_receive_skb_core(struct sk_buff *skb);
+void netif_receive_skb_list(struct list_head *head);
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
void napi_gro_flush(struct napi_struct *napi, bool flush_old);
struct sk_buff *napi_get_frags(struct napi_struct *napi);
diff --git a/net/core/dev.c b/net/core/dev.c
index dffed642e686..110c8dfebc01 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4792,6 +4792,25 @@ int netif_receive_skb(struct sk_buff *skb)
}
EXPORT_SYMBOL(netif_receive_skb);
+/**
+ * netif_receive_skb_list - process many receive buffers from network
+ * @head: list of skbs to process.
+ *
+ * For now, just calls netif_receive_skb() in a loop, ignoring the
+ * return value.
+ *
+ * This function may only be called from softirq context and interrupts
+ * should be enabled.
+ */
+void netif_receive_skb_list(struct list_head *head)
+{
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list)
+ netif_receive_skb(skb);
+}
+EXPORT_SYMBOL(netif_receive_skb_list);
+
DEFINE_PER_CPU(struct work_struct, flush_works);
/* Network device is going away, flush any packets still pending */
^ permalink raw reply related
* [PATCH v4 net-next 2/9] sfc: batch up RX delivery
From: Edward Cree @ 2018-07-02 15:12 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
Improves packet rate of 1-byte UDP receives by up to 10%.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/efx.c | 12 ++++++++++++
drivers/net/ethernet/sfc/net_driver.h | 3 +++
drivers/net/ethernet/sfc/rx.c | 7 ++++++-
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 570ec72266f3..b24c2e21db8e 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -264,11 +264,17 @@ static int efx_check_disabled(struct efx_nic *efx)
static int efx_process_channel(struct efx_channel *channel, int budget)
{
struct efx_tx_queue *tx_queue;
+ struct list_head rx_list;
int spent;
if (unlikely(!channel->enabled))
return 0;
+ /* Prepare the batch receive list */
+ EFX_WARN_ON_PARANOID(channel->rx_list != NULL);
+ INIT_LIST_HEAD(&rx_list);
+ channel->rx_list = &rx_list;
+
efx_for_each_channel_tx_queue(tx_queue, channel) {
tx_queue->pkts_compl = 0;
tx_queue->bytes_compl = 0;
@@ -291,6 +297,10 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
}
}
+ /* Receive any packets we queued up */
+ netif_receive_skb_list(channel->rx_list);
+ channel->rx_list = NULL;
+
return spent;
}
@@ -555,6 +565,8 @@ static int efx_probe_channel(struct efx_channel *channel)
goto fail;
}
+ channel->rx_list = NULL;
+
return 0;
fail:
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 65568925c3ef..961b92979640 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -448,6 +448,7 @@ enum efx_sync_events_state {
* __efx_rx_packet(), or zero if there is none
* @rx_pkt_index: Ring index of first buffer for next packet to be delivered
* by __efx_rx_packet(), if @rx_pkt_n_frags != 0
+ * @rx_list: list of SKBs from current RX, awaiting processing
* @rx_queue: RX queue for this channel
* @tx_queue: TX queues for this channel
* @sync_events_state: Current state of sync events on this channel
@@ -500,6 +501,8 @@ struct efx_channel {
unsigned int rx_pkt_n_frags;
unsigned int rx_pkt_index;
+ struct list_head *rx_list;
+
struct efx_rx_queue rx_queue;
struct efx_tx_queue tx_queue[EFX_TXQ_TYPES];
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index d2e254f2f72b..396ff01298cd 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -634,7 +634,12 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh,
return;
/* Pass the packet up */
- netif_receive_skb(skb);
+ if (channel->rx_list != NULL)
+ /* Add to list, will pass up later */
+ list_add_tail(&skb->list, channel->rx_list);
+ else
+ /* No list, so pass it up now */
+ netif_receive_skb(skb);
}
/* Handle a received packet. Second half: Touches packet payload. */
^ permalink raw reply related
* [PATCH v4 net-next 3/9] net: core: unwrap skb list receive slightly further
From: Edward Cree @ 2018-07-02 15:13 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/trace/events/net.h | 7 +++++++
net/core/dev.c | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/trace/events/net.h b/include/trace/events/net.h
index 9c886739246a..00aa72ce0e7c 100644
--- a/include/trace/events/net.h
+++ b/include/trace/events/net.h
@@ -223,6 +223,13 @@ DEFINE_EVENT(net_dev_rx_verbose_template, netif_receive_skb_entry,
TP_ARGS(skb)
);
+DEFINE_EVENT(net_dev_rx_verbose_template, netif_receive_skb_list_entry,
+
+ TP_PROTO(const struct sk_buff *skb),
+
+ TP_ARGS(skb)
+);
+
DEFINE_EVENT(net_dev_rx_verbose_template, netif_rx_entry,
TP_PROTO(const struct sk_buff *skb),
diff --git a/net/core/dev.c b/net/core/dev.c
index 110c8dfebc01..99167ff83919 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4806,8 +4806,10 @@ void netif_receive_skb_list(struct list_head *head)
{
struct sk_buff *skb, *next;
+ list_for_each_entry(skb, head, list)
+ trace_netif_receive_skb_list_entry(skb);
list_for_each_entry_safe(skb, next, head, list)
- netif_receive_skb(skb);
+ netif_receive_skb_internal(skb);
}
EXPORT_SYMBOL(netif_receive_skb_list);
^ permalink raw reply related
* [PATCH v4 net-next 4/9] net: core: Another step of skb receive list processing
From: Edward Cree @ 2018-07-02 15:13 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
netif_receive_skb_list_internal() now processes a list and hands it
on to the next function.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/core/dev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 5 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 99167ff83919..d7f2a880aeed 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4729,6 +4729,14 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
return ret;
}
+static void __netif_receive_skb_list(struct list_head *head)
+{
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list)
+ __netif_receive_skb(skb);
+}
+
static int netif_receive_skb_internal(struct sk_buff *skb)
{
int ret;
@@ -4769,6 +4777,50 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
return ret;
}
+static void netif_receive_skb_list_internal(struct list_head *head)
+{
+ struct bpf_prog *xdp_prog = NULL;
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ net_timestamp_check(netdev_tstamp_prequeue, skb);
+ if (skb_defer_rx_timestamp(skb))
+ /* Handled, remove from list */
+ list_del(&skb->list);
+ }
+
+ if (static_branch_unlikely(&generic_xdp_needed_key)) {
+ preempt_disable();
+ rcu_read_lock();
+ list_for_each_entry_safe(skb, next, head, list) {
+ xdp_prog = rcu_dereference(skb->dev->xdp_prog);
+ if (do_xdp_generic(xdp_prog, skb) != XDP_PASS)
+ /* Dropped, remove from list */
+ list_del(&skb->list);
+ }
+ rcu_read_unlock();
+ preempt_enable();
+ }
+
+ rcu_read_lock();
+#ifdef CONFIG_RPS
+ if (static_key_false(&rps_needed)) {
+ list_for_each_entry_safe(skb, next, head, list) {
+ struct rps_dev_flow voidflow, *rflow = &voidflow;
+ int cpu = get_rps_cpu(skb->dev, skb, &rflow);
+
+ if (cpu >= 0) {
+ enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
+ /* Handled, remove from list */
+ list_del(&skb->list);
+ }
+ }
+ }
+#endif
+ __netif_receive_skb_list(head);
+ rcu_read_unlock();
+}
+
/**
* netif_receive_skb - process receive buffer from network
* @skb: buffer to process
@@ -4796,20 +4848,19 @@ EXPORT_SYMBOL(netif_receive_skb);
* netif_receive_skb_list - process many receive buffers from network
* @head: list of skbs to process.
*
- * For now, just calls netif_receive_skb() in a loop, ignoring the
- * return value.
+ * Since return value of netif_receive_skb() is normally ignored, and
+ * wouldn't be meaningful for a list, this function returns void.
*
* This function may only be called from softirq context and interrupts
* should be enabled.
*/
void netif_receive_skb_list(struct list_head *head)
{
- struct sk_buff *skb, *next;
+ struct sk_buff *skb;
list_for_each_entry(skb, head, list)
trace_netif_receive_skb_list_entry(skb);
- list_for_each_entry_safe(skb, next, head, list)
- netif_receive_skb_internal(skb);
+ netif_receive_skb_list_internal(head);
}
EXPORT_SYMBOL(netif_receive_skb_list);
^ permalink raw reply related
* [PATCH v4 net-next 5/9] net: core: another layer of lists, around PF_MEMALLOC skb handling
From: Edward Cree @ 2018-07-02 15:13 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
First example of a layer splitting the list (rather than merely taking
individual packets off it).
Involves new list.h function, list_cut_before(), like list_cut_position()
but cuts on the other side of the given entry.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/list.h | 30 ++++++++++++++++++++++++++++++
net/core/dev.c | 44 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/include/linux/list.h b/include/linux/list.h
index 4b129df4d46b..de04cc5ed536 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -285,6 +285,36 @@ static inline void list_cut_position(struct list_head *list,
__list_cut_position(list, head, entry);
}
+/**
+ * list_cut_before - cut a list into two, before given entry
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ *
+ * This helper moves the initial part of @head, up to but
+ * excluding @entry, from @head to @list. You should pass
+ * in @entry an element you know is on @head. @list should
+ * be an empty list or a list you do not care about losing
+ * its data.
+ * If @entry == @head, all entries on @head are moved to
+ * @list.
+ */
+static inline void list_cut_before(struct list_head *list,
+ struct list_head *head,
+ struct list_head *entry)
+{
+ if (head->next == entry) {
+ INIT_LIST_HEAD(list);
+ return;
+ }
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry->prev;
+ list->prev->next = list;
+ head->next = entry;
+ entry->prev = head;
+}
+
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
diff --git a/net/core/dev.c b/net/core/dev.c
index d7f2a880aeed..d2454678bc82 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4670,6 +4670,14 @@ int netif_receive_skb_core(struct sk_buff *skb)
}
EXPORT_SYMBOL(netif_receive_skb_core);
+static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemalloc)
+{
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list)
+ __netif_receive_skb_core(skb, pfmemalloc);
+}
+
static int __netif_receive_skb(struct sk_buff *skb)
{
int ret;
@@ -4695,6 +4703,34 @@ static int __netif_receive_skb(struct sk_buff *skb)
return ret;
}
+static void __netif_receive_skb_list(struct list_head *head)
+{
+ unsigned long noreclaim_flag = 0;
+ struct sk_buff *skb, *next;
+ bool pfmemalloc = false; /* Is current sublist PF_MEMALLOC? */
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ if ((sk_memalloc_socks() && skb_pfmemalloc(skb)) != pfmemalloc) {
+ struct list_head sublist;
+
+ /* Handle the previous sublist */
+ list_cut_before(&sublist, head, &skb->list);
+ __netif_receive_skb_list_core(&sublist, pfmemalloc);
+ pfmemalloc = !pfmemalloc;
+ /* See comments in __netif_receive_skb */
+ if (pfmemalloc)
+ noreclaim_flag = memalloc_noreclaim_save();
+ else
+ memalloc_noreclaim_restore(noreclaim_flag);
+ }
+ }
+ /* Handle the remaining sublist */
+ __netif_receive_skb_list_core(head, pfmemalloc);
+ /* Restore pflags */
+ if (pfmemalloc)
+ memalloc_noreclaim_restore(noreclaim_flag);
+}
+
static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
{
struct bpf_prog *old = rtnl_dereference(dev->xdp_prog);
@@ -4729,14 +4765,6 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
return ret;
}
-static void __netif_receive_skb_list(struct list_head *head)
-{
- struct sk_buff *skb, *next;
-
- list_for_each_entry_safe(skb, next, head, list)
- __netif_receive_skb(skb);
-}
-
static int netif_receive_skb_internal(struct sk_buff *skb)
{
int ret;
^ permalink raw reply related
* [PATCH v4 net-next 6/9] net: core: propagate SKB lists through packet_type lookup
From: Edward Cree @ 2018-07-02 15:13 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
__netif_receive_skb_core() does a depressingly large amount of per-packet
work that can't easily be listified, because the another_round looping
makes it nontrivial to slice up into smaller functions.
Fortunately, most of that work disappears in the fast path:
* Hardware devices generally don't have an rx_handler
* Unless you're tcpdumping or something, there is usually only one ptype
* VLAN processing comes before the protocol ptype lookup, so doesn't force
a pt_prev deliver
so normally, __netif_receive_skb_core() will run straight through and pass
back the one ptype found in ptype_base[hash of skb->protocol].
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/core/dev.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 64 insertions(+), 8 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index d2454678bc82..edd67b1f1e12 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4494,7 +4494,8 @@ static inline int nf_ingress(struct sk_buff *skb, struct packet_type **pt_prev,
return 0;
}
-static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
+static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc,
+ struct packet_type **ppt_prev)
{
struct packet_type *ptype, *pt_prev;
rx_handler_func_t *rx_handler;
@@ -4624,8 +4625,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
if (pt_prev) {
if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
goto drop;
- else
- ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
+ *ppt_prev = pt_prev;
} else {
drop:
if (!deliver_exact)
@@ -4643,6 +4643,18 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
return ret;
}
+static int __netif_receive_skb_one_core(struct sk_buff *skb, bool pfmemalloc)
+{
+ struct net_device *orig_dev = skb->dev;
+ struct packet_type *pt_prev = NULL;
+ int ret;
+
+ ret = __netif_receive_skb_core(skb, pfmemalloc, &pt_prev);
+ if (pt_prev)
+ ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
+ return ret;
+}
+
/**
* netif_receive_skb_core - special purpose version of netif_receive_skb
* @skb: buffer to process
@@ -4663,19 +4675,63 @@ int netif_receive_skb_core(struct sk_buff *skb)
int ret;
rcu_read_lock();
- ret = __netif_receive_skb_core(skb, false);
+ ret = __netif_receive_skb_one_core(skb, false);
rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL(netif_receive_skb_core);
-static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemalloc)
+static inline void __netif_receive_skb_list_ptype(struct list_head *head,
+ struct packet_type *pt_prev,
+ struct net_device *orig_dev)
{
struct sk_buff *skb, *next;
+ if (!pt_prev)
+ return;
+ if (list_empty(head))
+ return;
+
list_for_each_entry_safe(skb, next, head, list)
- __netif_receive_skb_core(skb, pfmemalloc);
+ pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
+}
+
+static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemalloc)
+{
+ /* Fast-path assumptions:
+ * - There is no RX handler.
+ * - Only one packet_type matches.
+ * If either of these fails, we will end up doing some per-packet
+ * processing in-line, then handling the 'last ptype' for the whole
+ * sublist. This can't cause out-of-order delivery to any single ptype,
+ * because the 'last ptype' must be constant across the sublist, and all
+ * other ptypes are handled per-packet.
+ */
+ /* Current (common) ptype of sublist */
+ struct packet_type *pt_curr = NULL;
+ /* Current (common) orig_dev of sublist */
+ struct net_device *od_curr = NULL;
+ struct list_head sublist;
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ struct net_device *orig_dev = skb->dev;
+ struct packet_type *pt_prev = NULL;
+
+ __netif_receive_skb_core(skb, pfmemalloc, &pt_prev);
+ if (pt_curr != pt_prev || od_curr != orig_dev) {
+ /* dispatch old sublist */
+ list_cut_before(&sublist, head, &skb->list);
+ __netif_receive_skb_list_ptype(&sublist, pt_curr, od_curr);
+ /* start new sublist */
+ pt_curr = pt_prev;
+ od_curr = orig_dev;
+ }
+ }
+
+ /* dispatch final sublist */
+ __netif_receive_skb_list_ptype(head, pt_curr, od_curr);
}
static int __netif_receive_skb(struct sk_buff *skb)
@@ -4695,10 +4751,10 @@ static int __netif_receive_skb(struct sk_buff *skb)
* context down to all allocation sites.
*/
noreclaim_flag = memalloc_noreclaim_save();
- ret = __netif_receive_skb_core(skb, true);
+ ret = __netif_receive_skb_one_core(skb, true);
memalloc_noreclaim_restore(noreclaim_flag);
} else
- ret = __netif_receive_skb_core(skb, false);
+ ret = __netif_receive_skb_one_core(skb, false);
return ret;
}
^ permalink raw reply related
* [PATCH v4 net-next 7/9] net: ipv4: listified version of ip_rcv
From: Edward Cree @ 2018-07-02 15:14 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
Also involved adding a way to run a netfilter hook over a list of packets.
Rather than attempting to make netfilter know about lists (which would be
a major project in itself) we just let it call the regular okfn (in this
case ip_rcv_finish()) for any packets it steals, and have it give us back
a list of packets it's synchronously accepted (which normally NF_HOOK
would automatically call okfn() on, but we want to be able to potentially
pass the list to a listified version of okfn().)
The netfilter hooks themselves are indirect calls that still happen per-
packet (see nf_hook_entry_hookfn()), but again, changing that can be left
for future work.
There is potential for out-of-order receives if the netfilter hook ends up
synchronously stealing packets, as they will be processed before any
accepts earlier in the list. However, it was already possible for an
asynchronous accept to cause out-of-order receives, so presumably this is
considered OK.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
include/linux/netdevice.h | 3 +++
include/linux/netfilter.h | 22 +++++++++++++++
include/net/ip.h | 2 ++
net/core/dev.c | 8 +++---
net/ipv4/af_inet.c | 1 +
net/ipv4/ip_input.c | 68 ++++++++++++++++++++++++++++++++++++++++++-----
6 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e104b2e4a735..fe81a2bfcd08 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2291,6 +2291,9 @@ struct packet_type {
struct net_device *,
struct packet_type *,
struct net_device *);
+ void (*list_func) (struct list_head *,
+ struct packet_type *,
+ struct net_device *);
bool (*id_match)(struct packet_type *ptype,
struct sock *sk);
void *af_packet_priv;
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index dd2052f0efb7..5a5e0a2ab2a3 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -288,6 +288,20 @@ NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk, struct
return ret;
}
+static inline void
+NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
+ struct list_head *head, struct net_device *in, struct net_device *out,
+ int (*okfn)(struct net *, struct sock *, struct sk_buff *))
+{
+ struct sk_buff *skb, *next;
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ int ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn);
+ if (ret != 1)
+ list_del(&skb->list);
+ }
+}
+
/* Call setsockopt() */
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
unsigned int len);
@@ -369,6 +383,14 @@ NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
return okfn(net, sk, skb);
}
+static inline void
+NF_HOOK_LIST(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
+ struct list_head *head, struct net_device *in, struct net_device *out,
+ int (*okfn)(struct net *, struct sock *, struct sk_buff *))
+{
+ /* nothing to do */
+}
+
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
struct sock *sk, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
diff --git a/include/net/ip.h b/include/net/ip.h
index 0d2281b4b27a..1de72f9cb23c 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -138,6 +138,8 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
struct ip_options_rcu *opt);
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
struct net_device *orig_dev);
+void ip_list_rcv(struct list_head *head, struct packet_type *pt,
+ struct net_device *orig_dev);
int ip_local_deliver(struct sk_buff *skb);
int ip_mr_input(struct sk_buff *skb);
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
diff --git a/net/core/dev.c b/net/core/dev.c
index edd67b1f1e12..4c5ebfab9bc8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4692,9 +4692,11 @@ static inline void __netif_receive_skb_list_ptype(struct list_head *head,
return;
if (list_empty(head))
return;
-
- list_for_each_entry_safe(skb, next, head, list)
- pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
+ if (pt_prev->list_func != NULL)
+ pt_prev->list_func(head, pt_prev, orig_dev);
+ else
+ list_for_each_entry_safe(skb, next, head, list)
+ pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
}
static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemalloc)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 06b218a2870f..3ff7659c9afd 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1882,6 +1882,7 @@ fs_initcall(ipv4_offload_init);
static struct packet_type ip_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IP),
.func = ip_rcv,
+ .list_func = ip_list_rcv,
};
static int __init inet_init(void)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 7582713dd18f..914240830bdf 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -408,10 +408,9 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
/*
* Main IP Receive routine.
*/
-int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static struct sk_buff *ip_rcv_core(struct sk_buff *skb, struct net *net)
{
const struct iphdr *iph;
- struct net *net;
u32 len;
/* When the interface is in promisc. mode, drop all the crap
@@ -421,7 +420,6 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
goto drop;
- net = dev_net(dev);
__IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -489,9 +487,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
/* Must drop socket now because of tproxy. */
skb_orphan(skb);
- return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
- net, NULL, skb, dev, NULL,
- ip_rcv_finish);
+ return skb;
csum_error:
__IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
@@ -500,5 +496,63 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
drop:
kfree_skb(skb);
out:
- return NET_RX_DROP;
+ return NULL;
+}
+
+/*
+ * IP receive entry point
+ */
+int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
+ struct net_device *orig_dev)
+{
+ struct net *net = dev_net(dev);
+
+ skb = ip_rcv_core(skb, net);
+ if (skb == NULL)
+ return NET_RX_DROP;
+ return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
+ net, NULL, skb, dev, NULL,
+ ip_rcv_finish);
+}
+
+static void ip_sublist_rcv(struct list_head *head, struct net_device *dev,
+ struct net *net)
+{
+ struct sk_buff *skb, *next;
+
+ NF_HOOK_LIST(NFPROTO_IPV4, NF_INET_PRE_ROUTING, net, NULL,
+ head, dev, NULL, ip_rcv_finish);
+ list_for_each_entry_safe(skb, next, head, list)
+ ip_rcv_finish(net, NULL, skb);
+}
+
+/* Receive a list of IP packets */
+void ip_list_rcv(struct list_head *head, struct packet_type *pt,
+ struct net_device *orig_dev)
+{
+ struct net_device *curr_dev = NULL;
+ struct net *curr_net = NULL;
+ struct sk_buff *skb, *next;
+ struct list_head sublist;
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ struct net_device *dev = skb->dev;
+ struct net *net = dev_net(dev);
+
+ skb = ip_rcv_core(skb, net);
+ if (skb == NULL)
+ continue;
+
+ if (curr_dev != dev || curr_net != net) {
+ /* dispatch old sublist */
+ list_cut_before(&sublist, head, &skb->list);
+ if (!list_empty(&sublist))
+ ip_sublist_rcv(&sublist, dev, net);
+ /* start new sublist */
+ curr_dev = dev;
+ curr_net = net;
+ }
+ }
+ /* dispatch final sublist */
+ ip_sublist_rcv(head, curr_dev, curr_net);
}
^ permalink raw reply related
* [PATCH v4 net-next 8/9] net: ipv4: listify ip_rcv_finish
From: Edward Cree @ 2018-07-02 15:14 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
ip_rcv_finish_core(), if it does not drop, sets skb->dst by either early
demux or route lookup. The last step, calling dst_input(skb), is left to
the caller; in the listified case, we split to form sublists with a common
dst, but then ip_sublist_rcv_finish() just calls dst_input(skb) in a loop.
The next step in listification would thus be to add a list_input() method
to struct dst_entry.
Early demux is an indirect call based on iph->protocol; this is another
opportunity for listification which is not taken here (it would require
slicing up ip_rcv_finish_core() to allow splitting on protocol changes).
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/ipv4/ip_input.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 914240830bdf..24b9b0210aeb 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -307,7 +307,8 @@ static inline bool ip_rcv_options(struct sk_buff *skb)
return true;
}
-static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
{
const struct iphdr *iph = ip_hdr(skb);
int (*edemux)(struct sk_buff *skb);
@@ -393,7 +394,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
goto drop;
}
- return dst_input(skb);
+ return NET_RX_SUCCESS;
drop:
kfree_skb(skb);
@@ -405,6 +406,15 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
goto drop;
}
+static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+{
+ int ret = ip_rcv_finish_core(net, sk, skb);
+
+ if (ret != NET_RX_DROP)
+ ret = dst_input(skb);
+ return ret;
+}
+
/*
* Main IP Receive routine.
*/
@@ -515,15 +525,47 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
ip_rcv_finish);
}
-static void ip_sublist_rcv(struct list_head *head, struct net_device *dev,
- struct net *net)
+static void ip_sublist_rcv_finish(struct list_head *head)
{
struct sk_buff *skb, *next;
+ list_for_each_entry_safe(skb, next, head, list)
+ dst_input(skb);
+}
+
+static void ip_list_rcv_finish(struct net *net, struct sock *sk,
+ struct list_head *head)
+{
+ struct dst_entry *curr_dst = NULL;
+ struct sk_buff *skb, *next;
+ struct list_head sublist;
+
+ list_for_each_entry_safe(skb, next, head, list) {
+ struct dst_entry *dst;
+
+ if (ip_rcv_finish_core(net, sk, skb) == NET_RX_DROP)
+ continue;
+
+ dst = skb_dst(skb);
+ if (curr_dst != dst) {
+ /* dispatch old sublist */
+ list_cut_before(&sublist, head, &skb->list);
+ if (!list_empty(&sublist))
+ ip_sublist_rcv_finish(&sublist);
+ /* start new sublist */
+ curr_dst = dst;
+ }
+ }
+ /* dispatch final sublist */
+ ip_sublist_rcv_finish(head);
+}
+
+static void ip_sublist_rcv(struct list_head *head, struct net_device *dev,
+ struct net *net)
+{
NF_HOOK_LIST(NFPROTO_IPV4, NF_INET_PRE_ROUTING, net, NULL,
head, dev, NULL, ip_rcv_finish);
- list_for_each_entry_safe(skb, next, head, list)
- ip_rcv_finish(net, NULL, skb);
+ ip_list_rcv_finish(net, NULL, head);
}
/* Receive a list of IP packets */
^ permalink raw reply related
* [PATCH v4 net-next 9/9] net: don't bother calling list RX functions on empty lists
From: Edward Cree @ 2018-07-02 15:14 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <5bf84d99-8f77-54ee-7543-ada13a730361@solarflare.com>
Generally the check should be very cheap, as the sk_buff_head is in cache.
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
net/core/dev.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 4c5ebfab9bc8..d6084b0cd9ce 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4773,7 +4773,8 @@ static void __netif_receive_skb_list(struct list_head *head)
/* Handle the previous sublist */
list_cut_before(&sublist, head, &skb->list);
- __netif_receive_skb_list_core(&sublist, pfmemalloc);
+ if (!list_empty(&sublist))
+ __netif_receive_skb_list_core(&sublist, pfmemalloc);
pfmemalloc = !pfmemalloc;
/* See comments in __netif_receive_skb */
if (pfmemalloc)
@@ -4783,7 +4784,8 @@ static void __netif_receive_skb_list(struct list_head *head)
}
}
/* Handle the remaining sublist */
- __netif_receive_skb_list_core(head, pfmemalloc);
+ if (!list_empty(head))
+ __netif_receive_skb_list_core(head, pfmemalloc);
/* Restore pflags */
if (pfmemalloc)
memalloc_noreclaim_restore(noreclaim_flag);
@@ -4944,6 +4946,8 @@ void netif_receive_skb_list(struct list_head *head)
{
struct sk_buff *skb;
+ if (list_empty(head))
+ return;
list_for_each_entry(skb, head, list)
trace_netif_receive_skb_list_entry(skb);
netif_receive_skb_list_internal(head);
^ permalink raw reply related
* Re: incomplete firmware-version shown in ethtool -i
From: John W. Linville @ 2018-07-02 15:06 UTC (permalink / raw)
To: Gang Gang10 Liu; +Cc: netdev@vger.kernel.org
In-Reply-To: <CB4BD528EE74B3468883651D71AA4268767B8308@CNMAILEX03.lenovo.com>
On Wed, Jun 27, 2018 at 07:54:39AM +0000, Gang Gang10 Liu wrote:
> Dear,
>
> I study that the ethtool only can show 31 characters firmware version, is it NIC driver not followed ethtool spec or
> Can we have any other way to get the full firmware version?
>
I think the bnxt team is doing what they can to make as much
information available as possible. In this case, they seem to be
trying to make versioning info about the firmware package available
along with the info about the firmware version itself, and together
just barely overflowing the available space in the ethtool structure.
I'll leave it to you and/or Broadcom to determine whether or not that
is a bug that needs to be changed.
In the meanwhile, from your quoted message it seems that lspci can
give you the correct package version information for the device.
Good luck!
John
>
> Thanks!
>
>
> [http://lenovocentral.lenovo.com/marketing/branding/email_signature/images/gradient.gif]
>
> Gang Liu 刘刚
> Global Advisory Testing Engineer
>
> DCG Test Strategy and Automation
> Lenovo SZ
>
> [http://lenovocentral.lenovo.com/marketing/branding/email_signature/images/Email%20Gifs/T.gif]+86 13620981830
> [http://lenovocentral.lenovo.com/marketing/branding/email_signature/images/Email%20Gifs/E.gif]liugang10@lenovo.com<mailto:rrivera2@lenovo.com>
>
>
>
> Lenovo.com <http://www.lenovo.com/>
> Twitter<http://twitter.com/lenovo> | Facebook<http://www.facebook.com/lenovo> | Instagram<https://instagram.com/lenovo> | Blogs<http://blog.lenovo.com/> | Forums<http://forums.lenovo.com/>
>
>
> [The-Lenovo-Way]
>
>
>
>
>
>
> From: Gang Gang10 Liu
> Sent: Wednesday, June 27, 2018 3:13 PM
> To: Ken Cheng4 <kcheng4@lenovo.com>; Yuhong YH6 Wu <wuyh6@lenovo.com>; Qinwei QW1 Yu <yuqw1@lenovo.com>; Vincent HY1 Long <longhy1@lenovo.com>; -Product GTE <-Product_GTE@lenovo.com>
> Cc: Frank Y Wu <frankwu@lenovo.com>
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Hi all,
>
>
> From ethtool source code, the root cause for this issue is:
>
> the internal buffer for firmware-version in ethtool is 32 (include the string tail zero), so it only can show 31 characters version.
> But the actual firmware-version got from NIC driver is large than 32.
>
> struct ethtool_drvinfo {
> __u32 cmd;
> char driver[32];
> char version[32];
> char fw_version[ETHTOOL_FWVERS_LEN];
> …
>
> #define ETHTOOL_FWVERS_LEN 32
>
>
>
>
> From: Ken Cheng4
> Sent: Wednesday, June 27, 2018 2:44 PM
> To: Yuhong YH6 Wu <wuyh6@lenovo.com<mailto:wuyh6@lenovo.com>>; Qinwei QW1 Yu <yuqw1@lenovo.com<mailto:yuqw1@lenovo.com>>; Vincent HY1 Long <longhy1@lenovo.com<mailto:longhy1@lenovo.com>>; -Product GTE <-Product_GTE@lenovo.com<mailto:-Product_GTE@lenovo.com>>; Gang Gang10 Liu <liugang10@lenovo.com<mailto:liugang10@lenovo.com>>
> Cc: Frank Y Wu <frankwu@lenovo.com<mailto:frankwu@lenovo.com>>
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Yuhong,
>
> A merge request for common had been raised to fix the failure from this ethtool bug while testing firmware level of Broadcom cards.
> https://l3-prd01-rtp.labs.lenovo.com:4443/te/common/merge_requests/1513
>
>
> ===Background===
> Ethtool can not return correctly when the last number is zero like "212.0.107/1.9.1 pkg 212.0.112." <--missing 0 in the end.
>
> Code change is to:
>
> (1) get incomplete version like: 212.0.112
> (2) get complete version from lspci like "[V0] Vendor specific: 212.0.112.0"
> (3) compare the first three numbers with the firmware level from ethtool, ex:212.0.112
> (4) if the first three numbers match, fill incomplete firmware version from ethtool with correct one from lspci like: "212.0.107/1.9.1 pkg 212.0.112.0"
>
> I will let Liu Gang to review first and then submit another merge request for more_common.
>
>
>
> Ken Cheng
> Global TE Engineer
> LME
> Taiwan
>
>
> kcheng4@lenovo.com<mailto:e-mail>
> Ph: +886 2 8170-7580
> Fax: +886 2 2651-8246
>
>
> Shipping Address:
> Lenovo Technology B.V. Taiwan Branch
> 4F, No. 66 SanChong Road, NanGang,
> Taipei, Taiwan, 11502
> 荷蘭商聯想股份有限公司台灣分公司
> 台北市南港區三重路66號4樓
>
> [描述: Lenovo-For-Those-Who-Do]
>
>
>
> From: Ken Cheng4
> Sent: Tuesday, June 26, 2018 12:35 PM
> To: Yuhong YH6 Wu; Qinwei QW1 Yu; Vincent HY1 Long; -Product GTE
> Cc: Frank Y Wu
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Yuhong,
>
> We may need more time to investigate whether his statement is valid for the other component cards:
>
> === quoted from Qinwei ===
> I believe it has same problem for other vendor adapters when the last number of FW version is 0.
>
> But for now I think a quick patch might be better for EOQ support. I was thinking to add an additional zero in the end of fw string when the last digit returned from ethtool is period ‘.’ in order to avoid that tuple error.
>
> For example, to add an additional 0 after “212.0.112.” before it is sent to tuple actual_parts = version_tuple(actual)
>
>
> Ken Cheng
> Global TE Engineer
> LME
> Taiwan
>
>
> kcheng4@lenovo.com<mailto:e-mail>
> Ph: +886 2 8170-7580
> Fax: +886 2 2651-8246
>
>
> Shipping Address:
> Lenovo Technology B.V. Taiwan Branch
> 4F, No. 66 SanChong Road, NanGang,
> Taipei, Taiwan, 11502
> 荷蘭商聯想股份有限公司台灣分公司
> 台北市南港區三重路66號4樓
>
> [描述: Lenovo-For-Those-Who-Do]
>
>
>
> From: Yuhong YH6 Wu
> Sent: Tuesday, June 26, 2018 10:41 AM
> To: Qinwei QW1 Yu; Vincent HY1 Long; -Product GTE; Ken Cheng4
> Cc: Frank Y Wu
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Hi Ken,
>
> Pre talk with Dev Qinwei brcm fw show have some problem by ethtool whether able to use lspci common replace ethtool to read fw level as below.
>
> [6/26/2018 10:07 AM] Yuhong YH6 Wu:
>
> [root@localhost ~]# ethtool -i eth2
> driver: bnxt_en
> version: 1.7.25
> firmware-version: 212.0.107/1.9.1 pkg 212.0.112. – missing 0
> expansion-rom-version:
> bus-info: 0000:06:00.0
> supports-statistics: yes
> supports-test: yes
> supports-eeprom-access: yes
> supports-register-dump: no
> supports-priv-flags: no
> 重启之后那个0就没了
> [6/26/2018 10:09 AM] Yuhong YH6 Wu:
>
> [root@localhost ~]# lspci -vv -s 06:00.0 |grep V0 -- lspci can read out complete string character.
> [V0] Vendor specific: 212.0.112.0
> 这里看到有
>
>
>
> From: Yuhong YH6 Wu
> Sent: Tuesday, June 26, 2018 9:20 AM
> To: Qinwei QW1 Yu <yuqw1@lenovo.com<mailto:yuqw1@lenovo.com>>; Vincent HY1 Long <longhy1@lenovo.com<mailto:longhy1@lenovo.com>>; -Product GTE <-Product_GTE@lenovo.com<mailto:-Product_GTE@lenovo.com>>; Ken Cheng4 <kcheng4@lenovo.com<mailto:kcheng4@lenovo.com>>
> Cc: Frank Y Wu <frankwu@lenovo.com<mailto:frankwu@lenovo.com>>
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Hi Qinwei,
> But actual fw level is ‘212.0.112.’ and chg log is ‘Firmware Version: 212.0.112.0’ are you sure this is correct ?
>
> Hi Ken,
>
> If ‘212.0.112.’ fw is correct we need change the common code fix below issue from Broadcom.py.
>
> 180625-11:26:32 INFO ----------------------------------------------------------------------------------------------------
> 180625-11:26:32 INFO | Broadcom FW Flash |
> 180625-11:26:32 INFO ----------------------------------------------------------------------------------------------------
> 180625-11:26:32 INFO Fetching Broadcom information for location Rear Slot 2
> 180625-11:26:36 INFO Configuring <eth0>...
> 180625-11:26:36 INFO Configuring <eth1>...
> 180625-11:26:38 INFO Configuring <eth2>...
> 180625-11:26:40 INFO Configuring <eth3>...
> 180625-11:26:42 INFO Configuring <eth4>...
> 180625-11:26:44 INFO Configuring <eth5>...
> 180625-11:26:46 INFO Configuring <eth6>...
> 180625-11:26:46 INFO Configuring <eth7>...
> 180625-11:26:48 INFO Configuring <eth8>...
> 180625-11:26:50 INFO Configuring <eth9>...
> 180625-11:26:52 INFO Configuring <eth10>...
> 180625-11:26:54 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:54 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO pattern:\.|-v|-,version:5719-v1.47
> 180625-11:26:56 INFO pattern:\.|-v|-,version:5719-v1.47
> 180625-11:26:56 INFO Verified Broadcom [Slot 2] firmware level actual(=5719-v1.47) == expected(=5719-v1.47)
> 180625-11:26:56 INFO Fetching Broadcom information for location Rear Slot 1
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:56 INFO bnxt_en:212.0.107/1.9.1 pkg 212.0.112.
> 180625-11:26:57 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:57 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:57 INFO bnxt_en:212.0.107/1.9.1 pkg 212.0.112.
> 180625-11:26:57 INFO pattern:\.|-v|-,version:212.0.112.
> 180625-11:26:57 ERR* Unhandled Exception has been thrown
> 180625-11:26:57 EXC** Traceback (most recent call last):
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/platform/modules/Run.py", line 384, in runmain
> 180625-11:26:57 EXC** result = func(*bares, **keywords)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/tests/broadcom_code_test.py", line 37, in main
> 180625-11:26:57 EXC** broadcom.verify_firmware_level(location)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 180, in verify_firmware_level
> 180625-11:26:57 EXC** result, expected, actual = self._verify_firmware_level(location)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 193, in _verify_firmware_level
> 180625-11:26:57 EXC** actual_parts = version_tuple(actual)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 59, in version_tuple
> 180625-11:26:57 EXC** return tuple(int(v, base) for v in re.split(pattern, version))
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 59, in <genexpr>
> 180625-11:26:57 EXC** return tuple(int(v, base) for v in re.split(pattern, version))
> 180625-11:26:57 EXC** ValueError: invalid literal for int() with base 16: ''
> 180625-11:26:57 FAIL FAIL
> 180625-11:26:57 TESTE FAIL broadcom_code_test.py flash
>
>
> From: Qinwei QW1 Yu
> Sent: Monday, June 25, 2018 6:50 PM
> To: Yuhong YH6 Wu <wuyh6@lenovo.com<mailto:wuyh6@lenovo.com>>; Vincent HY1 Long <longhy1@lenovo.com<mailto:longhy1@lenovo.com>>; -Product GTE <-Product_GTE@lenovo.com<mailto:-Product_GTE@lenovo.com>>
> Cc: Frank Y Wu <frankwu@lenovo.com<mailto:frankwu@lenovo.com>>
> Subject: RE: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Hi Yuhong
>
> The version in adapter VPD is correct.
> I suppose it is caused by ethtool.
> Different ethtool version has different display. See attachment.
> I believe it has same problem for other vendor adapters when the last number of FW version is 0.
>
> Best Regards!
>
> -Qinwei
> NIC Engineer
>
> From: Yuhong YH6 Wu
> Sent: Monday, June 25, 2018 1:29 PM
> To: Qinwei QW1 Yu <yuqw1@lenovo.com<mailto:yuqw1@lenovo.com>>; Vincent HY1 Long <longhy1@lenovo.com<mailto:longhy1@lenovo.com>>; -Product GTE <-Product_GTE@lenovo.com<mailto:-Product_GTE@lenovo.com>>
> Cc: Frank Y Wu <frankwu@lenovo.com<mailto:frankwu@lenovo.com>>
> Subject: common fw brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64 issue
>
> Hi Qinwei,
> Per talk in lync bnxt_en fw show at ‘212.0.112.’ but actually need is ‘212.0.112.0’ from 18b bin file ‘brcm-lnvgy_fw_nic_nxe-212.0.112.0-a_linux_x86-64.bin’
> Pls help to confirm this.
>
> [root@localhost ~]# ethtool -i eth5
> driver: bnxt_en
> version: 1.7.25
> firmware-version: 212.0.107/1.9.1 pkg 212.0.112.
> expansion-rom-version:
> bus-info: 0000:30:00.0
> supports-statistics: yes
> supports-test: yes
> supports-eeprom-access: yes
> supports-register-dump: no
> supports-priv-flags: no
>
> failed in test process as below info:
>
>
> 180625-11:26:32 INFO ----------------------------------------------------------------------------------------------------
> 180625-11:26:32 INFO | Broadcom FW Flash |
> 180625-11:26:32 INFO ----------------------------------------------------------------------------------------------------
> 180625-11:26:32 INFO Fetching Broadcom information for location Rear Slot 2
> 180625-11:26:36 INFO Configuring <eth0>...
> 180625-11:26:36 INFO Configuring <eth1>...
> 180625-11:26:38 INFO Configuring <eth2>...
> 180625-11:26:40 INFO Configuring <eth3>...
> 180625-11:26:42 INFO Configuring <eth4>...
> 180625-11:26:44 INFO Configuring <eth5>...
> 180625-11:26:46 INFO Configuring <eth6>...
> 180625-11:26:46 INFO Configuring <eth7>...
> 180625-11:26:48 INFO Configuring <eth8>...
> 180625-11:26:50 INFO Configuring <eth9>...
> 180625-11:26:52 INFO Configuring <eth10>...
> 180625-11:26:54 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:54 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5bdef98>
> 180625-11:26:56 INFO pattern:\.|-v|-,version:5719-v1.47
> 180625-11:26:56 INFO pattern:\.|-v|-,version:5719-v1.47
> 180625-11:26:56 INFO Verified Broadcom [Slot 2] firmware level actual(=5719-v1.47) == expected(=5719-v1.47)
> 180625-11:26:56 INFO Fetching Broadcom information for location Rear Slot 1
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:56 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:56 INFO bnxt_en:212.0.107/1.9.1 pkg 212.0.112.
> 180625-11:26:57 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:57 INFO <LANTools.NETIF object at 0x7f18b5be2dd8>
> 180625-11:26:57 INFO bnxt_en:212.0.107/1.9.1 pkg 212.0.112.
> 180625-11:26:57 INFO pattern:\.|-v|-,version:212.0.112.
> 180625-11:26:57 ERR* Unhandled Exception has been thrown
> 180625-11:26:57 EXC** Traceback (most recent call last):
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/platform/modules/Run.py", line 384, in runmain
> 180625-11:26:57 EXC** result = func(*bares, **keywords)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/tests/broadcom_code_test.py", line 37, in main
> 180625-11:26:57 EXC** broadcom.verify_firmware_level(location)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 180, in verify_firmware_level
> 180625-11:26:57 EXC** result, expected, actual = self._verify_firmware_level(location)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 193, in _verify_firmware_level
> 180625-11:26:57 EXC** actual_parts = version_tuple(actual)
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 59, in version_tuple
> 180625-11:26:57 EXC** return tuple(int(v, base) for v in re.split(pattern, version))
> 180625-11:26:57 EXC** File "/dfcxact/mtsn/J3002240/debug_yuhongw_18b_brcm/repos/common/modules/Broadcom.py", line 59, in <genexpr>
> 180625-11:26:57 EXC** return tuple(int(v, base) for v in re.split(pattern, version))
> 180625-11:26:57 EXC** ValueError: invalid literal for int() with base 16: ''
> 180625-11:26:57 FAIL FAIL
> 180625-11:26:57 TESTE FAIL broadcom_code_test.py flash
>
> Globa Test Engineer
> Email: wuyh6@lenovo.com<mailto:wuyh6@lenovo.com>
>
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH net-next 1/2] tcp: notify when a delayed ack is sent
From: Neal Cardwell @ 2018-07-02 15:17 UTC (permalink / raw)
To: Lawrence Brakmo
Cc: Netdev, Kernel Team, bmatheny, ast, Yuchung Cheng, Steve Ibanez,
Eric Dumazet
In-Reply-To: <20180630014815.2881895-2-brakmo@fb.com>
On Fri, Jun 29, 2018 at 9:48 PM Lawrence Brakmo <brakmo@fb.com> wrote:
>
> DCTCP depends on the CA_EVENT_NON_DELAYED_ACK and CA_EVENT_DELAYED_ACK
> notifications to keep track if it needs to send an ACK for packets that
> were received with a particular ECN state but whose ACK was delayed.
>
> Under some circumstances, for example when a delayed ACK is sent with a
> data packet, DCTCP state was not being updated due to a lack of
> notification that the previously delayed ACK was sent. As a result, it
> would sometimes send a duplicate ACK when a new data packet arrived.
>
> This patch insures that DCTCP's state is correctly updated so it will
> not send the duplicate ACK.
>
> Signed-off-by: Lawrence Brakmo <brakmo@fb.com>
> ---
> net/ipv4/tcp_output.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index f8f6129160dd..41f6ad7a21e4 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -172,6 +172,8 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
> __sock_put(sk);
> }
> tcp_dec_quickack_mode(sk, pkts);
> + if (inet_csk_ack_scheduled(sk))
> + tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
> inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
> }
Thanks for this fix! Seems like this would work, but if I am reading
this correctly then it seems like this would cause a duplicate call to
tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK) when we are sending a pure
ACK (delayed or non-delayed):
(1) once from tcp_send_ack() before we send the ACK:
tcp_send_ack(struct sock *sk)
-> tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
(2) then again from tcp_event_ack_sent() after we have sent the ACK:
tcp_event_ack_sent()
-> if (inet_csk_ack_scheduled(sk))
tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
What if we remove the original CA_EVENT_NON_DELAYED_ACK call and just
replace it with your new one? (not compiled, not tested):
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3889dcd4868d4..bddb49617d9be 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -184,6 +184,8 @@ static inline void tcp_event_ack_sent(struct sock
*sk, unsigned int pkts)
__sock_put(sk);
}
tcp_dec_quickack_mode(sk, pkts);
+ if (inet_csk_ack_scheduled(sk))
+ tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
}
@@ -3836,8 +3838,6 @@ void tcp_send_ack(struct sock *sk)
if (sk->sk_state == TCP_CLOSE)
return;
- tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK);
-
/* We are not putting this on the write queue, so
* tcp_transmit_skb() will set the ownership to this
* sock.
Aside from lower CPU overhead, one nice benefit of that is that we
then only call tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK) in one
place, which might be a little easier to reason about.
Does that work?
neal
^ permalink raw reply related
* Re: Compiler warnings in kernel 4.14.51
From: David Ahern @ 2018-07-02 15:18 UTC (permalink / raw)
To: Enrico Mioso, netdev
Cc: David S. Miller, Daniel Borkmann, Kirill Tkhai, Jakub Kicinski,
Alexei Starovoitov, Rasmus Villemoes, John Fastabend,
Jesper Dangaard Brouer
In-Reply-To: <20180701203507.GA15211@mStation.localdomain>
On 7/1/18 2:35 PM, Enrico Mioso wrote:
> Hello!
>
> While compiling kernel 4.14.51 I got the following warnings:
> CC net/core/dev.o
> net/core/dev.c: In function 'validate_xmit_skb_list':
> net/core/dev.c:3121:15: warning: 'tail' may be used uninitialized in this function [-Wmaybe-uninitialized]
> ...
>
> CC net/ipv4/fib_trie.o
> net/ipv4/fib_trie.c: In function 'fib_trie_unmerge':
> net/ipv4/fib_trie.c:1749:8: warning: 'local_tp' may be used uninitialized in this function [-Wmaybe-uninitialized]
>
> The kernel has been compiled for the MIPS architecture, little-endian 32-bit.
Not seen with x86-64, Debian stretch. In both cases the compiler should
be able to see they are set before use.
^ 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