* Re: ipsec doesn't route TCP with 4.11 kernel
From: Steffen Klassert @ 2017-05-03 8:21 UTC (permalink / raw)
To: Eric Dumazet
Cc: Don Bowman, Cong Wang, linux-kernel@vger.kernel.org, Herbert Xu,
Linux Kernel Network Developers
In-Reply-To: <1493398002.31837.12.camel@edumazet-glaptop3.roam.corp.google.com>
On Fri, Apr 28, 2017 at 09:46:42AM -0700, Eric Dumazet wrote:
> On Fri, 2017-04-28 at 09:13 +0200, Steffen Klassert wrote:
> > encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
> >
> > Ok, this is espinudp. This information was important.
>
> > This is not a GRO issue as I thought, the TX side is already broken.
> >
> > Could you please try the patch below?
> >
> > Subject: [PATCH] esp4: Fix udpencap for local TCP packets.
> >
> > Locally generated TCP packets are usually cloned, so we
> > do skb_cow_data() on this packets. After that we need to
> > reload the pointer to the esp header. On udpencap this
> > header has an offset to skb_transport_header, so take this
> > offset into account.
>
>
> It looks like locally generated TCP packets could avoid the
> skb_cow_data(), if you were using skb_header_cloned() instead of
> skb_cloned() ?
Yes, should be possible in the codepath where we do crypto
with separate src and dst buffers. Would require some
rearrangements to make sure we don't do inplace crypto
in this case.
Thanks for the hint!
^ permalink raw reply
* Re: ipsec doesn't route TCP with 4.11 kernel
From: Steffen Klassert @ 2017-05-03 8:14 UTC (permalink / raw)
To: Don Bowman
Cc: Cong Wang, linux-kernel@vger.kernel.org, Herbert Xu,
Linux Kernel Network Developers
In-Reply-To: <CADJev7_Tc0aRsPs0Q7Wijd-YBM39ZshitJpSo2yEqPVwag2X_Q@mail.gmail.com>
On Sat, Apr 29, 2017 at 08:39:34PM -0400, Don Bowman wrote:
> On 28 April 2017 at 03:13, Steffen Klassert
> <steffen.klassert@secunet.com> wrote:
> > On Thu, Apr 27, 2017 at 06:13:38PM -0400, Don Bowman wrote:
> >> On 27 April 2017 at 04:42, Steffen Klassert <steffen.klassert@secunet.com>
> >> wrote:
> >> > On Wed, Apr 26, 2017 at 10:01:34PM -0700, Cong Wang wrote:
> >> >> (Cc'ing netdev and IPSec maintainers)
> >> >>
> >> >> On Tue, Apr 25, 2017 at 6:08 PM, Don Bowman <db@donbowman.ca> wrote:
> >>
>
> <snip>
>
> confirmed, with this patch in place that the tcp functions properly.
Thanks for testing!
I'll make sure to get this fix into the mainline soon.
^ permalink raw reply
* Re: [PATCH] net: ethernet: stmmac: properly set PS bit in MII configurations during reset
From: Giuseppe CAVALLARO @ 2017-05-03 8:13 UTC (permalink / raw)
To: Thomas Petazzoni, Alexandre Torgue; +Cc: netdev, stable
In-Reply-To: <1493286329-24448-1-git-send-email-thomas.petazzoni@free-electrons.com>
Hello Thomas
this was initially set by using the hw->link.port; both the core_init
and adjust callback
should invoke the hook and tuning the PS bit according to the speed and
mode.
So maybe the ->set_ps is superfluous and you could reuse the existent hook
let me know
Regards
peppe
On 4/27/2017 11:45 AM, Thomas Petazzoni wrote:
> On the SPEAr600 SoC, which has the dwmac1000 variant of the IP block,
> the DMA reset never succeeds when a MII PHY is used (no problem with a
> GMII PHY). The dwmac_dma_reset() function sets the
> DMA_BUS_MODE_SFT_RESET bit in the DMA_BUS_MODE register, and then
> polls until this bit clears. When a MII PHY is used, with the current
> driver, this bit never clears and the driver therefore doesn't work.
>
> The reason is that the PS bit of the GMAC_CONTROL register should be
> correctly configured for the DMA reset to work. When the PS bit is 0,
> it tells the MAC we have a GMII PHY, when the PS bit is 1, it tells
> the MAC we have a MII PHY.
>
> Doing a DMA reset clears all registers, so the PS bit is cleared as
> well. This makes the DMA reset work fine with a GMII PHY. However,
> with MII PHY, the PS bit should be set.
>
> We have identified this issue thanks to two SPEAr600 platform:
>
> - One equipped with a GMII PHY, with which the existing driver was
> working fine.
>
> - One equipped with a MII PHY, where the current driver fails because
> the DMA reset times out.
>
> This patch fixes the problem for the MII PHY configuration, and has
> been tested with a GMII PHY configuration as well.
>
> In terms of implement, since the ->reset() hook is implemented in the
> DMA related code, we do not want to touch directly from this function
> the MAC registers. Therefore, a ->set_ps() hook has been added to
> stmmac_ops, which gets called between the moment the reset is asserted
> and the polling loop waiting for the reset bit to clear.
>
> In order for this ->set_ps() hook to decide what to do, we pass it the
> "struct mac_device_info" so it can access the MAC registers, and the
> PHY interface type so it knows if we're using a MII PHY or not.
>
> The ->set_ps() hook is only implemented for the dwmac1000 case.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: <stable@vger.kernel.org>
> ---
> Do not hesitate to suggest ideas for alternative implementations, I'm
> not sure if the current proposal is the one that fits best with the
> current design of the driver.
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 12 +++++++++---
> drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 16 ++++++++++++++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 3 ++-
> drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 7 ++++++-
> drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 3 ++-
> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 6 +++++-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
> 7 files changed, 42 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 04d9245..d576f95 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -407,10 +407,13 @@ struct stmmac_desc_ops {
> extern const struct stmmac_desc_ops enh_desc_ops;
> extern const struct stmmac_desc_ops ndesc_ops;
>
> +struct mac_device_info;
> +
> /* Specific DMA helpers */
> struct stmmac_dma_ops {
> /* DMA core initialization */
> - int (*reset)(void __iomem *ioaddr);
> + int (*reset)(void __iomem *ioaddr, struct mac_device_info *hw,
> + phy_interface_t interface);
> void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
> u32 dma_tx, u32 dma_rx, int atds);
> /* Configure the AXI Bus Mode Register */
> @@ -445,12 +448,15 @@ struct stmmac_dma_ops {
> void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
> };
>
> -struct mac_device_info;
> -
> /* Helpers to program the MAC core */
> struct stmmac_ops {
> /* MAC core initialization */
> void (*core_init)(struct mac_device_info *hw, int mtu);
> + /* Set port select. Called between asserting DMA reset and
> + * waiting for the reset bit to clear.
> + */
> + void (*set_ps)(struct mac_device_info *hw,
> + phy_interface_t interface);
> /* Enable and verify that the IPC module is supported */
> int (*rx_ipc)(struct mac_device_info *hw);
> /* Enable RX Queues */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
> index 19b9b308..dfcbb5b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
> @@ -75,6 +75,21 @@ static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
> #endif
> }
>
> +static void dwmac1000_set_ps(struct mac_device_info *hw,
> + phy_interface_t interface)
> +{
> + void __iomem *ioaddr = hw->pcsr;
> + u32 value = readl(ioaddr + GMAC_CONTROL);
> +
> + /* When a MII PHY is used, we must set the PS bit for the DMA
> + * reset to succeed.
> + */
> + if (interface == PHY_INTERFACE_MODE_MII)
> + value |= GMAC_CONTROL_PS;
> +
> + writel(value, ioaddr + GMAC_CONTROL);
> +}
> +
> static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
> {
> void __iomem *ioaddr = hw->pcsr;
> @@ -488,6 +503,7 @@ static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
>
> static const struct stmmac_ops dwmac1000_ops = {
> .core_init = dwmac1000_core_init,
> + .set_ps = dwmac1000_set_ps,
> .rx_ipc = dwmac1000_rx_ipc_enable,
> .dump_regs = dwmac1000_dump_regs,
> .host_irq_status = dwmac1000_irq_status,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> index 1b06df7..e9c6c49 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> @@ -183,7 +183,8 @@
> #define DMA_CHAN0_DBG_STAT_RPS GENMASK(11, 8)
> #define DMA_CHAN0_DBG_STAT_RPS_SHIFT 8
>
> -int dwmac4_dma_reset(void __iomem *ioaddr);
> +int dwmac4_dma_reset(void __iomem *ioaddr, struct mac_device_info *hw,
> + phy_interface_t interface);
> void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr);
> void dwmac4_enable_dma_irq(void __iomem *ioaddr);
> void dwmac410_enable_dma_irq(void __iomem *ioaddr);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index c7326d5..485eecb 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -14,7 +14,8 @@
> #include "dwmac4_dma.h"
> #include "dwmac4.h"
>
> -int dwmac4_dma_reset(void __iomem *ioaddr)
> +int dwmac4_dma_reset(void __iomem *ioaddr, struct mac_device_info *hw,
> + phy_interface_t interface)
> {
> u32 value = readl(ioaddr + DMA_BUS_MODE);
> int limit;
> @@ -22,6 +23,10 @@ int dwmac4_dma_reset(void __iomem *ioaddr)
> /* DMA SW reset */
> value |= DMA_BUS_MODE_SFT_RESET;
> writel(value, ioaddr + DMA_BUS_MODE);
> +
> + if (hw->mac->set_ps)
> + hw->mac->set_ps(hw, interface);
> +
> limit = 10;
> while (limit--) {
> if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> index 56e485f..25ae028 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
> @@ -144,6 +144,7 @@ void dwmac_dma_stop_tx(void __iomem *ioaddr);
> void dwmac_dma_start_rx(void __iomem *ioaddr);
> void dwmac_dma_stop_rx(void __iomem *ioaddr);
> int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x);
> -int dwmac_dma_reset(void __iomem *ioaddr);
> +int dwmac_dma_reset(void __iomem *ioaddr, struct mac_device_info *hw,
> + phy_interface_t interface);
>
> #endif /* __DWMAC_DMA_H__ */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> index e60bfca..1a17df5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> @@ -23,7 +23,8 @@
>
> #define GMAC_HI_REG_AE 0x80000000
>
> -int dwmac_dma_reset(void __iomem *ioaddr)
> +int dwmac_dma_reset(void __iomem *ioaddr, struct mac_device_info *hw,
> + phy_interface_t interface)
> {
> u32 value = readl(ioaddr + DMA_BUS_MODE);
> int err;
> @@ -32,6 +33,9 @@ int dwmac_dma_reset(void __iomem *ioaddr)
> value |= DMA_BUS_MODE_SFT_RESET;
> writel(value, ioaddr + DMA_BUS_MODE);
>
> + if (hw->mac->set_ps)
> + hw->mac->set_ps(hw, interface);
> +
> err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
> !(value & DMA_BUS_MODE_SFT_RESET),
> 100000, 10000);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 4498a38..66bc218 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1585,7 +1585,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
> if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE))
> atds = 1;
>
> - ret = priv->hw->dma->reset(priv->ioaddr);
> + ret = priv->hw->dma->reset(priv->ioaddr, priv->hw,
> + priv->plat->interface);
> if (ret) {
> dev_err(priv->device, "Failed to reset the dma\n");
> return ret;
^ permalink raw reply
* Re: [net-next PATCH 1/4] samples/bpf: adjust rlimit RLIMIT_MEMLOCK for traceex2, tracex3 and tracex4
From: Jesper Dangaard Brouer @ 2017-05-03 8:12 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: kafai, netdev, eric, Daniel Borkmann, brouer
In-Reply-To: <20170503005314.7oovr764r3e4elzd@ast-mbp>
On Tue, 2 May 2017 17:53:16 -0700
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> On Tue, May 02, 2017 at 02:31:50PM +0200, Jesper Dangaard Brouer wrote:
> > Needed to adjust max locked memory RLIMIT_MEMLOCK for testing these bpf samples
> > as these are using more and larger maps than can fit in distro default 64Kbytes limit.
> >
> > Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> ...
> > + struct rlimit r = {1024*1024, RLIM_INFINITY};
> ...
> > + struct rlimit r = {1024*1024, RLIM_INFINITY};
>
> why magic numbers?
> All other samples do
> struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
I just wanted to provide some examples showing that it is possible to
set some reasonable limit.
The RLIM_INFINITY setting is basically just disabling the kernels
memory limit checks, and it is sort of a bad coding pattern (that
people will copy) as the two example programs does not need much.
> > + if (setrlimit(RLIMIT_MEMLOCK, &r)) {
> > + perror("setrlimit(RLIMIT_MEMLOCK)");
>
> ip_tunnel.c test does:
> perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
> Few others do:
> assert(!setrlimit(RLIMIT_MEMLOCK, &r));
> and the rest just:
> setrlimit(RLIMIT_MEMLOCK, &r);
>
> We probalby need to move this to a helper.
>
> > + struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
>
> here it's consistent :)
>
> > + if (setrlimit(RLIMIT_MEMLOCK, &r)) {
> > + perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)");
>
> but with different perror ?
> Let's do a common helper for all?
Sure, it makes sense to streamline this into a helper, just not in this
patchset ;-) Lets do that later...
And I would argue that this helper should allow users to specify some
expected/reasonable memory usage size, as the kernel side checks would
then provide some value, instead of being effectively disabled. I can
easily imagine someone increasing a _kern.c hash map max size to
100 million, without realizing that this can OOM the machine.
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH] brcmfmac: btcoex: replace init_timer with setup_timer
From: Arend van Spriel @ 2017-05-03 8:05 UTC (permalink / raw)
To: Xie Qirong, Franky Lin, Hante Meuleman, Kalle Valo
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
brcm80211-dev-list.pdl-dY08KVG/lbpWk0Htik3J/w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Piotr Haber
In-Reply-To: <20170503073555.3922-1-cheerx1994-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 5/3/2017 9:35 AM, Xie Qirong wrote:
> Signed-off-by: Xie Qirong <cheerx1994-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>
> setup_timer.cocci suggested the following improvement:
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c:383:1-11: Use
> setup_timer function for function on line 384.
Move the text above before your sign-off so it will end up in the git
commit message.
When done you may also add my acknowledgement, ie.:
Acked-by: Arend van Spriel <arend.vanspriel-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
Regards,
Arend
^ permalink raw reply
* Re: [PATCH net-next v2] net: ipv6: make sure multicast packets are not forwarded beyond the different scopes
From: Donatas Abraitis @ 2017-05-03 7:53 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stable
In-Reply-To: <20170502.145923.66844914584656456.davem@davemloft.net>
Looks like there is this test already:
if (IPV6_ADDR_MC_SCOPE(&ipv6_hdr(skb)->daddr) <=
IPV6_ADDR_SCOPE_NODELOCAL &&
!(dev->flags & IFF_LOOPBACK)) {
kfree_skb(skb);
return 0;
}
On Tue, May 2, 2017 at 9:59 PM, David Miller <davem@davemloft.net> wrote:
> From: Donatas Abraitis <donatas.abraitis@gmail.com>
> Date: Thu, 27 Apr 2017 10:12:02 +0300
>
>> RFC4291 2.7 Routers must not forward any multicast packets
>> beyond of the scope indicated by the scop field in the
>> destination multicast address.
>>
>> Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
>
> I think it's a ">=" test which is needed here, not pure equality.
> Scopes are subsets of other scopes and are therefore allowed within
> eachother.
>
> Did you actually see misbehavior due to this issue, or see a real
> bonafide conformance test fail?
>
> If you're just reading the RFC and sticking tests here and there based
> upon what you read, without any testing or real life verification of
> the issue, this is _strongly_ discouraged.
>
> It would even be ok if you merely showed how another open source
> networking stack makes this test.
--
Donatas
^ permalink raw reply
* [PATCH net] tg3: don't clear stats while tg3_close
From: YueHaibing @ 2017-05-03 7:51 UTC (permalink / raw)
To: davem, netdev; +Cc: weiyongjun1
Now tg3 NIC's stats will be cleared after ifdown/ifup. bond_get_stats traverse
its salves to get statistics,cumulative the increment.If a tg3 NIC is added to
bonding as a slave,ifdown/ifup will cause bonding's stats become tremendous value
(ex.1638.3 PiB) because of negative increment.
Fixes: 92feeabf3f67 ("tg3: Save stats across chip resets")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/broadcom/tg3.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 30d1eb9..29beba1 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -11722,10 +11722,6 @@ static int tg3_close(struct net_device *dev)
tg3_stop(tp);
- /* Clear stats across close / open calls */
- memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev));
- memset(&tp->estats_prev, 0, sizeof(tp->estats_prev));
-
if (pci_device_is_present(tp->pdev)) {
tg3_power_down_prepare(tp);
--
2.5.0
^ permalink raw reply related
* [PATCH] brcmfmac: btcoex: replace init_timer with setup_timer
From: Xie Qirong @ 2017-05-03 7:35 UTC (permalink / raw)
To: Arend van Spriel, Franky Lin, Hante Meuleman, Kalle Valo
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
brcm80211-dev-list.pdl-dY08KVG/lbpWk0Htik3J/w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Piotr Haber, Xie Qirong
Signed-off-by: Xie Qirong <cheerx1994-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
setup_timer.cocci suggested the following improvement:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c:383:1-11: Use
setup_timer function for function on line 384.
Patch was compile checked with: x86_64_defconfig + CONFIG_BRCMFMAC=y +
CONFIG_BRCMFMAC_USB=y + CONFIG_BRCMFMAC_PCIE=y + CONFIG_BRCM_TRACING=y +
CONFIG_BRCMDBG=y
Kernel version: next-20170502 (localversion-next is next-20170502)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
index 14a70d4..3559fb5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
@@ -380,9 +380,7 @@ int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg)
/* Set up timer for BT */
btci->timer_on = false;
btci->timeout = BRCMF_BTCOEX_OPPR_WIN_TIME;
- init_timer(&btci->timer);
- btci->timer.data = (ulong)btci;
- btci->timer.function = brcmf_btcoex_timerfunc;
+ setup_timer(&btci->timer, brcmf_btcoex_timerfunc, (ulong)btci);
btci->cfg = cfg;
btci->saved_regs_part1 = false;
btci->saved_regs_part2 = false;
--
2.9.3
^ permalink raw reply related
* Re: [PATCH 0/9] net: thunderx: Adds XDP support
From: Sunil Kovvuri @ 2017-05-03 7:28 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, LKML, LAKML, Sunil Goutham
In-Reply-To: <20170502.154744.1762061314370744901.davem@davemloft.net>
On Wed, May 3, 2017 at 1:17 AM, David Miller <davem@davemloft.net> wrote:
> From: sunil.kovvuri@gmail.com
> Date: Tue, 2 May 2017 18:36:49 +0530
>
>> From: Sunil Goutham <sgoutham@cavium.com>
>>
>> This patch series adds support for XDP to ThunderX NIC driver
>> which is used on CN88xx, CN81xx and CN83xx platforms.
>>
>> Patches 1-4 are performance improvement and cleanup patches
>> which are done keeping XDP performance bottlenecks in view.
>> Rest of the patches adds actual XDP support.
>
> Series applied, thanks for doing this work.
Thanks.
>
> Do you have any performance numbers?
Below are the forwarding numbers on a single core.
with network stack: 0.32 Mpps
with XDP (XDP_TX): 3 Mpps
and XDP_DROP: 3.8 Mpps
Thanks,
Sunil.
^ permalink raw reply
* Miss it//Re: [PATCH v3] iov_iter: don't revert iov buffer if csum error
From: Ding Tianhong @ 2017-05-03 7:15 UTC (permalink / raw)
To: David Miller, pabeni, edumazet, hannes, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, LinuxArm, weiyongjun (A), Al Viro
In-Reply-To: <12d4d81f-40c7-c83d-11d6-290acc084695@huawei.com>
Miss it, it is already in the kernel tree, sorry for the noisy.
On 2017/5/3 15:02, Ding Tianhong wrote:
> The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve
> ->msg_iter on error) will revert the iov buffer if copy to iter
> failed, but it didn't copy any datagram if the skb_checksum_complete
> error, so no need to revert any data at this place.
>
> v2: Sabrina notice that return -EFAULT when checksum error is not correct
> here, it would confuse the caller about the return value, so fix it.
>
> v3: According AI's suggestion, directly return -EINVAL when __skb_checksum_complete()
> return error is a more simple solution.
>
> Fixes: 327868212381 ("make skb_copy_datagram_msg() et.al. preserve->msg_iter on error")
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
> ---
> net/core/datagram.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/core/datagram.c b/net/core/datagram.c
> index 0306543..726bf8a 100644
> --- a/net/core/datagram.c
> +++ b/net/core/datagram.c
> @@ -719,7 +719,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
>
> if (msg_data_left(msg) < chunk) {
> if (__skb_checksum_complete(skb))
> - goto csum_error;
> + return -EINVAL;
> if (skb_copy_datagram_msg(skb, hlen, msg, chunk))
> goto fault;
> } else {
>
^ permalink raw reply
* Re:
From: H.A @ 2017-05-03 7:00 UTC (permalink / raw)
To: Recipients
With profound love in my heart, I Kindly Oblige your interest to very important proposal.. It is Truly Divine and require your utmost attention..........
S hlubokou láskou v mém srdci, Laskave jsem prinutit svuj zájem k návrhu .. Je velmi duležité, skutecne Divine a vyžadují vaši nejvyšší pozornost.
Kontaktujte me prímo pres: helenaroberts99@gmail.com pro úplné podrobnosti.complete.
HELINA .A ROBERTS
---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
^ permalink raw reply
* Re: [PATCH v3] iov_iter: don't revert iov buffer if csum error
From: Al Viro @ 2017-05-03 7:07 UTC (permalink / raw)
To: Ding Tianhong
Cc: David Miller, pabeni, edumazet, hannes, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, LinuxArm, weiyongjun (A)
In-Reply-To: <12d4d81f-40c7-c83d-11d6-290acc084695@huawei.com>
On Wed, May 03, 2017 at 03:02:32PM +0800, Ding Tianhong wrote:
> The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve
> ->msg_iter on error) will revert the iov buffer if copy to iter
> failed, but it didn't copy any datagram if the skb_checksum_complete
> error, so no need to revert any data at this place.
See a6a5993243550b09f620941dea741b7421fdf79c in mainline...
^ permalink raw reply
* [PATCH v3] iov_iter: don't revert iov buffer if csum error
From: Ding Tianhong @ 2017-05-03 7:02 UTC (permalink / raw)
To: David Miller, pabeni, edumazet, hannes, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, LinuxArm, weiyongjun (A), Al Viro
The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve
->msg_iter on error) will revert the iov buffer if copy to iter
failed, but it didn't copy any datagram if the skb_checksum_complete
error, so no need to revert any data at this place.
v2: Sabrina notice that return -EFAULT when checksum error is not correct
here, it would confuse the caller about the return value, so fix it.
v3: According AI's suggestion, directly return -EINVAL when __skb_checksum_complete()
return error is a more simple solution.
Fixes: 327868212381 ("make skb_copy_datagram_msg() et.al. preserve->msg_iter on error")
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
net/core/datagram.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 0306543..726bf8a 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -719,7 +719,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
if (msg_data_left(msg) < chunk) {
if (__skb_checksum_complete(skb))
- goto csum_error;
+ return -EINVAL;
if (skb_copy_datagram_msg(skb, hlen, msg, chunk))
goto fault;
} else {
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next] net/esp4: Fix invalid esph pointer crash
From: Steffen Klassert @ 2017-05-03 7:02 UTC (permalink / raw)
To: ilant; +Cc: netdev
In-Reply-To: <20170430133438.31962-1-ilant@mellanox.com>
On Sun, Apr 30, 2017 at 04:34:38PM +0300, ilant@mellanox.com wrote:
> From: Ilan Tayari <ilant@mellanox.com>
>
> Both esp_output and esp_xmit take a pointer to the ESP header
> and place it in esp_info struct prior to calling esp_output_head.
>
> Inside esp_output_head, the call to esp_output_udp_encap
> makes sure to update the pointer if it gets invalid.
> However, if esp_output_head itself calls skb_cow_data, the
> pointer is not updated and stays invalid, causing a crash
> after esp_output_head returns.
>
> Update the pointer if it becomes invalid in esp_output_head
>
> Fixes: fca11ebde3f0 ("esp4: Reorganize esp_output")
> Signed-off-by: Ilan Tayari <ilant@mellanox.com>
> ---
> net/ipv4/esp4.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> index 7f2caf71212b..65cc02bd82bc 100644
> --- a/net/ipv4/esp4.c
> +++ b/net/ipv4/esp4.c
> @@ -317,6 +317,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
> if (nfrags < 0)
> goto out;
> tail = skb_tail_pointer(trailer);
> + esp->esph = ip_esp_hdr(skb);
This is not quite right for udpencap. It fixes the crash,
but introduces a bug that we already have in v4.11.
On udpencap the esp header has an offset to skb_transport_header,
the problem was discussed last week here:
https://lkml.org/lkml/2017/4/25/937
I plan to fix this with the patch below:
Subject: [PATCH RFC] esp4: Fix udpencap for local TCP packets.
Locally generated TCP packets are usually cloned, so we
do skb_cow_data() on this packets. After that we need to
reload the pointer to the esp header. On udpencap this
header has an offset to skb_transport_header, so take this
offset into account.
Fixes: 67d349ed603 ("net/esp4: Fix invalid esph pointer crash")
Fixes: fca11ebde3f0 ("esp4: Reorganize esp_output")
Reported-by: Don Bowman <db@donbowman.ca>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv4/esp4.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 65cc02b..93322f8 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -248,6 +248,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
u8 *tail;
u8 *vaddr;
int nfrags;
+ int esph_offset;
struct page *page;
struct sk_buff *trailer;
int tailen = esp->tailen;
@@ -313,11 +314,13 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
}
cow:
+ esph_offset = (unsigned char *)esp->esph - skb_transport_header(skb);
+
nfrags = skb_cow_data(skb, tailen, &trailer);
if (nfrags < 0)
goto out;
tail = skb_tail_pointer(trailer);
- esp->esph = ip_esp_hdr(skb);
+ esp->esph = (struct ip_esp_hdr *)(skb_transport_header(skb) + esph_offset);
skip_cow:
esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto);
--
2.7.4
^ permalink raw reply related
* RE: [PATCH net v3] driver: veth: Fix one possbile memleak when fail to register_netdevice
From: Gao Feng @ 2017-05-03 6:37 UTC (permalink / raw)
To: 'Xin Long'
Cc: 'Gao Feng', 'davem', jarod,
'Stephen Hemminger', dsa, 'network dev'
In-Reply-To: <CADvbK_c32g2t-Azgf10da8qke5B+wgG4dw3jLTE2L+R2qR3xPA@mail.gmail.com>
> From: Xin Long [mailto:lucien.xin@gmail.com]
> Sent: Wednesday, May 3, 2017 1:38 PM
> On Wed, May 3, 2017 at 10:07 AM, Gao Feng <gfree.wind@foxmail.com>
> wrote:
> >> From: netdev-owner@vger.kernel.org
> >> [mailto:netdev-owner@vger.kernel.org]
> >> On Behalf Of Xin Long
> >> Sent: Wednesday, May 3, 2017 12:59 AM On Tue, May 2, 2017 at 7:03 PM,
> >> Gao Feng <gfree.wind@vip.163.com> wrote:
> >> >> From: Xin Long [mailto:lucien.xin@gmail.com]
> >> >> Sent: Tuesday, May 2, 2017 3:56 PM On Sat, Apr 29, 2017 at 11:51
> >> >> AM, <gfree.wind@foxmail.com> wrote:
> >> >> > From: Gao Feng <gfree.wind@foxmail.com>
[...]
> > The fix you mentioned change the original logic.
> > The dev->vstats is freed in advance in the ndo_uninit, not destructor.
> > It may break the backward.
> Sorry, I didn't get your "backward"
> I can't see there will be any problem caused by it.
> can you say this patch also break the 'backward' ?
> https://patchwork.ozlabs.org/patch/748964/
>
> It's really weird to do dev->reg_state check in ndo_unint ndo_unint is supposed
> to free the memory alloced in ndo_init.
>
I am not sure if it would break the backward, so I said it MAY break.
I assumed there may be someone would access the dev->vstats after ndo_uninit,
because current veth driver free the mem in the destructor.
I selected this approach because I don't want to bring new bugs during fix bug.
If you're sure it is safe to free dev->vstats in ndo_uninit, I would like to update it.
BTW there are too many drivers which have possible memleak.
You could find the list by https://www.mail-archive.com/netdev@vger.kernel.org/msg166629.html.
Some drivers allocate the resources in ndo_init, free some in ndo_uninit and free left in destructor.
I think there are some reasons.
We could not move all free in the ndo_uninit from destructor. What's your opinion?
Best Regards
Feng
^ permalink raw reply
* Re: [PATCH iproute2 net 0/8] tc/act_pedit: Support offset relative to conventional header
From: Amir Vadai @ 2017-05-03 6:27 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Or Gerlitz, Jamal Hadi Salim
In-Reply-To: <20170501092625.30274bee@xeon-e3>
On Mon, May 01, 2017 at 09:26:25AM -0700, Stephen Hemminger wrote:
> On Sun, 23 Apr 2017 15:53:48 +0300
> Amir Vadai <amir@vadai.me> wrote:
>
> > Hi Stephen,
> >
> > This patchset extends pedit to support modifying a field in an offset relative
> > to the conventional network headers (kenrel support was added [1] in 4.11 rc1).
> > Without the extended pedit, user could specify fields in TCP and ICMP headers,
> > but the kernel code was using an offset relative to the begining of the IP
> > header. This will break if IP header length is greater than the minimal value
> > of 20, or if L3 is not IPv4.
> >
> > It also introduces support in manipulating ETH, TCP, UDP and IP.ttl fields and
> > a new command to increase/decrease the value of a field (current use case is IP.ttl).
> >
> > Since there might be deployments already using pedit, special consideration was
> > taken, not to break those scripts - only by specifying the special keyword
> > 'ex', the extended capabilities are available, thus there should be no impact
> > on existing scripts.
> > Also, the new code can live together with rules added by the old code. It
> > supports both the old netlink and the new one.
> >
> > This patchset is against the master and not net-next as the functionality was
> > added in 4.11
> >
> > Thanks,
> > Amir
> >
> > [1] - 71d0ed7079df ("net/act_pedit: Support using offset relative to the
> > conventional network headers")
[...]
>
> Applied. Then I cleaned up long lines
Thanks. Will make sure to clean up long lines in future patches.
^ permalink raw reply
* Re: [net-next PATCH 0/4] Improve bpf ELF-loader under samples/bpf
From: Jesper Dangaard Brouer @ 2017-05-03 6:16 UTC (permalink / raw)
To: Daniel Borkmann
Cc: kafai, netdev, eric, Daniel Borkmann, Alexei Starovoitov, brouer
In-Reply-To: <5908F5AC.6000703@iogearbox.net>
On Tue, 02 May 2017 23:10:04 +0200
Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 05/02/2017 02:31 PM, Jesper Dangaard Brouer wrote:
> > This series improves and fixes bpf ELF loader and programs under
> > samples/bpf. The bpf_load.c created some hard to debug issues when
> > the struct (bpf_map_def) used in the ELF maps section format changed
> > in commit fb30d4b71214 ("bpf: Add tests for map-in-map").
> >
> > This was hotfixed in commit 409526bea3c3 ("samples/bpf: bpf_load.c
> > detect and abort if ELF maps section size is wrong") by detecting the
> > issue and aborting the program.
> >
> > In most situations the bpf-loader should be able to handle these kind
> > of changes to the struct size. This patch series aim to do proper
> > backward and forward compabilility handling when loading ELF files.
> >
> > This series also adjust the callback that was introduced in commit
> > 9fd63d05f3e8 ("bpf: Allow bpf sample programs (*_user.c) to change
> > bpf_map_def") to use the new bpf_map_data structure, before more users
> > start to use this callback.
> >
> > Hoping these changes can make the merge window, as above mentioned
> > commits have not been merged yet, and it would be good to avoid users
> > hitting these issues.
>
> Overall, set looks good to me. The last patch doesn't have a
> user yet, so probably better to drop it until there is an actual
> user in the tree.
The reason for simply exporting map_data[] was that in patch 3, the
data-struct (bpf_map_data) is already exposed, thus users can already
grab and store those into a separate data structure. Thus, it seemed
natural to simply export/expose the map_data[] array directly. Guess,
I could have combined patch 4 and 3. As patch-3 uses the data struct,
but in an indirect way.
To Daniel, if you still feel we should drop patch 4, then let me know.
It is only the other patches that are time critical, as patch 4 is
trivial to introduce once the first sample program uses this directly
(instead of indirectly through the callback).
> Long term, I'd like to see the samples being migrated to use the
> tools/lib/bpf/ library from the tree, so that we can avoid duplicating
> effort with having two libs in the tree (f.e. elf map validation is
> performed to a certain degree in the other one, but w/o compat
> support last time I looked).
Yes, I agree that we should migrate to use the tools/lib/bpf/ library.
But as you also say, it actually have similar compat loader issues,
although it does more validation. Once we start this migration, I'll
also fix the compat loader issues in this lib.
> Anyway, other than that:
>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Thanks
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [net-next PATCH 2/4] samples/bpf: make bpf_load.c code compatible with ELF maps section changes
From: Jesper Dangaard Brouer @ 2017-05-03 5:48 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: kafai, netdev, eric, Daniel Borkmann, brouer
In-Reply-To: <20170503005449.urnux43sril3ganq@ast-mbp>
On Tue, 2 May 2017 17:54:51 -0700
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> On Tue, May 02, 2017 at 02:31:56PM +0200, Jesper Dangaard Brouer wrote:
> > This patch does proper parsing of the ELF "maps" section, in-order to
> > be both backwards and forwards compatible with changes to the map
> > definition struct bpf_map_def, which gets compiled into the ELF file.
> >
> > The assumption is that new features with value zero, means that they
> > are not in-use. For backward compatibility where loading an ELF file
> > with a smaller struct bpf_map_def, only copy objects ELF size, leaving
> > rest of loaders struct zero. For forward compatibility where ELF file
> > have a larger struct bpf_map_def, only copy loaders own struct size
> > and verify that rest of the larger struct is zero, assuming this means
> > the newer feature was not activated, thus it should be safe for this
> > older loader to load this newer ELF file.
> >
> > Fixes: fb30d4b71214 ("bpf: Add tests for map-in-map")
> > Fixes: 409526bea3c3 ("samples/bpf: bpf_load.c detect and abort if ELF maps section size is wrong")
> > Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
>
> I would just merge patches 2 and 3 to reduce churn,
> but it looks like great improvement already.
I could have combined them, but I prefer keeping them separate to keep
the ELF changes separated from changing a sample program e.g.
map_perf_test_user.c. IHMO is is cleaner this way.
> Acked-by: Alexei Starovoitov <ast@kernel.org>
Thanks
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH net v3] driver: veth: Fix one possbile memleak when fail to register_netdevice
From: Xin Long @ 2017-05-03 5:37 UTC (permalink / raw)
To: Gao Feng; +Cc: Gao Feng, davem, jarod, Stephen Hemminger, dsa, network dev
In-Reply-To: <000c01d2c3b2$0925e880$1b71b980$@foxmail.com>
On Wed, May 3, 2017 at 10:07 AM, Gao Feng <gfree.wind@foxmail.com> wrote:
>> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>> On Behalf Of Xin Long
>> Sent: Wednesday, May 3, 2017 12:59 AM
>> On Tue, May 2, 2017 at 7:03 PM, Gao Feng <gfree.wind@vip.163.com> wrote:
>> >> From: Xin Long [mailto:lucien.xin@gmail.com]
>> >> Sent: Tuesday, May 2, 2017 3:56 PM
>> >> On Sat, Apr 29, 2017 at 11:51 AM, <gfree.wind@foxmail.com> wrote:
>> >> > From: Gao Feng <gfree.wind@foxmail.com>
>> > [...]
>> >> > -static void veth_dev_free(struct net_device *dev)
>> >> > +static void veth_destructor_free(struct net_device *dev)
>> >> > {
>> >> > free_percpu(dev->vstats);
>> >> > +}
>> >> not sure why you needed to add this function.
>> >> to use free_percpu() directly may be clearer.
>> >
>> > Because both of ndo_uninit and destructor need to perform same free
>> statements.
>> > It is good at maintain the codes with the common function.
>> >>
>> >> > +
>> >> > +static void veth_dev_uninit(struct net_device *dev) {
>> >> call free_percpu() here, no need to check dev->reg_state.
>> >> free_percpu will just return if dev->vstats is NULL.
>> >
>> > It would break the original design if don't check the reg_state.
>> > The original logic is that free the resources in the destructor, not in ndo_init.
>> I got what you're doing now, can you pls try to fix this with:
>>
>> --- a/drivers/net/veth.c
>> +++ b/drivers/net/veth.c
>> @@ -219,10 +219,9 @@ static int veth_dev_init(struct net_device *dev)
>> return 0;
>> }
>>
>> -static void veth_dev_free(struct net_device *dev)
>> +static void veth_dev_uninit(struct net_device *dev)
>> {
>> free_percpu(dev->vstats);
>> - free_netdev(dev);
>> }
>>
>> #ifdef CONFIG_NET_POLL_CONTROLLER
>> @@ -279,6 +278,7 @@ static void veth_set_rx_headroom(struct net_device
>> *dev, int new_hr)
>>
>> static const struct net_device_ops veth_netdev_ops = {
>> .ndo_init = veth_dev_init,
>> + .ndo_uninit = veth_dev_uninit,
>> .ndo_open = veth_open,
>> .ndo_stop = veth_close,
>> .ndo_start_xmit = veth_xmit,
>> @@ -317,7 +317,7 @@ static void veth_setup(struct net_device *dev)
>> NETIF_F_HW_VLAN_STAG_TX |
>> NETIF_F_HW_VLAN_CTAG_RX |
>> NETIF_F_HW_VLAN_STAG_RX);
>> - dev->destructor = veth_dev_free;
>> + dev->destructor = free_netdev;
>> dev->max_mtu = ETH_MAX_MTU;
>>
>> dev->hw_features = VETH_FEATURES;
>>
>>
>> just as what other virtual nic drivers do (vxlan, geneve, macsec, bridge ....)
>>
>
> The fix you mentioned change the original logic.
> The dev->vstats is freed in advance in the ndo_uninit, not destructor.
> It may break the backward.
Sorry, I didn't get your "backward"
I can't see there will be any problem caused by it.
can you say this patch also break the 'backward' ?
https://patchwork.ozlabs.org/patch/748964/
It's really weird to do dev->reg_state check in ndo_unint
ndo_unint is supposed to free the memory alloced in ndo_init.
>
> Regards
> Feng
>
>
^ permalink raw reply
* Re: [PATCH 1/1] IB/mlx5: Add port_xmit_wait to counter registers read
From: Leon Romanovsky @ 2017-05-03 5:38 UTC (permalink / raw)
To: Tim Wright
Cc: matanb-VPRAkNaXOzVWk0Htik3J/w, dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
saeedm-VPRAkNaXOzVWk0Htik3J/w, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170501163008.27043-1-tim-r/Uwd3QrhQcqdlJmJB21zg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 723 bytes --]
On Mon, May 01, 2017 at 05:30:08PM +0100, Tim Wright wrote:
> Add port_xmit_wait to the error counters read by mlx5_ib_process_mad to
> ensure sysfs port counter provides correct value for PortXmitWait.
> Otherwise the sysfs port_xmit_wait file always contains zero.
>
> The previous MAD_IFC implementation populated this counter, but it was
> removed during the migration to PPCNT for error counters (32-bit only).
>
> Signed-off-by: Tim Wright <tim-r/Uwd3QrhQcqdlJmJB21zg@public.gmane.org>
> ---
> drivers/infiniband/hw/mlx5/mad.c | 2 ++
> include/linux/mlx5/mlx5_ifc.h | 4 +++-
> 2 files changed, 5 insertions(+), 1 deletion(-)
>
Thanks,
Acked-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH] xdp: use common helper for netlink extended ack reporting
From: Johannes Berg @ 2017-05-03 5:32 UTC (permalink / raw)
To: Daniel Borkmann, davem; +Cc: jakub.kicinski, alexei.starovoitov, netdev
In-Reply-To: <9dc20d2c3cca095b42e730655c8fd9f5d59a4568.1493763990.git.daniel@iogearbox.net>
On Wed, 2017-05-03 at 00:39 +0200, Daniel Borkmann wrote:
> Small follow-up to d74a32acd59a ("xdp: use netlink extended ACK
> reporting")
> in order to let drivers all use the same NL_SET_ERR_MSG_MOD() helper
> macro
> for reporting. This also ensures that we consistently add the
> driver's
> prefix for dumping the report in user space to indicate that the
> error
> message is driver specific and not coming from core code.
> Furthermore,
> NL_SET_ERR_MSG_MOD() now reuses NL_SET_ERR_MSG() and thus makes all
> macros
> check the pointer as suggested.
>
> References: https://www.spinics.net/lists/netdev/msg433267.html
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
I did wonder about the whole _TRY_ thing. LGTM
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
johannes
^ permalink raw reply
* Re: [PATCH v4 net-next 00/10] net/ncsi: Add debugging functionality
From: David Miller @ 2017-05-03 5:25 UTC (permalink / raw)
To: gwshan; +Cc: netdev, joe, kubakici, f.fainelli
In-Reply-To: <1493786681-27468-1-git-send-email-gwshan@linux.vnet.ibm.com>
Sorry, the net-next tree is closed right now as we are in the merge
window.
Please resubmit this when the net-next tree opens back up.
Thank you.
^ permalink raw reply
* [PATCH v4 net-next 05/10] net/ncsi: Ethtool operation to get NCSI channel info
From: Gavin Shan @ 2017-05-03 4:44 UTC (permalink / raw)
To: netdev; +Cc: joe, kubakici, f.fainelli, davem, Gavin Shan
In-Reply-To: <1493786681-27468-1-git-send-email-gwshan@linux.vnet.ibm.com>
This adds ethtool command (ETHTOOL_GNCSICINFO) to retrieve the
NCSI channel information for the specified one. The simplified
output of this command is shown as follows from the modified
(private) ethtool:
# ethtool --ncsi eth0 info
NCSI channel 0:0 version:
version: 00000000
alpha2: 00000000
f/w name:
f/w version: 00000000
PCI IDs: 0000 0000 0000 0000
Manufacture ID: 00000000
Generic capability: 0000000f (0000000f)
Multicast capability: 00000007 (00000000)
Buffer capability: 00004000
AEN capability: 00000007 (00000000)
VLAN capability: 00000007 (00000000)
Filters: VLAN (2), Mixed (0), MC (2), UC (4)
Link status: 000ff66b 00000000 00000000
MAC filter entries:
00:00:00:00:00:00
48:c4:b6:f0:a6:d4
b6:fa:8f:70:00:00
00:00:00:01:07:34
VLAN filter entries:
0004
bc84
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
include/linux/ethtool.h | 2 +
include/uapi/linux/ethtool.h | 151 +++++++++++++++++++++++++++++++++++++++++++
net/core/ethtool.c | 22 +++++++
net/ncsi/ncsi-ethtool.c | 120 ++++++++++++++++++++++++++++++++++
4 files changed, 295 insertions(+)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 720bb4d..5704b8b 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -376,5 +376,7 @@ struct ethtool_ops {
const struct ethtool_link_ksettings *);
int (*get_ncsi_channels)(struct net_device *,
struct ethtool_ncsi_channels *);
+ int (*get_ncsi_channel_info)(struct net_device *,
+ struct ethtool_ncsi_channel_info *);
};
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index e43aacf..81fbd51 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1332,6 +1332,7 @@ struct ethtool_per_queue_op {
#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
#define ETHTOOL_GNCSICHANNELS 0x00000050 /* Get NCSI channels */
+#define ETHTOOL_GNCSICINFO 0x00000051 /* Get NCSI channel information */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -1780,4 +1781,154 @@ struct ethtool_ncsi_channels {
#define ETHTOOL_NCSI_CHANNEL_ACTIVE (1 << 8)
#define ETHTOOL_NCSI_CHANNEL_FLAGS 0x100
};
+
+/**
+ * struct ethtool_ncsi_channel_info - NCSI channel information
+ *
+ * @cmd: Command number = %ETHTOOL_GNCSICINFO
+ * @id: NCSI channel identifier
+ * @version: BCD encoded NCSI version
+ * @alpha2: BCD encoded NCSI version
+ * @fw_name: Firmware name string
+ * @fw_version: Firmware version
+ * @pci_ids: PCI identifier
+ * @mf_id: Manufacture identifier
+ * @cap_generic: Generic capability list
+ * @cap_bc: Broadcast capability list
+ * @setting_bc: Broadcast filtering setting
+ * @cap_mc: Multicast capability list
+ * @setting_mc: Multicast filtering setting
+ * @cap_buf: Length of receive buffer
+ * @cap_aen: AEN capability list
+ * @setting_aen: AEN setting
+ * @cap_vlan: VLAN filtering capability list
+ * @setting_vlan: VLAN filltering setting
+ * @cap_vlan_filter: Number of VLAN filtering entries
+ * @cap_mixed_filter: Number of mixed filtering entries
+ * @cap_mc_filter: Number of multicast filtering entries
+ * @cap_uc_filter: Number of unicast filtering entries
+ * @link_status: Link status
+ * @link_other_ind: Link other indication
+ * @link_oem: Link OEM information
+ * @mac_valid_bits: Bitmap for valid MAC filtering entries
+ * @mac: MAC filtering entries
+ * @vlan_valid_bits: Bitmap for valid VLAN filtering entries
+ * @vlan: VLAN filtering entries
+ */
+struct ethtool_ncsi_channel_info {
+ __u32 cmd;
+ __u32 id;
+ __u32 version;
+ __u32 alpha2;
+ __u8 fw_name[12];
+ __u32 fw_version;
+ __u16 pci_ids[4];
+ __u32 mf_id;
+ __u32 cap_generic;
+#define ETHTOOL_NCSI_G_HWA (1 << 0) /* HW arbitration */
+#define ETHTOOL_NCSI_G_HDS (1 << 1) /* HNC driver status change */
+#define ETHTOOL_NCSI_G_FC (1 << 2) /* HNC to MC flow control */
+#define ETHTOOL_NCSI_G_FC1 (1 << 3) /* MC to HNC flow control */
+#define ETHTOOL_NCSI_G_MC (1 << 4) /* Global MC filtering */
+#define ETHTOOL_NCSI_G_HWA_MASK 0x60
+#define ETHTOOL_NCSI_G_HWA_UNKNOWN 0x00 /* Unknown HW arbitration */
+#define ETHTOOL_NCSI_G_HWA_SUPPORT 0x20 /* Supported HW arbitration */
+#define ETHTOOL_NCSI_G_HWA_NOT_SUPPORT 0x40 /* No HW arbitration */
+#define ETHTOOL_NCSI_G_HWA_RESERVED 0x60 /* Reserved HW arbitration */
+#define ETHTOOL_NCSI_G_MASK 0x7f
+ __u32 cap_bc;
+ __u32 setting_bc;
+#define ETHTOOL_NCSI_BC_ARP (1 << 0) /* ARP packet filtering */
+#define ETHTOOL_NCSI_BC_DHCPC (1 << 1) /* DHCP client filtering */
+#define ETHTOOL_NCSI_BC_DHCPS (1 << 2) /* DHCP server filtering */
+#define ETHTOOL_NCSI_BC_NETBIOS (1 << 3) /* NetBIOS packet filtering */
+#define ETHTOOL_NCSI_BC_MASK 0xf
+ __u32 cap_mc;
+ __u32 setting_mc;
+#define ETHTOOL_NCSI_MC_IPV6_NEIGHBOR (1 << 0) /* IPv6 neighbor filter */
+#define ETHTOOL_NCSI_MC_IPV6_ROUTER (1 << 1) /* IPv6 router filter */
+#define ETHTOOL_NCSI_MC_DHCPV6_RELAY (1 << 2) /* DHCPv6 relay/server */
+#define ETHTOOL_NCSI_MC_DHCPV6_WELL_KNOWN (1 << 3) /* DHCPv6 well-known MC */
+#define ETHTOOL_NCSI_MC_IPV6_MLD (1 << 4) /* IPv6 MLD filtering */
+#define ETHTOOL_NCSI_MC_IPV6_NEIGHBOR_S (1 << 5) /* IPv6 neighbour filter */
+#define ETHTOOL_NCSI_MC_MASK 0x3f
+ __u32 cap_buf;
+ __u32 cap_aen;
+ __u32 setting_aen;
+#define ETHTOOL_NCSI_AEN_LSC (1 << 0) /* Link status change */
+#define ETHTOOL_NCSI_AEN_CR (1 << 1) /* Configuration required */
+#define ETHTOOL_NCSI_AEN_HDS (1 << 2) /* HNC driver status */
+#define ETHTOOL_NCSI_AEN_MASK 0x07
+ __u32 cap_vlan;
+ __u32 setting_vlan;
+#define ETHTOOL_NCSI_VLAN_ONLY (1 << 0) /* Filter VLAN packet only */
+#define ETHTOOL_NCSI_VLAN_NO (1 << 1) /* Filter VLAN and non-VLAN */
+#define ETHTOOL_NCSI_VLAN_ANY (1 << 2) /* Filter Any-and-non-VLAN */
+#define ETHTOOL_NCSI_VLAN_MASK 0x07
+ __u8 cap_vlan_filter;
+ __u8 cap_mixed_filter;
+ __u8 cap_mc_filter;
+ __u8 cap_uc_filter;
+ __u32 link_status;
+#define ETHTOOL_NCSI_LINK_UP (1 << 0) /* Link up or down */
+#define ETHTOOL_NCSI_LINK_SPEED_MASK 0x1e /* Link speed */
+#define ETHTOOL_NCSI_LINK_SPEED_INVALID 0x0
+#define ETHTOOL_NCSI_LINK_SPEED_10BASE_T_H 0x2
+#define ETHTOOL_NCSI_LINK_SPEED_10BASE_T_F 0x4
+#define ETHTOOL_NCSI_LINK_SPEED_100BASE_TX_H 0x6
+#define ETHTOOL_NCSI_LINK_SPEED_100BASE_T4 0x8
+#define ETHTOOL_NCSI_LINK_SPEED_100BASE_TX_F 0xa
+#define ETHTOOL_NCSI_LINK_SPEED_1000BASE_T_H 0xc
+#define ETHTOOL_NCSI_LINK_SPEED_1000BASE_T_F 0xe
+#define ETHTOOL_NCSI_LINK_SPEED_10GBASE_T 0x10
+#define ETHTOOL_NCSI_LINK_SPEED_20G 0x12
+#define ETHTOOL_NCSI_LINK_SPEED_25G 0x14
+#define ETHTOOL_NCSI_LINK_SPEED_40G 0x16
+#define ETHTOOL_NCSI_LINK_SPEED_50G 0x18
+#define ETHTOOL_NCSI_LINK_SPEED_100G 0x1a
+#define ETHTOOL_NCSI_LINK_SPEED_2_5G 0x1c
+#define ETHTOOL_NCSI_LINK_SPEED_OPTIONAL 0x1e
+#define ETHTOOL_NCSI_LINK_AUTONEG_ENABLED (1 << 5) /* Enabled auto-neg */
+#define ETHTOOL_NCSI_LINK_AUTONEG_DONE (1 << 6) /* Auto-neg is done */
+#define ETHTOOL_NCSI_LINK_PARALLEL (1 << 7) /* Parallel detection */
+#define ETHTOOL_NCSI_LINK_LPA_1000BASE_T_F (1 << 9) /* LPA: 1000BASE_T_Full */
+#define ETHTOOL_NCSI_LINK_LPA_1000BASE_T_H (1 << 10) /* LPA: 1000BASE_T_Half */
+#define ETHTOOL_NCSI_LINK_LPA_100_T4 (1 << 11) /* LPA: 100T4 */
+#define ETHTOOL_NCSI_LINK_LPA_100BASE_TX_F (1 << 12) /* LPA: 100BASE_TX_Full */
+#define ETHTOOL_NCSI_LINK_LPA_100BASE_TX_H (1 << 13) /* LPA: 100BASE_TX_Half */
+#define ETHTOOL_NCSI_LINK_LPA_10BASE_T_F (1 << 14) /* LPA: 10BASE_T_Full */
+#define ETHTOOL_NCSI_LINK_LPA_10BASE_T_H (1 << 15) /* LPA: 10BASE_T_Half */
+#define ETHTOOL_NCSI_LINK_TX_FC (1 << 16) /* Tx flow control */
+#define ETHTOOL_NCSI_LINK_RX_FC (1 << 17) /* Rx flow control */
+#define ETHTOOL_NCSI_LINK_LPA_FC_MASK 0xc0000
+#define ETHTOOL_NCSI_LINK_LPA_FC_NONE 0x0
+#define ETHTOOL_NCSI_LINK_LPA_FC_SYNC 0x40000
+#define ETHTOOL_NCSI_LINK_LPA_FC_ASYNC 0x80000
+#define ETHTOOL_NCSI_LINK_SERDES (1 << 20) /* SerDes used or not */
+#define ETHTOOL_NCSI_LINK_OEM_VALID (1 << 21)
+#define ETHTOOL_NCSI_LINK_ESPEED_MASK 0xff000000
+#define ETHTOOL_NCSI_LINK_ESPEED_INVALID 0x0
+#define ETHTOOL_NCSI_LINK_ESPEED_10BASE_T_H 0x01000000
+#define ETHTOOL_NCSI_LINK_ESPEED_10BASE_T_F 0x02000000
+#define ETHTOOL_NCSI_LINK_ESPEED_100BASE_TX_H 0x03000000
+#define ETHTOOL_NCSI_LINK_ESPEED_100BASE_T4 0x04000000
+#define ETHTOOL_NCSI_LINK_ESPEED_100BASE_TX_F 0x05000000
+#define ETHTOOL_NCSI_LINK_ESPEED_1000BASE_T_H 0x06000000
+#define ETHTOOL_NCSI_LINK_ESPEED_1000BASE_T_F 0x07000000
+#define ETHTOOL_NCSI_LINK_ESPEED_10GBASE_T 0x08000000
+#define ETHTOOL_NCSI_LINK_ESPEED_20G 0x09000000
+#define ETHTOOL_NCSI_LINK_ESPEED_25G 0x0a000000
+#define ETHTOOL_NCSI_LINK_ESPEED_40G 0x0b000000
+#define ETHTOOL_NCSI_LINK_ESPEED_50G 0x0c000000
+#define ETHTOOL_NCSI_LINK_ESPEED_100G 0x0d000000
+#define ETHTOOL_NCSI_LINK_ESPEED_2_5G 0x0e000000
+#define ETHTOOL_NCSI_LINK_ESPEED_OPTIONAL 0x0f000000
+ __u32 link_other_ind;
+#define ETHTOOL_NCSI_LINK_HNC_DRV_STATUS (1 << 0)
+ __u32 link_oem;
+ __u32 mac_valid_bits;
+ __u8 mac[8][6];
+ __u32 vlan_valid_bits;
+ __u16 vlan[16];
+};
#endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 7644765..116ef10 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -793,6 +793,25 @@ static int ethtool_get_ncsi_channels(struct net_device *dev,
return ret;
}
+static int ethtool_get_ncsi_channel_info(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_ncsi_channel_info enci;
+ int ret;
+
+ if (!dev->ethtool_ops->get_ncsi_channel_info)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&enci, useraddr, sizeof(enci)))
+ return -EFAULT;
+
+ ret = dev->ethtool_ops->get_ncsi_channel_info(dev, &enci);
+ if (!ret && copy_to_user(useraddr, &enci, sizeof(enci)))
+ return -EFAULT;
+
+ return ret;
+}
+
static void
warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
{
@@ -2833,6 +2852,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GNCSICHANNELS:
rc = ethtool_get_ncsi_channels(dev, useraddr);
break;
+ case ETHTOOL_GNCSICINFO:
+ rc = ethtool_get_ncsi_channel_info(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/ncsi/ncsi-ethtool.c b/net/ncsi/ncsi-ethtool.c
index 747aab6..9eee5fb 100644
--- a/net/ncsi/ncsi-ethtool.c
+++ b/net/ncsi/ncsi-ethtool.c
@@ -57,6 +57,124 @@ static int ncsi_get_channels(struct net_device *dev,
return 0;
}
+static int ncsi_get_channel_info(struct net_device *dev,
+ struct ethtool_ncsi_channel_info *enci)
+{
+ struct ncsi_dev *nd;
+ struct ncsi_dev_priv *ndp;
+ struct ncsi_channel *nc;
+ unsigned long flags;
+ int i;
+
+ nd = ncsi_find_dev(dev);
+ if (!nd)
+ return -ENXIO;
+
+ ndp = TO_NCSI_DEV_PRIV(nd);
+ ncsi_find_package_and_channel(ndp, enci->id, NULL, &nc);
+ if (!nc)
+ return -ENXIO;
+
+ spin_lock_irqsave(&nc->lock, flags);
+
+ /* NCSI channel's version */
+ enci->version = nc->version.version;
+ enci->alpha2 = nc->version.alpha2;
+ memcpy(enci->fw_name, nc->version.fw_name, 12);
+ enci->fw_version = nc->version.fw_version;
+ memcpy(enci->pci_ids, nc->version.pci_ids,
+ 4 * sizeof(enci->pci_ids[0]));
+ enci->mf_id = nc->version.mf_id;
+
+ /* NCSI channel's capabilities */
+ enci->cap_generic = (nc->caps[NCSI_CAP_GENERIC].cap &
+ ETHTOOL_NCSI_G_MASK);
+ enci->cap_bc = (nc->caps[NCSI_CAP_BC].cap &
+ ETHTOOL_NCSI_BC_MASK);
+ enci->cap_mc = (nc->caps[NCSI_CAP_MC].cap &
+ ETHTOOL_NCSI_MC_MASK);
+ enci->cap_buf = nc->caps[NCSI_CAP_BUFFER].cap;
+ enci->cap_aen = (nc->caps[NCSI_CAP_AEN].cap &
+ ETHTOOL_NCSI_AEN_MASK);
+ enci->cap_vlan = (nc->caps[NCSI_CAP_VLAN].cap &
+ ETHTOOL_NCSI_VLAN_MASK);
+ for (i = NCSI_FILTER_BASE; i < NCSI_FILTER_MAX; i++) {
+ struct ncsi_channel_filter *ncf;
+ unsigned char *p_cap_filter;
+ unsigned int *p_valid_bits;
+ int entry_size, s_idx, d_idx;
+ void *dest;
+
+ switch (i) {
+ case NCSI_FILTER_VLAN:
+ p_cap_filter = &enci->cap_vlan_filter;
+ entry_size = 2;
+ p_valid_bits = &enci->vlan_valid_bits;
+ dest = enci->vlan;
+ d_idx = 0;
+ break;
+ case NCSI_FILTER_UC:
+ p_cap_filter = &enci->cap_uc_filter;
+ entry_size = 6;
+ p_valid_bits = &enci->mac_valid_bits;
+ dest = enci->mac;
+ d_idx = 0;
+ break;
+ case NCSI_FILTER_MC:
+ p_cap_filter = &enci->cap_mc_filter;
+ entry_size = 6;
+ break;
+ case NCSI_FILTER_MIXED:
+ p_cap_filter = &enci->cap_mixed_filter;
+ entry_size = 6;
+ break;
+ default:
+ continue;
+ }
+
+ *p_cap_filter = 0;
+ ncf = nc->filters[i];
+ if (!ncf)
+ continue;
+
+ *p_cap_filter = ncf->total;
+ s_idx = -1;
+ while ((s_idx = find_next_bit((void *)&ncf->bitmap,
+ ncf->total, s_idx + 1))
+ < ncf->total) {
+ memcpy(dest + (d_idx * entry_size),
+ ((void *)(ncf->data)) + (s_idx * entry_size),
+ entry_size);
+ *p_valid_bits |= (1 << d_idx);
+
+ d_idx++;
+ }
+ }
+
+ /* NCSI channel's settings */
+ enci->setting_bc = nc->modes[NCSI_MODE_BC].enable ?
+ nc->modes[NCSI_MODE_BC].data[0] : 0;
+ enci->setting_bc &= ETHTOOL_NCSI_BC_MASK;
+ enci->setting_mc = nc->modes[NCSI_MODE_MC].enable ?
+ nc->modes[NCSI_MODE_MC].data[0] : 0;
+ enci->setting_mc &= ETHTOOL_NCSI_MC_MASK;
+ enci->setting_aen = nc->modes[NCSI_MODE_AEN].enable ?
+ nc->modes[NCSI_MODE_AEN].data[0] : 0;
+ enci->setting_aen &= ETHTOOL_NCSI_AEN_MASK;
+ enci->setting_vlan = nc->modes[NCSI_MODE_VLAN].enable ?
+ nc->modes[NCSI_MODE_VLAN].data[0] : 0;
+ enci->setting_vlan &= ETHTOOL_NCSI_VLAN_MASK;
+
+ /* NCSI channel's link status */
+ enci->link_status = nc->modes[NCSI_MODE_LINK].data[2];
+ enci->link_other_ind = nc->modes[NCSI_MODE_LINK].data[3];
+ enci->link_oem = nc->modes[NCSI_MODE_LINK].data[4];
+
+ spin_unlock_irqrestore(&nc->lock, flags);
+
+ return 0;
+}
+
void ncsi_ethtool_register_dev(struct net_device *dev)
{
struct ethtool_ops *ops;
@@ -66,6 +184,7 @@ void ncsi_ethtool_register_dev(struct net_device *dev)
return;
ops->get_ncsi_channels = ncsi_get_channels;
+ ops->get_ncsi_channel_info = ncsi_get_channel_info;
}
void ncsi_ethtool_unregister_dev(struct net_device *dev)
@@ -77,4 +196,5 @@ void ncsi_ethtool_unregister_dev(struct net_device *dev)
return;
ops->get_ncsi_channels = NULL;
+ ops->get_ncsi_channel_info = NULL;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 net-next 06/10] net/ncsi: Ethtool operation to get NCSI hw statistics
From: Gavin Shan @ 2017-05-03 4:44 UTC (permalink / raw)
To: netdev; +Cc: joe, kubakici, f.fainelli, davem, Gavin Shan
In-Reply-To: <1493786681-27468-1-git-send-email-gwshan@linux.vnet.ibm.com>
This adds ethtool command (ETHTOOL_GNCSISTATS) to retrieve the
NCSI hardware statistics. The simplified output of this command is
shown as follows from the modified (private) ethtool. It's obvious
the HW statistics isn't fetched from hardware yet, which is to be
sorted out later.
# ethtool --ncsi eth0 stats
NCSI statistics as below
hnc_cnt_hi: 0
hnc_cnt_lo: 0
hnc_rx_bytes: 0
hnc_tx_bytes: 0
hnc_rx_uc_pkts: 0
hnc_rx_mc_pkts: 0
hnc_rx_bc_pkts: 0
hnc_tx_uc_pkts: 0
hnc_tx_mc_pkts: 0
hnc_tx_bc_pkts: 0
hnc_fcs_err: 0
hnc_align_err: 0
hnc_false_carrier: 0
hnc_runt_pkts: 0
hnc_jabber_pkts: 0
hnc_rx_pause_xon: 0
hnc_rx_pause_xoff: 0
hnc_tx_pause_xon: 0
hnc_tx_pause_xoff: 0
hnc_tx_s_collision: 0
hnc_tx_m_collision: 0
hnc_l_collision: 0
hnc_e_collision: 0
hnc_rx_ctl_frames: 0
hnc_rx_64_frames: 0
hnc_rx_127_frames: 0
hnc_rx_255_frames: 0
hnc_rx_511_frames: 0
hnc_rx_1023_frames: 0
hnc_rx_1522_frames: 0
hnc_rx_9022_frames: 0
hnc_tx_64_frames: 0
hnc_tx_127_frames: 0
hnc_tx_255_frames: 0
hnc_tx_511_frames: 0
hnc_tx_1023_frames: 0
hnc_tx_1522_frames: 0
hnc_tx_9022_frames: 0
hnc_rx_valid_bytes: 0
hnc_rx_runt_pkts: 0
hnc_rx_jabber_pkts: 0
ncsi_rx_cmds: 0
ncsi_dropped_cmds: 0
ncsi_cmd_type_errs: 0
ncsi_cmd_csum_errs: 0
ncsi_rx_pkts: 0
ncsi_tx_pkts: 0
ncsi_tx_aen_pkts: 0
pt_tx_pkts: 0
pt_tx_dropped: 0
pt_tx_channel_err: 0
pt_tx_us_err: 0
pt_rx_pkts: 0
pt_rx_dropped: 0
pt_rx_channel_err: 0
pt_rx_us_err: 0
pt_rx_os_err: 0
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
include/linux/ethtool.h | 2 +
include/uapi/linux/ethtool.h | 124 +++++++++++++++++++++++++++++++++++++++++++
net/core/ethtool.c | 29 ++++++++++
net/ncsi/ncsi-ethtool.c | 87 ++++++++++++++++++++++++++++++
4 files changed, 242 insertions(+)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 5704b8b..6d712ca 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -378,5 +378,7 @@ struct ethtool_ops {
struct ethtool_ncsi_channels *);
int (*get_ncsi_channel_info)(struct net_device *,
struct ethtool_ncsi_channel_info *);
+ int (*get_ncsi_stats)(struct net_device *,
+ struct ethtool_ncsi_stats *);
};
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 81fbd51..472773c 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1333,6 +1333,7 @@ struct ethtool_per_queue_op {
#define ETHTOOL_GNCSICHANNELS 0x00000050 /* Get NCSI channels */
#define ETHTOOL_GNCSICINFO 0x00000051 /* Get NCSI channel information */
+#define ETHTOOL_GNCSISTATS 0x00000052 /* Get NCSI HW statistics */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -1931,4 +1932,127 @@ struct ethtool_ncsi_channel_info {
__u32 vlan_valid_bits;
__u16 vlan[16];
};
+
+/**
+ * struct ethtool_ncsi_stats - NCSI hardware statistics
+ *
+ * @cmd: Command number = %ETHTOOL_GNCSISTATS
+ * @hnc_cnt_hi: Counter cleared
+ * @hnc_cnt_lo: Counter cleared
+ * @hnc_rx_bytes: Rx bytes
+ * @hnc_tx_bytes: Tx bytes
+ * @hnc_rx_uc_pkts: Rx UC packets
+ * @hnc_rx_mc_pkts: Rx MC packets
+ * @hnc_rx_bc_pkts: Rx BC packets
+ * @hnc_tx_uc_pkts: Tx UC packets
+ * @hnc_tx_mc_pkts: Tx MC packets
+ * @hnc_tx_bc_pkts: Tx BC packets
+ * @hnc_fcs_err: FCS errors
+ * @hnc_align_err: Alignment errors
+ * @hnc_false_carrier: False carrier detection
+ * @hnc_runt_pkts: Rx runt packets
+ * @hnc_jabber_pkts: Rx jabber packets
+ * @hnc_rx_pause_xon: Rx pause XON frames
+ * @hnc_rx_pause_xoff: Rx XOFF frames
+ * @hnc_tx_pause_xon: Tx XON frames
+ * @hnc_tx_pause_xoff: Tx XOFF frames
+ * @hnc_tx_s_collision: Single collision frames
+ * @hnc_tx_m_collision: Multiple collision frames
+ * @hnc_l_collision: Late collision frames
+ * @hnc_e_collision: Excessive collision frames
+ * @hnc_rx_ctl_frames: Rx control frames
+ * @hnc_rx_64_frames: Rx 64-bytes frames
+ * @hnc_rx_127_frames: Rx 65-127 bytes frames
+ * @hnc_rx_255_frames: Rx 128-255 bytes frames
+ * @hnc_rx_511_frames: Rx 256-511 bytes frames
+ * @hnc_rx_1023_frames: Rx 512-1023 bytes frames
+ * @hnc_rx_1522_frames: Rx 1024-1522 bytes frames
+ * @hnc_rx_9022_frames: Rx 1523-9022 bytes frames
+ * @hnc_tx_64_frames: Tx 64-bytes frames
+ * @hnc_tx_127_frames: Tx 65-127 bytes frames
+ * @hnc_tx_255_frames: Tx 128-255 bytes frames
+ * @hnc_tx_511_frames: Tx 256-511 bytes frames
+ * @hnc_tx_1023_frames: Tx 512-1023 bytes frames
+ * @hnc_tx_1522_frames: Tx 1024-1522 bytes frames
+ * @hnc_tx_9022_frames: Tx 1523-9022 bytes frames
+ * @hnc_rx_valid_bytes: Rx valid bytes
+ * @hnc_rx_runt_pkts: Rx error runt packets
+ * @hnc_rx_jabber_pkts: Rx error jabber packets
+ * @ncsi_rx_cmds: Rx NCSI commands
+ * @ncsi_dropped_cmds: Dropped commands
+ * @ncsi_cmd_type_errs: Command type errors
+ * @ncsi_cmd_csum_errs: Command checksum errors
+ * @ncsi_rx_pkts: Rx NCSI packets
+ * @ncsi_tx_pkts: Tx NCSI packets
+ * @ncsi_tx_aen_pkts: Tx AEN packets
+ * @pt_tx_pkts: Tx packets
+ * @pt_tx_dropped: Tx dropped packets
+ * @pt_tx_channel_err: Tx channel errors
+ * @pt_tx_us_err: Tx undersize errors
+ * @pt_rx_pkts: Rx packets
+ * @pt_rx_dropped: Rx dropped packets
+ * @pt_rx_channel_err: Rx channel errors
+ * @pt_rx_us_err: Rx undersize errors
+ * @pt_rx_os_err: Rx oversize errors
+ */
+struct ethtool_ncsi_stats {
+ __u32 cmd;
+ __u64 hnc_cnt_hi;
+ __u64 hnc_cnt_lo;
+ __u64 hnc_rx_bytes;
+ __u64 hnc_tx_bytes;
+ __u64 hnc_rx_uc_pkts;
+ __u64 hnc_rx_mc_pkts;
+ __u64 hnc_rx_bc_pkts;
+ __u64 hnc_tx_uc_pkts;
+ __u64 hnc_tx_mc_pkts;
+ __u64 hnc_tx_bc_pkts;
+ __u64 hnc_fcs_err;
+ __u64 hnc_align_err;
+ __u64 hnc_false_carrier;
+ __u64 hnc_runt_pkts;
+ __u64 hnc_jabber_pkts;
+ __u64 hnc_rx_pause_xon;
+ __u64 hnc_rx_pause_xoff;
+ __u64 hnc_tx_pause_xon;
+ __u64 hnc_tx_pause_xoff;
+ __u64 hnc_tx_s_collision;
+ __u64 hnc_tx_m_collision;
+ __u64 hnc_l_collision;
+ __u64 hnc_e_collision;
+ __u64 hnc_rx_ctl_frames;
+ __u64 hnc_rx_64_frames;
+ __u64 hnc_rx_127_frames;
+ __u64 hnc_rx_255_frames;
+ __u64 hnc_rx_511_frames;
+ __u64 hnc_rx_1023_frames;
+ __u64 hnc_rx_1522_frames;
+ __u64 hnc_rx_9022_frames;
+ __u64 hnc_tx_64_frames;
+ __u64 hnc_tx_127_frames;
+ __u64 hnc_tx_255_frames;
+ __u64 hnc_tx_511_frames;
+ __u64 hnc_tx_1023_frames;
+ __u64 hnc_tx_1522_frames;
+ __u64 hnc_tx_9022_frames;
+ __u64 hnc_rx_valid_bytes;
+ __u64 hnc_rx_runt_pkts;
+ __u64 hnc_rx_jabber_pkts;
+ __u64 ncsi_rx_cmds;
+ __u64 ncsi_dropped_cmds;
+ __u64 ncsi_cmd_type_errs;
+ __u64 ncsi_cmd_csum_errs;
+ __u64 ncsi_rx_pkts;
+ __u64 ncsi_tx_pkts;
+ __u64 ncsi_tx_aen_pkts;
+ __u64 pt_tx_pkts;
+ __u64 pt_tx_dropped;
+ __u64 pt_tx_channel_err;
+ __u64 pt_tx_us_err;
+ __u64 pt_rx_pkts;
+ __u64 pt_rx_dropped;
+ __u64 pt_rx_channel_err;
+ __u64 pt_rx_us_err;
+ __u64 pt_rx_os_err;
+};
#endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 116ef10..f26aa36 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -812,6 +812,32 @@ static int ethtool_get_ncsi_channel_info(struct net_device *dev,
return ret;
}
+static int ethtool_get_ncsi_stats(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_ncsi_stats *ens;
+ int ret;
+
+ if (!dev->ethtool_ops->get_ncsi_stats)
+ return -EOPNOTSUPP;
+
+ ens = kzalloc(sizeof(*ens), GFP_KERNEL);
+ if (!ens)
+ return -ENOMEM;
+
+ if (copy_from_user(ens, useraddr, sizeof(*ens))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = dev->ethtool_ops->get_ncsi_stats(dev, ens);
+ if (!ret && copy_to_user(useraddr, ens, sizeof(*ens)))
+ ret = -EFAULT;
+out:
+ kfree(ens);
+ return ret;
+}
+
static void
warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
{
@@ -2855,6 +2881,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GNCSICINFO:
rc = ethtool_get_ncsi_channel_info(dev, useraddr);
break;
+ case ETHTOOL_GNCSISTATS:
+ rc = ethtool_get_ncsi_stats(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/ncsi/ncsi-ethtool.c b/net/ncsi/ncsi-ethtool.c
index 9eee5fb..1ccdb50 100644
--- a/net/ncsi/ncsi-ethtool.c
+++ b/net/ncsi/ncsi-ethtool.c
@@ -175,6 +175,91 @@ static int ncsi_get_channel_info(struct net_device *dev,
return 0;
}
+static int ncsi_get_stats(struct net_device *dev,
+ struct ethtool_ncsi_stats *ens)
+{
+ struct ncsi_dev *nd;
+ struct ncsi_dev_priv *ndp;
+ struct ncsi_package *np;
+ struct ncsi_channel *nc;
+ struct ncsi_channel_stats *ncs;
+ unsigned long flags;
+
+ nd = ncsi_find_dev(dev);
+ if (!nd)
+ return -ENXIO;
+
+ ndp = TO_NCSI_DEV_PRIV(nd);
+ NCSI_FOR_EACH_PACKAGE(ndp, np) {
+ NCSI_FOR_EACH_CHANNEL(np, nc) {
+ spin_lock_irqsave(&nc->lock, flags);
+
+ ncs = &nc->stats;
+ ens->hnc_cnt_hi += ncs->hnc_cnt_hi;
+ ens->hnc_cnt_lo += ncs->hnc_cnt_lo;
+ ens->hnc_rx_bytes += ncs->hnc_rx_bytes;
+ ens->hnc_tx_bytes += ncs->hnc_tx_bytes;
+ ens->hnc_rx_uc_pkts += ncs->hnc_rx_uc_pkts;
+ ens->hnc_rx_mc_pkts += ncs->hnc_rx_mc_pkts;
+ ens->hnc_rx_bc_pkts += ncs->hnc_rx_bc_pkts;
+ ens->hnc_tx_uc_pkts += ncs->hnc_tx_uc_pkts;
+ ens->hnc_tx_mc_pkts += ncs->hnc_tx_mc_pkts;
+ ens->hnc_tx_bc_pkts += ncs->hnc_tx_bc_pkts;
+ ens->hnc_fcs_err += ncs->hnc_fcs_err;
+ ens->hnc_align_err += ncs->hnc_align_err;
+ ens->hnc_false_carrier += ncs->hnc_false_carrier;
+ ens->hnc_runt_pkts += ncs->hnc_runt_pkts;
+ ens->hnc_jabber_pkts += ncs->hnc_jabber_pkts;
+ ens->hnc_rx_pause_xon += ncs->hnc_rx_pause_xon;
+ ens->hnc_rx_pause_xoff += ncs->hnc_rx_pause_xoff;
+ ens->hnc_tx_pause_xon += ncs->hnc_tx_pause_xon;
+ ens->hnc_tx_pause_xoff += ncs->hnc_tx_pause_xoff;
+ ens->hnc_tx_s_collision += ncs->hnc_tx_s_collision;
+ ens->hnc_tx_m_collision += ncs->hnc_tx_m_collision;
+ ens->hnc_l_collision += ncs->hnc_l_collision;
+ ens->hnc_e_collision += ncs->hnc_e_collision;
+ ens->hnc_rx_ctl_frames += ncs->hnc_rx_ctl_frames;
+ ens->hnc_rx_64_frames += ncs->hnc_rx_64_frames;
+ ens->hnc_rx_127_frames += ncs->hnc_rx_127_frames;
+ ens->hnc_rx_255_frames += ncs->hnc_rx_255_frames;
+ ens->hnc_rx_511_frames += ncs->hnc_rx_511_frames;
+ ens->hnc_rx_1023_frames += ncs->hnc_rx_1023_frames;
+ ens->hnc_rx_1522_frames += ncs->hnc_rx_1522_frames;
+ ens->hnc_rx_9022_frames += ncs->hnc_rx_9022_frames;
+ ens->hnc_tx_64_frames += ncs->hnc_tx_64_frames;
+ ens->hnc_tx_127_frames += ncs->hnc_tx_127_frames;
+ ens->hnc_tx_255_frames += ncs->hnc_tx_255_frames;
+ ens->hnc_tx_511_frames += ncs->hnc_tx_511_frames;
+ ens->hnc_tx_1023_frames += ncs->hnc_tx_1023_frames;
+ ens->hnc_tx_1522_frames += ncs->hnc_tx_1522_frames;
+ ens->hnc_tx_9022_frames += ncs->hnc_tx_9022_frames;
+ ens->hnc_rx_valid_bytes += ncs->hnc_rx_valid_bytes;
+ ens->hnc_rx_runt_pkts += ncs->hnc_rx_runt_pkts;
+ ens->hnc_rx_jabber_pkts += ncs->hnc_rx_jabber_pkts;
+ ens->ncsi_rx_cmds += ncs->ncsi_rx_cmds;
+ ens->ncsi_dropped_cmds += ncs->ncsi_dropped_cmds;
+ ens->ncsi_cmd_type_errs += ncs->ncsi_cmd_type_errs;
+ ens->ncsi_cmd_csum_errs += ncs->ncsi_cmd_csum_errs;
+ ens->ncsi_rx_pkts += ncs->ncsi_rx_pkts;
+ ens->ncsi_tx_pkts += ncs->ncsi_tx_pkts;
+ ens->ncsi_tx_aen_pkts += ncs->ncsi_tx_aen_pkts;
+ ens->pt_tx_pkts += ncs->pt_tx_pkts;
+ ens->pt_tx_dropped += ncs->pt_tx_dropped;
+ ens->pt_tx_channel_err += ncs->pt_tx_channel_err;
+ ens->pt_tx_us_err += ncs->pt_tx_us_err;
+ ens->pt_rx_pkts += ncs->pt_rx_pkts;
+ ens->pt_rx_dropped += ncs->pt_rx_dropped;
+ ens->pt_rx_channel_err += ncs->pt_rx_channel_err;
+ ens->pt_rx_us_err += ncs->pt_rx_us_err;
+ ens->pt_rx_os_err += ncs->pt_rx_os_err;
+
+ spin_unlock_irqrestore(&nc->lock, flags);
+ }
+ }
+
+ return 0;
+}
+
void ncsi_ethtool_register_dev(struct net_device *dev)
{
struct ethtool_ops *ops;
@@ -185,6 +270,7 @@ void ncsi_ethtool_register_dev(struct net_device *dev)
ops->get_ncsi_channels = ncsi_get_channels;
ops->get_ncsi_channel_info = ncsi_get_channel_info;
+ ops->get_ncsi_stats = ncsi_get_stats;
}
void ncsi_ethtool_unregister_dev(struct net_device *dev)
@@ -197,4 +283,5 @@ void ncsi_ethtool_unregister_dev(struct net_device *dev)
ops->get_ncsi_channels = NULL;
ops->get_ncsi_channel_info = NULL;
+ ops->get_ncsi_stats = NULL;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 net-next 07/10] net/ncsi: Ethtool operation to get NCSI sw statistics
From: Gavin Shan @ 2017-05-03 4:44 UTC (permalink / raw)
To: netdev; +Cc: joe, kubakici, f.fainelli, davem, Gavin Shan
In-Reply-To: <1493786681-27468-1-git-send-email-gwshan@linux.vnet.ibm.com>
This adds ethtool command (ETHTOOL_GNCSISWSTATS) to retrieve the
NCSI software statistics. The simplified output of this command is
shown as follows from the modified (private) ethtool.
COMMAND OK TIMEOUT ERROR
====================================
CIS 32 29 0
SP 10 7 0
DP 17 14 0
EC 1 0 0
ECNT 1 0 0
AE 1 0 0
GLS 10 0 0
SMA 1 0 0
DBF 1 0 0
GC 2 0 0
GP 2 0 0
RESPONSE OK TIMEOUT ERROR
====================================
CIS 3 0 0
SP 3 0 0
DP 2 0 1
EC 1 0 0
ECNT 1 0 0
AE 1 0 0
GLS 10 0 0
SMA 1 0 0
DBF 1 0 0
GC 0 0 2
GP 2 0 0
AEN OK TIMEOUT ERROR
====================================
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
include/linux/ethtool.h | 2 ++
include/uapi/linux/ethtool.h | 20 ++++++++++++++++++++
net/core/ethtool.c | 29 ++++++++++++++++++++++++++++
net/ncsi/Kconfig | 9 +++++++++
net/ncsi/Makefile | 1 +
net/ncsi/internal.h | 13 +++++++++++++
net/ncsi/ncsi-aen.c | 14 +++++++++++++-
net/ncsi/ncsi-cmd.c | 12 +++++++++++-
net/ncsi/ncsi-debug.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
net/ncsi/ncsi-ethtool.c | 34 +++++++++++++++++++++++++++++++++
net/ncsi/ncsi-manage.c | 4 ++++
net/ncsi/ncsi-rsp.c | 19 ++++++++++++++++++-
12 files changed, 199 insertions(+), 3 deletions(-)
create mode 100644 net/ncsi/ncsi-debug.c
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 6d712ca..eb57142 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -380,5 +380,7 @@ struct ethtool_ops {
struct ethtool_ncsi_channel_info *);
int (*get_ncsi_stats)(struct net_device *,
struct ethtool_ncsi_stats *);
+ int (*get_ncsi_sw_stats)(struct net_device *,
+ struct ethtool_ncsi_sw_stats *);
};
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 472773c..bf6fa2b 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1334,6 +1334,7 @@ struct ethtool_per_queue_op {
#define ETHTOOL_GNCSICHANNELS 0x00000050 /* Get NCSI channels */
#define ETHTOOL_GNCSICINFO 0x00000051 /* Get NCSI channel information */
#define ETHTOOL_GNCSISTATS 0x00000052 /* Get NCSI HW statistics */
+#define ETHTOOL_GNCSISWSTATS 0x00000053 /* Get NCSI software statistics */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -2055,4 +2056,23 @@ struct ethtool_ncsi_stats {
__u64 pt_rx_us_err;
__u64 pt_rx_os_err;
};
+
+/**
+ * struct ethtool_ncsi_sw_stats - NCSI software statistics
+ *
+ * @cmd: Command number = %ETHTOOL_GNCSISWSTATS
+ * @command: Statistics for sent command packets
+ * @response: Statistics for received response packets
+ * @aen: Statistics for received AEN packets
+ */
+struct ethtool_ncsi_sw_stats {
+ __u32 cmd;
+#define ETHTOOL_NCSI_SW_STAT_OK 0
+#define ETHTOOL_NCSI_SW_STAT_TIMEOUT 1
+#define ETHTOOL_NCSI_SW_STAT_ERROR 2
+#define ETHTOOL_NCSI_SW_STAT_MAX 3
+ __u64 command[128][ETHTOOL_NCSI_SW_STAT_MAX];
+ __u64 response[128][ETHTOOL_NCSI_SW_STAT_MAX];
+ __u64 aen[256][ETHTOOL_NCSI_SW_STAT_MAX];
+};
#endif /* _UAPI_LINUX_ETHTOOL_H */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index f26aa36..998d29b 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -838,6 +838,32 @@ static int ethtool_get_ncsi_stats(struct net_device *dev,
return ret;
}
+static int ethtool_get_ncsi_sw_stats(struct net_device *dev,
+ void __user *useraddr)
+{
+ struct ethtool_ncsi_sw_stats *enss;
+ int ret;
+
+ if (!dev->ethtool_ops->get_ncsi_sw_stats)
+ return -EOPNOTSUPP;
+
+ enss = kzalloc(sizeof(*enss), GFP_KERNEL);
+ if (!enss)
+ return -ENOMEM;
+
+ if (copy_from_user(&enss->cmd, useraddr, sizeof(enss->cmd))) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = dev->ethtool_ops->get_ncsi_sw_stats(dev, enss);
+ if (!ret && copy_to_user(useraddr, enss, sizeof(*enss)))
+ ret = -EFAULT;
+out:
+ kfree(enss);
+ return ret;
+}
+
static void
warn_incomplete_ethtool_legacy_settings_conversion(const char *details)
{
@@ -2884,6 +2910,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GNCSISTATS:
rc = ethtool_get_ncsi_stats(dev, useraddr);
break;
+ case ETHTOOL_GNCSISWSTATS:
+ rc = ethtool_get_ncsi_sw_stats(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig
index 08a8a60..9e59145 100644
--- a/net/ncsi/Kconfig
+++ b/net/ncsi/Kconfig
@@ -10,3 +10,12 @@ config NET_NCSI
support. Enable this only if your system connects to a network
device via NCSI and the ethernet driver you're using supports
the protocol explicitly.
+
+config NET_NCSI_DEBUG
+ bool "Enable NCSI debugging"
+ depends on NET_NCSI && DEBUG_FS
+ default n
+ ---help---
+ This enables the interfaces (e.g. debugfs) for NCSI debugging purpose.
+
+ If unsure, say N.
diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile
index 71a258a..4e0c5d2 100644
--- a/net/ncsi/Makefile
+++ b/net/ncsi/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-rsp.o ncsi-aen.o ncsi-manage.o \
ncsi-ethtool.o
+obj-$(CONFIG_NET_NCSI_DEBUG) += ncsi-debug.o
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index 09a7ba7..5a6cd74 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -275,6 +275,9 @@ struct ncsi_dev_priv {
struct list_head channel_queue; /* Config queue of channels */
struct work_struct work; /* For channel management */
struct packet_type ptype; /* NCSI packet Rx handler */
+#ifdef CONFIG_NET_NCSI_DEBUG
+ struct ethtool_ncsi_sw_stats stats; /* NCSI software statistics */
+#endif /* CONFIG_NET_NCSI_DEBUG */
struct list_head node; /* Form NCSI device list */
};
@@ -341,4 +344,14 @@ int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb);
void ncsi_ethtool_register_dev(struct net_device *dev);
void ncsi_ethtool_unregister_dev(struct net_device *dev);
+/* Debugging functionality */
+#ifdef CONFIG_NET_NCSI_DEBUG
+void ncsi_dev_update_stats(struct ncsi_dev_priv *ndp,
+ int type, int subtype, int errno);
+#else
+static inline void ncsi_dev_update_stats(struct ncsi_dev_priv *ndp,
+ int type, int subtype, int errno)
+{
+}
+#endif /* CONFIG_NET_NCSI_DEBUG */
#endif /* __NCSI_INTERNAL_H__ */
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
index 6898e72..7a3d181 100644
--- a/net/ncsi/ncsi-aen.c
+++ b/net/ncsi/ncsi-aen.c
@@ -206,16 +206,28 @@ int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb)
}
if (!nah) {
+ ncsi_dev_update_stats(ndp, NCSI_PKT_AEN, h->type,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
netdev_warn(ndp->ndev.dev, "Invalid AEN (0x%x) received\n",
h->type);
return -ENOENT;
}
ret = ncsi_validate_aen_pkt(h, nah->payload);
- if (ret)
+ if (ret) {
+ ncsi_dev_update_stats(ndp, NCSI_PKT_AEN, h->type,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
goto out;
+ }
ret = nah->handler(ndp, h);
+ if (!ret) {
+ ncsi_dev_update_stats(ndp, NCSI_PKT_AEN, h->type,
+ ETHTOOL_NCSI_SW_STAT_OK);
+ } else {
+ ncsi_dev_update_stats(ndp, NCSI_PKT_AEN, h->type,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
+ }
out:
consume_skb(skb);
return ret;
diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c
index db7083b..875ff07 100644
--- a/net/ncsi/ncsi-cmd.c
+++ b/net/ncsi/ncsi-cmd.c
@@ -323,6 +323,8 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
}
if (!nch) {
+ ncsi_dev_update_stats(nca->ndp, nca->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
netdev_err(nca->ndp->ndev.dev,
"Cannot send packet with type 0x%02x\n", nca->type);
return -ENOENT;
@@ -331,13 +333,18 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
/* Get packet payload length and allocate the request */
nca->payload = nch->payload;
nr = ncsi_alloc_command(nca);
- if (!nr)
+ if (!nr) {
+ ncsi_dev_update_stats(nca->ndp, nca->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
return -ENOMEM;
+ }
/* Prepare the packet */
nca->id = nr->id;
ret = nch->handler(nr->cmd, nca);
if (ret) {
+ ncsi_dev_update_stats(nca->ndp, nca->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
ncsi_free_request(nr);
return ret;
}
@@ -359,9 +366,12 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
skb_get(nr->cmd);
ret = dev_queue_xmit(nr->cmd);
if (ret < 0) {
+ ncsi_dev_update_stats(nca->ndp, nca->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
ncsi_free_request(nr);
return ret;
}
+ ncsi_dev_update_stats(nca->ndp, nca->type, 0, ETHTOOL_NCSI_SW_STAT_OK);
return 0;
}
diff --git a/net/ncsi/ncsi-debug.c b/net/ncsi/ncsi-debug.c
new file mode 100644
index 0000000..0e6c038
--- /dev/null
+++ b/net/ncsi/ncsi-debug.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright Gavin Shan, IBM Corporation 2017.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <linux/debugfs.h>
+#include <linux/skbuff.h>
+
+#include <net/ncsi.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include "internal.h"
+#include "ncsi-pkt.h"
+
+void ncsi_dev_update_stats(struct ncsi_dev_priv *ndp,
+ int type, int subtype, int errno)
+{
+ unsigned long flags;
+
+ if (errno >= ETHTOOL_NCSI_SW_STAT_MAX)
+ return;
+
+ spin_lock_irqsave(&ndp->lock, flags);
+
+ if (type == NCSI_PKT_AEN) {
+ if (subtype < 256)
+ ndp->stats.aen[subtype][errno]++;
+ } else if (type < 128) {
+ ndp->stats.command[type][errno]++;
+ } else if (type < 256) {
+ ndp->stats.response[type - 128][errno]++;
+ }
+
+ spin_unlock_irqrestore(&ndp->lock, flags);
+}
diff --git a/net/ncsi/ncsi-ethtool.c b/net/ncsi/ncsi-ethtool.c
index 1ccdb50..82642ae 100644
--- a/net/ncsi/ncsi-ethtool.c
+++ b/net/ncsi/ncsi-ethtool.c
@@ -260,6 +260,38 @@ static int ncsi_get_stats(struct net_device *dev,
return 0;
}
+#ifdef CONFIG_NET_NCSI_DEBUG
+static int ncsi_get_sw_stats(struct net_device *dev,
+ struct ethtool_ncsi_sw_stats *enss)
+{
+ struct ncsi_dev *nd;
+ struct ncsi_dev_priv *ndp;
+ unsigned long flags;
+
+ nd = ncsi_find_dev(dev);
+ if (!nd)
+ return -ENXIO;
+
+ ndp = TO_NCSI_DEV_PRIV(nd);
+ spin_lock_irqsave(&ndp->lock, flags);
+ memcpy(enss->command, ndp->stats.command,
+ 128 * ETHTOOL_NCSI_SW_STAT_MAX * sizeof(enss->command[0][0]));
+ memcpy(enss->response, ndp->stats.response,
+ 128 * ETHTOOL_NCSI_SW_STAT_MAX * sizeof(enss->response[0][0]));
+ memcpy(enss->aen, ndp->stats.aen,
+ 256 * ETHTOOL_NCSI_SW_STAT_MAX * sizeof(enss->aen[0][0]));
+ spin_unlock_irqrestore(&ndp->lock, flags);
+
+ return 0;
+}
+#else
+static int ncsi_get_sw_stats(struct net_device *dev,
+ struct ethtool_ncsi_sw_stats *enss)
+{
+ return -EOPNOTSUPP;
+}
+#endif /* CONFIG_NET_NCSI_DEBUG */
+
void ncsi_ethtool_register_dev(struct net_device *dev)
{
struct ethtool_ops *ops;
@@ -271,6 +303,7 @@ void ncsi_ethtool_register_dev(struct net_device *dev)
ops->get_ncsi_channels = ncsi_get_channels;
ops->get_ncsi_channel_info = ncsi_get_channel_info;
ops->get_ncsi_stats = ncsi_get_stats;
+ ops->get_ncsi_sw_stats = ncsi_get_sw_stats;
}
void ncsi_ethtool_unregister_dev(struct net_device *dev)
@@ -284,4 +317,5 @@ void ncsi_ethtool_unregister_dev(struct net_device *dev)
ops->get_ncsi_channels = NULL;
ops->get_ncsi_channel_info = NULL;
ops->get_ncsi_stats = NULL;
+ ops->get_ncsi_sw_stats = NULL;
}
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index f1c10f0..8365a5b 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -521,6 +521,7 @@ static void ncsi_request_timeout(unsigned long data)
{
struct ncsi_request *nr = (struct ncsi_request *)data;
struct ncsi_dev_priv *ndp = nr->ndp;
+ struct ncsi_pkt_hdr *hdr;
unsigned long flags;
/* If the request already had associated response,
@@ -534,6 +535,9 @@ static void ncsi_request_timeout(unsigned long data)
}
spin_unlock_irqrestore(&ndp->lock, flags);
+ hdr = (struct ncsi_pkt_hdr *)skb_network_header(nr->cmd);
+ ncsi_dev_update_stats(ndp, hdr->type, 0, ETHTOOL_NCSI_SW_STAT_TIMEOUT);
+
/* Release the request */
ncsi_free_request(nr);
}
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index 087db77..d362d2c 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -998,6 +998,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
}
if (!nrh) {
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
hdr->type);
return -ENOENT;
@@ -1008,12 +1010,16 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
nr = &ndp->requests[hdr->id];
if (!nr->used) {
spin_unlock_irqrestore(&ndp->lock, flags);
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_TIMEOUT);
return -ENODEV;
}
nr->rsp = skb;
if (!nr->enabled) {
spin_unlock_irqrestore(&ndp->lock, flags);
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_TIMEOUT);
ret = -ENOENT;
goto out;
}
@@ -1024,11 +1030,22 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
if (payload < 0)
payload = ntohs(hdr->length);
ret = ncsi_validate_rsp_pkt(nr, payload);
- if (ret)
+ if (ret) {
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
goto out;
+ }
/* Process the packet */
ret = nrh->handler(nr);
+ if (!ret) {
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_OK);
+ } else {
+ ncsi_dev_update_stats(ndp, hdr->type, 0,
+ ETHTOOL_NCSI_SW_STAT_ERROR);
+ }
+
out:
ncsi_free_request(nr);
return ret;
--
2.7.4
^ permalink raw reply related
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