* Re: [PATCH net] tcp/dccp: fix lockdep issue when SYN is backlogged
From: Eric Dumazet @ 2018-10-02 18:25 UTC (permalink / raw)
To: David Miller, edumazet; +Cc: netdev, eric.dumazet
In-Reply-To: <20181001.154308.1092275550794942572.davem@davemloft.net>
On 10/01/2018 03:43 PM, David Miller wrote:
> From: Eric Dumazet <edumazet@google.com>
> Date: Mon, 1 Oct 2018 15:02:26 -0700
>> This patch extends what I did in commit 449809a66c1d ("tcp/dccp:
>> block BH for SYN processing") by adding an extra rcu_read_{lock|unlock}
>> pair in the paths that might be taken when processing SYN from
>> socket backlog (thus possibly in process context)
>>
>> Fixes: 06f877d613be ("tcp/dccp: fix other lockdep splats accessing ireq_opt")
>> Signed-off-by: Eric Dumazet <edumazet@google.com>
>> Reported-by: syzbot <syzkaller@googlegroups.com>
>
> Applied and queued up for -stable, thanks Eric.
>
This needs a followup, timers do not imply rcu_read_lock() :/
I will send a patch, sorry for not having caught this earlier.
^ permalink raw reply
* Re: [PATCH v2 0/5] Introducing ixgbe AF_XDP ZC support
From: William Tu @ 2018-10-02 18:23 UTC (permalink / raw)
To: Björn Töpel
Cc: jeffrey.t.kirsher, intel-wired-lan, Björn Töpel,
Karlsson, Magnus, Magnus Karlsson, Alexei Starovoitov,
Daniel Borkmann, Linux Kernel Network Developers,
Jesper Dangaard Brouer, Test, Jakub Kicinski
In-Reply-To: <20181002080034.11754-1-bjorn.topel@gmail.com>
On Tue, Oct 2, 2018 at 1:01 AM Björn Töpel <bjorn.topel@gmail.com> wrote:
>
> From: Björn Töpel <bjorn.topel@intel.com>
>
> Jeff: Please remove the v1 patches from your dev-queue!
>
> This patch set introduces zero-copy AF_XDP support for Intel's ixgbe
> driver.
>
> The ixgbe zero-copy code is located in its own file ixgbe_xsk.[ch],
> analogous to the i40e ZC support. Again, as in i40e, code paths have
> been copied from the XDP path to the zero-copy path. Going forward we
> will try to generalize more code between the AF_XDP ZC drivers, and
> also reduce the heavy C&P.
>
> We have run some benchmarks on a dual socket system with two Broadwell
> E5 2660 @ 2.0 GHz with hyperthreading turned off. Each socket has 14
> cores which gives a total of 28, but only two cores are used in these
> experiments. One for TR/RX and one for the user space application. The
> memory is DDR4 @ 2133 MT/s (1067 MHz) and the size of each DIMM is
> 8192MB and with 8 of those DIMMs in the system we have 64 GB of total
> memory. The compiler used is GCC 7.3.0. The NIC is Intel
> 82599ES/X520-2 10Gbit/s using the ixgbe driver.
>
> Below are the results in Mpps of the 82599ES/X520-2 NIC benchmark runs
> for 64B and 1500B packets, generated by a commercial packet generator
> HW blasting packets at full 10Gbit/s line rate. The results are with
> retpoline and all other spectre and meltdown fixes.
>
> AF_XDP performance 64B packets:
> Benchmark XDP_DRV with zerocopy
> rxdrop 14.7
> txpush 14.6
> l2fwd 11.1
>
> AF_XDP performance 1500B packets:
> Benchmark XDP_DRV with zerocopy
> rxdrop 0.8
> l2fwd 0.8
>
> XDP performance on our system as a base line.
>
> 64B packets:
> XDP stats CPU Mpps issue-pps
> XDP-RX CPU 16 14.7 0
>
> 1500B packets:
> XDP stats CPU Mpps issue-pps
> XDP-RX CPU 16 0.8 0
>
> The structure of the patch set is as follows:
>
> Patch 1: Introduce Rx/Tx ring enable/disable functionality
> Patch 2: Preparatory patche to ixgbe driver code for RX
> Patch 3: ixgbe zero-copy support for RX
> Patch 4: Preparatory patch to ixgbe driver code for TX
> Patch 5: ixgbe zero-copy support for TX
>
> Changes since v1:
>
> * Removed redundant AF_XDP precondition checks, pointed out by
> Jakub. Now, the preconditions are only checked at XDP enable time.
> * Fixed a crash in the egress path, due to incorrect usage of
> ixgbe_ring queue_index member. In v2 a ring_idx back reference is
> introduced, and used in favor of queue_index. William reported the
> crash, and helped me smoke out the issue. Kudos!
Thanks! I tested this series and no more crash.
The number is pretty good (*without* spectre and meltdown fixes)
model name : Intel(R) Xeon(R) CPU E5-2440 v2 @ 1.90GHz, total 16 cores/
AF_XDP performance 64B packets:
Benchmark XDP_DRV with zerocopy
rxdrop 20
txpush 18
l2fwd 20
Regards,
William
^ permalink raw reply
* Re: [PATCH net-next] net: drop unused skb_append_datato_frags()
From: David Miller @ 2018-10-02 18:21 UTC (permalink / raw)
To: pabeni; +Cc: netdev
In-Reply-To: <3a79b8d8f1a0fbaa84967ae7e8c34ffd07104a90.1538470695.git.pabeni@redhat.com>
From: Paolo Abeni <pabeni@redhat.com>
Date: Tue, 2 Oct 2018 11:03:40 +0200
> This helper is unused since commit 988cf74deb45 ("inet:
> Stop generating UFO packets.")
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v6 19/23] zinc: Curve25519 ARM implementation
From: Jason A. Donenfeld @ 2018-10-03 1:03 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: LKML, Netdev, Linux Crypto Mailing List, David Miller,
Greg Kroah-Hartman, Samuel Neves, Andrew Lutomirski,
Jean-Philippe Aumasson, Russell King - ARM Linux,
linux-arm-kernel, Peter Schwabe, Daniel J . Bernstein
In-Reply-To: <CAKv+Gu9FLDRLxHReKcveZYHNYerR5Y2pZd9gn-hWrU0jb2KgfA@mail.gmail.com>
(+Dan,Peter in CC. Replying to:
<https://lore.kernel.org/lkml/CAKv+Gu9FLDRLxHReKcveZYHNYerR5Y2pZd9gn-hWrU0jb2KgfA@mail.gmail.com/>
for context.)
Hi Ard,
On Tue, Oct 2, 2018 at 6:59 PM Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> Shouldn't this use the new simd abstraction as well?
Yes, it probably should, thanks.
> I guess qhasm means generated code, right?
> Because many of these adds are completely redundant ...
> This looks odd as well.
> Could you elaborate on what qhasm is exactly? And, as with the other
> patches, I would prefer it if we could have your changes as a separate
> patch (although having the qhasm base would be preferred)
Indeed qhasm converts this --
<https://github.com/floodyberry/supercop/blob/master/crypto_scalarmult/curve25519/neon2/scalarmult.pq>
-- into this. It's a thing from Dan (CC'd now) --
<http://cr.yp.to/qhasm.html>. As you've requested, I can layer the
patches to show our changes on top.
> ... you can drop this add
> same here
> and here
> and here
> and here
> and here
> and here
> and here
> redundant add
> I'll stop here - let me just note that this code does not strike me as
> particularly well optimized for in-order cores (such as A7).
> For instance, the sequence
> can be reordered as
> and not have every other instruction depend on the output of the previous one.
> Obviously, the ultimate truth is in the benchmark numbers, but I'd
> thought I'd mention it anyway.
Yes indeed the output is suboptimal in a lot of places. We can
gradually clean this up -- slowly and carefully over time -- if you
want. I can also look into producing a new implementation within HACL*
so that it's verified. Assurance-wise, though, I feel pretty good
about this implementation considering its origins, its breadth of use
(in BoringSSL), the fuzzing hours it's incurred, and the actual
implementation itself.
Either way, performance-wise, it's really worth having.
For example, on a Cortex-A7, we get these results (according to get_cycles()):
neon: 23142 cycles per call
fiat32: 49136 cycles per call
donna32: 71988 cycles per call
And on a Cortex-A9, we get these results (according to get_cycles()):
neon: 5020 cycles per call
fiat32: 17326 cycles per call
donna32: 28076 cycles per call
Jason
^ permalink raw reply
* Re: [PATCH net-next] netfilter: xt_quota: fix the behavior of xt_quota module
From: Pablo Neira Ayuso @ 2018-10-02 18:15 UTC (permalink / raw)
To: Chenbo Feng
Cc: zenczykowski, Chenbo Feng, netdev, netfilter-devel, kernel-team,
Lorenzo Colitti
In-Reply-To: <CAMOXUJkYwz-aOuWO4ygVchTVWiX59=3znCb-NWC55nsmHSD93A@mail.gmail.com>
Hi Chenbo,
On Tue, Oct 02, 2018 at 10:45:58AM -0700, Chenbo Feng wrote:
> On Tue, Oct 2, 2018 at 3:51 AM Pablo Neira Ayuso <pablo@netfilter.org> wrote:
[...]
> Do you mean the remain field will be zeroed when copying the
> xt_quota_info struct out of the kernel? I believe that is decided by
> the usersize defined in struct xt_match and this patch set it to the
> full struct size. So the whole xt_quota_info struct will be copied
> into userspace including the field stores the remaining quota. The
> userspace will not be aware of it if the ipatbles is not updated but
> it should not modify it as well. I have tested the behavior with
> net-next branch and it seems working. Am I missing something
> recently updated?
Hm, I see, I overlook that your patch removes this:
- .usersize = offsetof(struct xt_quota_info, master),
BTW, is iptables -D command working with your patch?
Telling this because if .usersize is removed, then IIRC userspace
compares this new remain field with userspace value and deletion will
break.
Patch that I was referring before is this one from Willem:
commit f32815d21d4d8287336fb9cef4d2d9e0866214c2
Author: Willem de Bruijn <willemb@google.com>
Date: Mon Jan 2 17:19:40 2017 -0500
xtables: add xt_match, xt_target and data copy_to_user functions
xt_entry_target, xt_entry_match and their private data may contain
kernel data.
[...]
Private data is defined in xt_match and xt_target. All matches and
targets that maintain kernel data store this at the tail of their
private structure. Extend xt_match and xt_target with .usersize to
limit how many bytes of data are copied. The remainder is cleared.
Let me know, thanks !
^ permalink raw reply
* Re: [PATCH net] net: systemport: Fix wake-up interrupt race during resume
From: David Miller @ 2018-10-03 0:35 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, linux-kernel
In-Reply-To: <20181002235204.26135-1-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 2 Oct 2018 16:52:03 -0700
> The AON_PM_L2 is normally used to trigger and identify the source of a
> wake-up event. Since the RX_SYS clock is no longer turned off, we also
> have an interrupt being sent to the SYSTEMPORT INTRL_2_0 controller, and
> that interrupt remains active up until the magic packet detector is
> disabled which happens much later during the driver resumption.
>
> The race happens if we have a CPU that is entering the SYSTEMPORT
> INTRL2_0 handler during resume, and another CPU has managed to clear the
> wake-up interrupt during bcm_sysport_resume_from_wol(). In that case, we
> have the first CPU stuck in the interrupt handler with an interrupt
> cause that has been cleared under its feet, and so we keep returning
> IRQ_NONE and we never make any progress.
>
> This was not a problem before because we would always turn off the
> RX_SYS clock during WoL, so the SYSTEMPORT INTRL2_0 would also be turned
> off as well, thus not latching the interrupt.
>
> The fix is to make sure we do not enable either the MPD or
> BRCM_TAG_MATCH interrupts since those are redundant with what the
> AON_PM_L2 interrupt controller already processes and they would cause
> such a race to occur.
>
> Fixes: bb9051a2b230 ("net: systemport: Add support for WAKE_FILTER")
> Fixes: 83e82f4c706b ("net: systemport: add Wake-on-LAN support")
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Applied, thanks Florian.
^ permalink raw reply
* Re: [PATCH net-next] netfilter: xt_quota: fix the behavior of xt_quota module
From: Chenbo Feng @ 2018-10-02 17:45 UTC (permalink / raw)
To: pablo
Cc: zenczykowski, Chenbo Feng, netdev, netfilter-devel, kernel-team,
Lorenzo Colitti
In-Reply-To: <20181002105125.uv7mcitvaalpjueo@salvia>
On Tue, Oct 2, 2018 at 3:51 AM Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>
> On Tue, Oct 02, 2018 at 03:38:24AM -0700, Maciej Żenczykowski wrote:
> > > Well, you will need a kernel + userspace update anyway, right?
> >
> > It's true you need new iptables userspace to *see* during dump and/or
> > manually *set* during restore the remain counter.
> >
> > However, (and I believe Chenbo tested this) just a new kernel is
> > enough to fix the problem of modifications within the table resetting
> > the counter.
> > This is because the data gets copied out of kernel and back into
> > kernel by old iptables without any further modifications.
> > ie. the new kernel not clearing the field on copy to userspace and
> > honouring it on copy to kernel is sufficient.
>
> I see, Willem removed this behaviour in newer kernels. The private
> area is now zeroed, is that what you mean right? So I guess this
> cannot be done transparently.
>
Sorry, resend in plain text mode.
Do you mean the remain field will be zeroed when copying the
xt_quota_info struct out of the kernel? I believe that is decided by
the usersize defined in struct xt_match and this patch set it to the
full struct size. So the whole xt_quota_info struct will be copied
into userspace including the field stores the remaining quota. The
userspace will not be aware of it if the ipatbles is not updated but
it should not modify it as well. I have tested the behavior with
net-next branch and it seems working. Am I missing something recently
updated?
> Anyway, I think the --remain approach to fix this longstanding
> problem from iptables :-).
>
> > So iptables-save | iptables-restore doesn't work, but iptables -A foo does.
> >
> > (currently iptables -t X -{A,D} foo clears all xt_quota counters in
> > table X even when foo is utterly unrelated)
> >
> > >> I mean: Instead of using atomic64_set() to set the counter to 1 once
> > >> we went over quota,
> > >
> > > incomplete sentence, sorry:
> > >
> > > I mean: Instead of using atomic64_set() to set the counter to 1 once
> > > we go overquota, we just keep updating 'consumed' bytes.
> >
> > I guess it's a fair point that with a u64 we won't ever realistically
> > overflow the number of sent bytes, so this could be a running counter
> > of matched bytes...
> >
> > and we don't even need to update it if it was over the quota when we
> > first looked at it, so we'll go over by at most # of cpus * max size
> > of gso packet bytes.
> >
> > > ie. we don't express things in 'remaining bytes' logic, but we account
> > > for 'bytes we already consumed'. So we never go negative - I know
> > > understand what you mean about -1... I think we are each other
> > > thinking from our respective approach proposal.
> >
> > I guess our decision was probably driven by xt_quota2 use on android
> > where infinite quota is often used as a temporary placeholder.
>
> I see, thanks for explaining.
>
> Thanks.
^ permalink raw reply
* RE: [PATCH net v2] net/ncsi: Extend NC-SI Netlink interface to allow user space to send NC-SI command
From: Justin.Lee1 @ 2018-10-02 17:36 UTC (permalink / raw)
To: sam, joel; +Cc: linux-aspeed, netdev, openbmc, amithash, christian, vijaykhemka
In-Reply-To: <18e571bb7c5879a12754b1df20f51fd87ea48712.camel@mendozajonas.com>
Hi Sam,
Sure, I will generate v3 after Vijay's patch is approved.
Thanks,
Justin
> On Fri, 2018-09-28 at 18:15 +0000, Justin.Lee1@Dell.com wrote:
> > The new command (NCSI_CMD_SEND_CMD) is added to allow user space application
> > to send NC-SI command to the network card.
> > Also, add a new attribute (NCSI_ATTR_DATA) for transferring request and response.
> >
> > The work flow is as below.
> >
> > Request:
> > User space application -> Netlink interface (msg)
> > -> new Netlink handler - ncsi_send_cmd_nl()
> > -> ncsi_xmit_cmd()
> > Response:
> > Response received - ncsi_rcv_rsp() -> internal response handler - ncsi_rsp_handler_xxx()
> > -> ncsi_rsp_handler_netlink()
> > -> ncsi_send_netlink_rsp ()
> > -> Netlink interface (msg)
> > -> user space application
> > Command timeout - ncsi_request_timeout() -> ncsi_send_netlink_timeout ()
> > -> Netlink interface (msg with zero data length)
> > -> user space application
> > Error:
> > Error detected -> ncsi_send_netlink_err () -> Netlink interface (err msg)
> > -> user space application
> >
> >
> > Signed-off-by: Justin Lee <justin.lee1@dell.com>
>
> Hi Justin,
>
> This is looking pretty good, combined with Vijay's base patch the two
> approaches should fit together nicely (
> http://patchwork.ozlabs.org/patch/976510/).
>
> A good merge order would probably be the above patch first, then this
> patch and Vijay's further OEM patches based on top of that to reduce
> conflicts.
>
> Cheers,
> Sam
^ permalink raw reply
* [PATCH net] nfp: avoid soft lockups under control message storm
From: Jakub Kicinski @ 2018-10-02 17:10 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
When FW floods the driver with control messages try to exit the cmsg
processing loop every now and then to avoid soft lockups. Cmsg
processing is generally very lightweight so 512 seems like a reasonable
budget, which should not be exceeded under normal conditions.
Fixes: 77ece8d5f196 ("nfp: add control vNIC datapath")
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Tested-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
---
.../net/ethernet/netronome/nfp/nfp_net_common.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 8ed38fd5a852..c6d29fdbb880 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -2077,14 +2077,17 @@ nfp_ctrl_rx_one(struct nfp_net *nn, struct nfp_net_dp *dp,
return true;
}
-static void nfp_ctrl_rx(struct nfp_net_r_vector *r_vec)
+static bool nfp_ctrl_rx(struct nfp_net_r_vector *r_vec)
{
struct nfp_net_rx_ring *rx_ring = r_vec->rx_ring;
struct nfp_net *nn = r_vec->nfp_net;
struct nfp_net_dp *dp = &nn->dp;
+ unsigned int budget = 512;
- while (nfp_ctrl_rx_one(nn, dp, r_vec, rx_ring))
+ while (nfp_ctrl_rx_one(nn, dp, r_vec, rx_ring) && budget--)
continue;
+
+ return budget;
}
static void nfp_ctrl_poll(unsigned long arg)
@@ -2096,9 +2099,13 @@ static void nfp_ctrl_poll(unsigned long arg)
__nfp_ctrl_tx_queued(r_vec);
spin_unlock_bh(&r_vec->lock);
- nfp_ctrl_rx(r_vec);
-
- nfp_net_irq_unmask(r_vec->nfp_net, r_vec->irq_entry);
+ if (nfp_ctrl_rx(r_vec)) {
+ nfp_net_irq_unmask(r_vec->nfp_net, r_vec->irq_entry);
+ } else {
+ tasklet_schedule(&r_vec->tasklet);
+ nn_dp_warn(&r_vec->nfp_net->dp,
+ "control message budget exceeded!\n");
+ }
}
/* Setup and Configuration
--
2.17.1
^ permalink raw reply related
* [PATCH net] net: systemport: Fix wake-up interrupt race during resume
From: Florian Fainelli @ 2018-10-02 23:52 UTC (permalink / raw)
To: netdev; +Cc: Florian Fainelli, David S. Miller, open list
The AON_PM_L2 is normally used to trigger and identify the source of a
wake-up event. Since the RX_SYS clock is no longer turned off, we also
have an interrupt being sent to the SYSTEMPORT INTRL_2_0 controller, and
that interrupt remains active up until the magic packet detector is
disabled which happens much later during the driver resumption.
The race happens if we have a CPU that is entering the SYSTEMPORT
INTRL2_0 handler during resume, and another CPU has managed to clear the
wake-up interrupt during bcm_sysport_resume_from_wol(). In that case, we
have the first CPU stuck in the interrupt handler with an interrupt
cause that has been cleared under its feet, and so we keep returning
IRQ_NONE and we never make any progress.
This was not a problem before because we would always turn off the
RX_SYS clock during WoL, so the SYSTEMPORT INTRL2_0 would also be turned
off as well, thus not latching the interrupt.
The fix is to make sure we do not enable either the MPD or
BRCM_TAG_MATCH interrupts since those are redundant with what the
AON_PM_L2 interrupt controller already processes and they would cause
such a race to occur.
Fixes: bb9051a2b230 ("net: systemport: Add support for WAKE_FILTER")
Fixes: 83e82f4c706b ("net: systemport: add Wake-on-LAN support")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/bcmsysport.c | 28 +++++++++-------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 147045757b10..c57238fce863 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1069,9 +1069,6 @@ static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
{
u32 reg;
- /* Stop monitoring MPD interrupt */
- intrl2_0_mask_set(priv, INTRL2_0_MPD | INTRL2_0_BRCM_MATCH_TAG);
-
/* Disable RXCHK, active filters and Broadcom tag matching */
reg = rxchk_readl(priv, RXCHK_CONTROL);
reg &= ~(RXCHK_BRCM_TAG_MATCH_MASK <<
@@ -1081,6 +1078,17 @@ static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
/* Clear the MagicPacket detection logic */
mpd_enable_set(priv, false);
+ reg = intrl2_0_readl(priv, INTRL2_CPU_STATUS);
+ if (reg & INTRL2_0_MPD)
+ netdev_info(priv->netdev, "Wake-on-LAN (MPD) interrupt!\n");
+
+ if (reg & INTRL2_0_BRCM_MATCH_TAG) {
+ reg = rxchk_readl(priv, RXCHK_BRCM_TAG_MATCH_STATUS) &
+ RXCHK_BRCM_TAG_MATCH_MASK;
+ netdev_info(priv->netdev,
+ "Wake-on-LAN (filters 0x%02x) interrupt!\n", reg);
+ }
+
netif_dbg(priv, wol, priv->netdev, "resumed from WOL\n");
}
@@ -1105,7 +1113,6 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
struct bcm_sysport_priv *priv = netdev_priv(dev);
struct bcm_sysport_tx_ring *txr;
unsigned int ring, ring_bit;
- u32 reg;
priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
@@ -1131,16 +1138,6 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
if (priv->irq0_stat & INTRL2_0_TX_RING_FULL)
bcm_sysport_tx_reclaim_all(priv);
- if (priv->irq0_stat & INTRL2_0_MPD)
- netdev_info(priv->netdev, "Wake-on-LAN (MPD) interrupt!\n");
-
- if (priv->irq0_stat & INTRL2_0_BRCM_MATCH_TAG) {
- reg = rxchk_readl(priv, RXCHK_BRCM_TAG_MATCH_STATUS) &
- RXCHK_BRCM_TAG_MATCH_MASK;
- netdev_info(priv->netdev,
- "Wake-on-LAN (filters 0x%02x) interrupt!\n", reg);
- }
-
if (!priv->is_lite)
goto out;
@@ -2641,9 +2638,6 @@ static int bcm_sysport_suspend_to_wol(struct bcm_sysport_priv *priv)
/* UniMAC receive needs to be turned on */
umac_enable_set(priv, CMD_RX_EN, 1);
- /* Enable the interrupt wake-up source */
- intrl2_0_mask_clear(priv, INTRL2_0_MPD | INTRL2_0_BRCM_MATCH_TAG);
-
netif_dbg(priv, wol, ndev, "entered WOL mode\n");
return 0;
--
2.17.1
^ permalink raw reply related
* Re: [RFC v2 bpf-next 4/5] tools/bpf: bpftool, print strerror when map lookup error occurs
From: Jakub Kicinski @ 2018-10-02 17:02 UTC (permalink / raw)
To: Prashant Bhole
Cc: Alexei Starovoitov, Daniel Borkmann, David S . Miller,
Quentin Monnet, netdev
In-Reply-To: <20181002053519.8000-5-bhole_prashant_q7@lab.ntt.co.jp>
On Tue, 2 Oct 2018 14:35:18 +0900, Prashant Bhole wrote:
> Since map lookup error can be ENOENT or EOPNOTSUPP, let's print
> strerror() as error message in normal and JSON output.
>
> This patch adds helper function print_entry_error() to print
> entry from lookup error occurs
>
> Example: Following example dumps a map which does not support lookup.
>
...
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Thank you!
^ permalink raw reply
* Re: [RFC v2 bpf-next 3/5] tools/bpf: bpftool, split the function do_dump()
From: Jakub Kicinski @ 2018-10-02 17:02 UTC (permalink / raw)
To: Prashant Bhole
Cc: Alexei Starovoitov, Daniel Borkmann, David S . Miller,
Quentin Monnet, netdev
In-Reply-To: <20181002053519.8000-4-bhole_prashant_q7@lab.ntt.co.jp>
On Tue, 2 Oct 2018 14:35:17 +0900, Prashant Bhole wrote:
> do_dump() function in bpftool/map.c has deep indentations. In order
> to reduce deep indent, let's move element printing code out of
> do_dump() into dump_map_elem() function.
>
> Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
^ permalink raw reply
* Re: [PATCH bpf-next v2 0/5] xsk: fix bug when trying to use both copy and zero-copy mode
From: Jakub Kicinski @ 2018-10-02 16:58 UTC (permalink / raw)
To: Magnus Karlsson
Cc: Karlsson, Magnus, Björn Töpel, ast, Daniel Borkmann,
Network Development, Jesper Dangaard Brouer
In-Reply-To: <CAJ8uoz2Bwrj2iMBn-DA6km=Zac45XigegdAOQQ9rWQkJMz8P=Q@mail.gmail.com>
On Tue, 2 Oct 2018 14:49:13 +0200, Magnus Karlsson wrote:
> On Mon, Oct 1, 2018 at 10:34 PM Jakub Kicinski wrote:
> > On Mon, 1 Oct 2018 14:51:32 +0200, Magnus Karlsson wrote:
> > > Jakub, please take a look at your patches. The last one I had to
> > > change slightly to make it fit with the new interface
> > > xdp_get_umem_from_qid(). An added bonus with this function is that we,
> > > in the future, can also use it from the driver to get a umem, thus
> > > simplifying driver implementations (and later remove the umem from the
> > > NDO completely). Björn will mail patches, at a later point in time,
> > > using this in the i40e and ixgbe drivers, that removes a good chunk of
> > > code from the ZC implementations.
> >
> > Nice, drivers which don't follow the prepare/commit model of handling
> > reconfigurations will benefit!
> >
> > > I also made your code aware of Tx queues. If we create a socket that
> > > only has a Tx queue, then the queue id will refer to a Tx queue id
> > > only and could be larger than the available amount of Rx queues.
> > > Please take a look at it.
> >
> > The semantics of Tx queue id are slightly unclear. To me XDP is
> > associated with Rx, so the qid in driver context can only refer to
> > Rx queue and its associated XDP Tx queue. It does not mean the Tx
> > queue stack uses, like it does for copy fallback. If one doesn't have
> > a Rx queue $id, there will be no associated XDP Tx queue $id (in all
> > drivers but Intel, and virtio, which use per-CPU Tx queues making TX
> > queue even more meaningless).
> >
> > Its to be seen how others implement AF_XDP. My general feeling is
> > that we should only talk about Rx queues in context of driver XDP.
>
> This is the way I see it. From an uapi point of view we can create a
> socket that can only do Rx, only Tx or both. We then bind this socket
> to a specific queue id on a device. If a packet is received on this
> queue id it is sent (by the default xdpsock sample program) to the
> socket. If a packet is sent on this socket it goes out on this same
> queue id. If you have not registered an Rx ring (in user space) for
> this socket, you cannot receive anything on this socket. And
> conversely, if you have no Tx ring, you will not be able to send
> anything.
>
> But if we take a look at this from the driver perspective and the NDO
> XDP_SETUP_XSK_UMEM, today it does not know anything about if Rx and Tx
> rings have been setup in the socket. It will always initialize the HW
> Rx and Tx queues of the supplied queue id. So with today's NDO
> interface you will always get a Rx/Tx queue pair. In order to realize
> the uapi above in an efficient manner and to support devices with more
> Tx queues than Rx, we need to change the NDO.
>
> Just as a note, in the applications I am used to work on, radio base
> stations and other telecom apps, it is the common case to have many
> more Tx queues than Rx queues just to be able to use scheduling,
> shaping and other QoS features that are important on egress in those
> systems. Therefore the interest in supporting Tx only queues. But
> maybe this is just a weird case, do not know.
It's a good case, it should be supported. I'm just wondering whether
the API we have today is going to be the right one. So for i40e you
actually allocate TX ring per RX ring? In ixgbe IIUC there is an XDP
TX ring per core so regardless how many TX queues one requests there
will actually be num_cpu_ids XDP TX queues... so even the check against
RX isn't meaningful there. Hm.. Okay, I think what you've done is the
safest bet, we can always relax the check later on.
LGTM, sorry for the noise! :)
^ permalink raw reply
* RE: [PATCH v2] net/ncsi: Add NCSI OEM command support
From: Justin.Lee1 @ 2018-10-02 16:53 UTC (permalink / raw)
To: sam, vijaykhemka, joel, linux-aspeed, openbmc, sdasari, netdev,
christian
In-Reply-To: <1004987ef0ab138e772ed5740a0d839bffe39910.camel@mendozajonas.com>
Hi Vijay,
Looks good. Please see my comment below.
Thanks,
Justin
> On Fri, 2018-09-28 at 18:06 -0700, Vijay Khemka wrote:
> > This patch adds OEM commands and response handling. It also defines OEM
> > command and response structure as per NCSI specification along with its
> > handlers.
> >
> > ncsi_cmd_handler_oem: This is a generic command request handler for OEM
> > commands
> > ncsi_rsp_handler_oem: This is a generic response handler for OEM commands
> >
> > Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
>
> Hi Vijay - looks good to me, and should be a good common base for your
> and Justin's changes.
>
> Reviewed-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
>
> > ---
> > net/ncsi/internal.h | 4 ++++
> > net/ncsi/ncsi-cmd.c | 31 ++++++++++++++++++++++++++++---
> > net/ncsi/ncsi-pkt.h | 16 ++++++++++++++++
> > net/ncsi/ncsi-rsp.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
> > 4 files changed, 91 insertions(+), 4 deletions(-)
> >
> > diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
> > index 8055e3965cef..c16cb7223064 100644
> > --- a/net/ncsi/internal.h
> > +++ b/net/ncsi/internal.h
> > @@ -68,6 +68,10 @@ enum {
> > NCSI_MODE_MAX
> > };
> >
> > +/* OEM Vendor Manufacture ID */
> > +#define NCSI_OEM_MFR_MLX_ID 0x8119
> > +#define NCSI_OEM_MFR_BCM_ID 0x113d
> > +
> > struct ncsi_channel_version {
> > u32 version; /* Supported BCD encoded NCSI version */
> > u32 alpha2; /* Supported BCD encoded NCSI version */
> > diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c
> > index 7567ca63aae2..2f98533eba46 100644
> > --- a/net/ncsi/ncsi-cmd.c
> > +++ b/net/ncsi/ncsi-cmd.c
> > @@ -211,6 +211,26 @@ static int ncsi_cmd_handler_snfc(struct sk_buff *skb,
> > return 0;
> > }
> >
> > +static int ncsi_cmd_handler_oem(struct sk_buff *skb,
> > + struct ncsi_cmd_arg *nca)
> > +{
> > + struct ncsi_cmd_oem_pkt *cmd;
OEM command doesn't not have the fixed data size. Should we use pointer instead?
struct ncsi_cmd_oem_pkt {
struct ncsi_cmd_pkt_hdr cmd; /* Command header */
__be32 mfr_id; /* Manufacture ID */
unsigned char *data; /* OEM Payload Data */
};
> > + unsigned int len;
> > +
> > + len = sizeof(struct ncsi_cmd_pkt_hdr) + 4;
> > + if (nca->payload < 26)
> > + len += 26;
Why does it add 26? I knew the other place in ncsi_alloc_command() is also add 26.
If it is less than 26, then it should be a fixed size of structure ncsi_cmd_pkt (46), right?
> > + else
> > + len += nca->payload;
> > +
> > + cmd = skb_put_zero(skb, len);
> > + cmd->mfr_id = nca->dwords[0];
> > + memcpy(cmd->data, &nca->dwords[1], nca->payload - 4);
Netlink request is using the new nca->data pointer to pass the data as the request payload
is not the same size and some command payload is bigger than 16 bytes.
Will you consider to use the same data pointer? So, we don't need to have a checking here.
If the command is used less than 16 bytes, we can simply assigned &nca->bytes[0] to it.
> > + ncsi_cmd_build_header(&cmd->cmd.common, nca);
> > +
> > + return 0;
> > +}
> > +
> > static struct ncsi_cmd_handler {
> > unsigned char type;
> > int payload;
> > @@ -244,7 +264,7 @@ static struct ncsi_cmd_handler {
> > { NCSI_PKT_CMD_GNS, 0, ncsi_cmd_handler_default },
> > { NCSI_PKT_CMD_GNPTS, 0, ncsi_cmd_handler_default },
> > { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default },
> > - { NCSI_PKT_CMD_OEM, 0, NULL },
> > + { NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem },
> > { NCSI_PKT_CMD_PLDM, 0, NULL },
> > { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
> > };
> > @@ -316,8 +336,13 @@ int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
> > return -ENOENT;
> > }
> >
> > - /* Get packet payload length and allocate the request */
> > - nca->payload = nch->payload;
> > + /* Get packet payload length and allocate the request
> > + * It is expected that if length set as negative in
> > + * handler structure means caller is initializing it
> > + * and setting length in nca before calling xmit function
> > + */
> > + if (nch->payload >= 0)
> > + nca->payload = nch->payload;
> > nr = ncsi_alloc_command(nca);
> > if (!nr)
> > return -ENOMEM;
> > diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
> > index 91b4b66438df..1f338386810d 100644
> > --- a/net/ncsi/ncsi-pkt.h
> > +++ b/net/ncsi/ncsi-pkt.h
> > @@ -151,6 +151,22 @@ struct ncsi_cmd_snfc_pkt {
> > unsigned char pad[22];
> > };
> >
> > +/* OEM Request Command as per NCSI Specification */
> > +struct ncsi_cmd_oem_pkt {
> > + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> > + __be32 mfr_id; /* Manufacture ID */
> > + unsigned char data[64]; /* OEM Payload Data */
> > + __be32 checksum; /* Checksum */
> > +};
> > +
> > +/* OEM Response Packet as per NCSI Specification */
> > +struct ncsi_rsp_oem_pkt {
> > + struct ncsi_rsp_pkt_hdr rsp; /* Command header */
> > + __be32 mfr_id; /* Manufacture ID */
> > + unsigned char data[64]; /* Payload data */
> > + __be32 checksum; /* Checksum */
> > +};
> > +
OEM command doesn't not have the fixed response data size too.
Should we use pointer instead?
> > /* Get Link Status */
> > struct ncsi_rsp_gls_pkt {
> > struct ncsi_rsp_pkt_hdr rsp; /* Response header */
> > diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
> > index 930c1d3796f0..22664ebdc93a 100644
> > --- a/net/ncsi/ncsi-rsp.c
> > +++ b/net/ncsi/ncsi-rsp.c
> > @@ -596,6 +596,48 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
> > return 0;
> > }
> >
> > +static struct ncsi_rsp_oem_handler {
> > + unsigned int mfr_id;
> > + int (*handler)(struct ncsi_request *nr);
> > +} ncsi_rsp_oem_handlers[] = {
> > + { NCSI_OEM_MFR_MLX_ID, NULL },
> > + { NCSI_OEM_MFR_BCM_ID, NULL }
> > +};
> > +
> > +
> > +/* Response handler for OEM command */
> > +static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
> > +{
> > + struct ncsi_rsp_oem_pkt *rsp;
> > + struct ncsi_rsp_oem_handler *nrh = NULL;
> > + unsigned int mfr_id, i;
> > +
> > + /* Get the response header */
> > + rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
> > + mfr_id = ntohl(rsp->mfr_id);
> > +
> > + /* Check for manufacturer id and Find the handler */
> > + for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
> > + if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
> > + if (ncsi_rsp_oem_handlers[i].handler)
> > + nrh = &ncsi_rsp_oem_handlers[i];
> > + else
> > + nrh = NULL;
> > +
> > + break;
> > + }
> > + }
> > +
> > + if (!nrh) {
> > + netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
> > + mfr_id);
> > + return -ENOENT;
> > + }
> > +
> > + /* Process the packet */
> > + return nrh->handler(nr);
> > +}
> > +
> > static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
> > {
> > struct ncsi_rsp_gvi_pkt *rsp;
> > @@ -932,7 +974,7 @@ static struct ncsi_rsp_handler {
> > { NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns },
> > { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts },
> > { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
> > - { NCSI_PKT_RSP_OEM, 0, NULL },
> > + { NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
> > { NCSI_PKT_RSP_PLDM, 0, NULL },
> > { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }
> > };
^ permalink raw reply
* Re: [PATCHv3 bpf-next 04/12] bpf: Add PTR_TO_SOCKET verifier type
From: Joe Stringer @ 2018-10-02 16:45 UTC (permalink / raw)
To: daniel
Cc: Joe Stringer, netdev, ast, john fastabend, tgraf,
Martin KaFai Lau, Nitin Hande, mauricio.vasquez
In-Reply-To: <8d27bf39-f6e6-1166-ce4e-c987c925ea24@iogearbox.net>
On Fri, 28 Sep 2018 at 06:38, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 09/28/2018 01:26 AM, Joe Stringer wrote:
> > Teach the verifier a little bit about a new type of pointer, a
> > PTR_TO_SOCKET. This pointer type is accessed from BPF through the
> > 'struct bpf_sock' structure.
> >
> > Signed-off-by: Joe Stringer <joe@wand.net.nz>
> [...]
> > +/* Return true if it's OK to have the same insn return a different type. */
> > +static bool reg_type_mismatch_ok(enum bpf_reg_type type)
> > +{
> > + switch (type) {
> > + case PTR_TO_CTX:
> > + case PTR_TO_SOCKET:
> > + case PTR_TO_SOCKET_OR_NULL:
> > + return false;
> > + default:
> > + return true;
> > + }
> > +}
> > +
> > +/* If an instruction was previously used with particular pointer types, then we
> > + * need to be careful to avoid cases such as the below, where it may be ok
> > + * for one branch accessing the pointer, but not ok for the other branch:
> > + *
> > + * R1 = sock_ptr
> > + * goto X;
> > + * ...
> > + * R1 = some_other_valid_ptr;
> > + * goto X;
> > + * ...
> > + * R2 = *(u32 *)(R1 + 0);
> > + */
> > +static bool reg_type_mismatch(enum bpf_reg_type src, enum bpf_reg_type prev)
> > +{
> > + return src != prev && (!reg_type_mismatch_ok(src) ||
> > + !reg_type_mismatch_ok(prev));
> > +}
> > +
> > static int do_check(struct bpf_verifier_env *env)
> > {
> > struct bpf_verifier_state *state;
> > @@ -4812,9 +4894,7 @@ static int do_check(struct bpf_verifier_env *env)
> > */
> > *prev_src_type = src_reg_type;
> >
> > - } else if (src_reg_type != *prev_src_type &&
> > - (src_reg_type == PTR_TO_CTX ||
> > - *prev_src_type == PTR_TO_CTX)) {
> > + } else if (reg_type_mismatch(src_reg_type, *prev_src_type)) {
> > /* ABuser program is trying to use the same insn
> > * dst_reg = *(u32*) (src_reg + off)
> > * with different pointer types:
> > @@ -4859,9 +4939,7 @@ static int do_check(struct bpf_verifier_env *env)
> >
> > if (*prev_dst_type == NOT_INIT) {
> > *prev_dst_type = dst_reg_type;
> > - } else if (dst_reg_type != *prev_dst_type &&
> > - (dst_reg_type == PTR_TO_CTX ||
> > - *prev_dst_type == PTR_TO_CTX)) {
> > + } else if (reg_type_mismatch(dst_reg_type, *prev_dst_type)) {
> > verbose(env, "same insn cannot be used with different pointers\n");
> > return -EINVAL;
>
> Can also be as follow-up later on, but it would be crucial to also have
> test_verifier tests on this logic here with mixing these pointer types
> from different branches (right now we only cover ctx there).
Thanks for the feedback. I've applied all of your suggestions.
Regarding these newer tests, I have added a few and will post that
with my next revision. Fortunately with the reference tracking it's
actually quite difficult to mix up the pointer types between socket
and another type, because if the type of the register is ambiguous
then you either end up leaking a reference or attempting to release
using a pointer to a non-socket. I've added tests for both of those
cases, along with attempts to read and write into offsets inside
ambiguous pointers which triggers most of these paths.
^ permalink raw reply
* Re: [PATCH RFC v2 net-next 03/25] netlink: introduce NLM_F_DUMP_PROPER_HDR flag
From: Jiri Benc @ 2018-10-02 16:33 UTC (permalink / raw)
To: David Ahern; +Cc: David Ahern, netdev, davem, christian, stephen
In-Reply-To: <61bdd006-98f8-18dd-9731-b64b34e35252@gmail.com>
On Tue, 2 Oct 2018 08:55:19 -0600, David Ahern wrote:
> You want take issue with a name suggest a different one.
I don't have a strong opinion on this. STRICT_HDR? HDR_CHECKED?
VERIFY_HDR? If you feel that your proposal is better, I don't mind.
Thanks,
Jiri
^ permalink raw reply
* Re: [PATCH RFC v2 net-next 03/25] netlink: introduce NLM_F_DUMP_PROPER_HDR flag
From: Jiri Benc @ 2018-10-02 16:30 UTC (permalink / raw)
To: David Ahern; +Cc: Christian Brauner, David Ahern, netdev, davem, stephen
In-Reply-To: <6d1380b4-217c-387b-7e44-efaa8d091108@gmail.com>
On Tue, 2 Oct 2018 08:57:24 -0600, David Ahern wrote:
> You can when you introduce a new option or a new flag that is required
> to get new behavior like kernel side filtering.
Yes. That was what I tried with the patchset a few years back. It would
be nice to revive the effort.
> I chose a netlink flag for consistency with NLM_F_DUMP_INTR and
> NLM_F_DUMP_FILTERED. Both are netlink flags. This patch set fixes only
> what is broken -- dumps.
When we're introducing better input checking in netlink (which is a
good thing!), it would be good to do it consistently and have it
generic across all operations.
Jiri
^ permalink raw reply
* Re: [PATCH RFC v2 net-next 02/25] net/ipv6: Refactor address dump to push inet6_fill_args to in6_dump_addrs
From: Jiri Benc @ 2018-10-02 16:24 UTC (permalink / raw)
To: David Ahern; +Cc: David Ahern, netdev, davem, christian, stephen
In-Reply-To: <1a37ac7e-8291-e3f2-c1f3-724c72f2b466@gmail.com>
On Tue, 2 Oct 2018 09:11:17 -0600, David Ahern wrote:
> Generically speaking a filter modifies the output based on the input.
> Specifying a target namespace is an input to the dump that modifies the
> output.
That's conventionally called "algorithm" :-)
Let's just say we have a different understanding of what "filter" is.
Perhaps we should look at it from a different side. What is the use
case of having NLM_F_DUMP_FILTERED set for IFA_TARGET_NETNSID? How is
this going to be used by applications?
> Yes, you can do it in userspace which is what iproute2 has done to this
> point, but it is grossly inefficient and that inefficiency has
> implications at scale.
You can't do that with IFA_TARGET_NETNSID. Which is my point. Without
the flag, you don't get a list of all interfaces in all net name spaces.
Jiri
^ permalink raw reply
* Re: [PATCH 1/1] bridge: remove BR_GROUPFWD_RESTRICTED for arbitrary forwarding of reserved addresses
From: Nikolay Aleksandrov @ 2018-10-02 16:10 UTC (permalink / raw)
To: Richard Weinberger
Cc: Ido Schimmel, Stephen Hemminger, Florian Fainelli,
bernhard.thaler, David S. Miller, bridge, netdev, David Gstir,
roopa
In-Reply-To: <1694684.hdcNQnb4e4@blindfold>
On 02/10/2018 18:56, Richard Weinberger wrote:
> Nikolay,
>
> Am Dienstag, 2. Oktober 2018, 16:59:31 CEST schrieb Nikolay Aleksandrov:
>> Richard please check commit:
>> commit 5af48b59f35c
>> Author: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
>> Date: Wed Sep 27 16:12:44 2017 +0300
>>
>> net: bridge: add per-port group_fwd_mask with less restrictions
>>
>> We need to be able to transparently forward most link-local frames via
>> tunnels (e.g. vxlan, qinq). Currently the bridge's group_fwd_mask has a
>> mask which restricts the forwarding of STP and LACP, but we need to be able
>> to forward these over tunnels and control that forwarding on a per-port
>> basis thus add a new per-port group_fwd_mask option which only disallows
>> mac pause frames to be forwarded (they're always dropped anyway).
>> The patch does not change the current default situation - all of the others
>> are still restricted unless configured for forwarding.
>> We have successfully tested this patch with LACP and STP forwarding over
>> VxLAN and qinq tunnels.
>>
>> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>
>>
>> Will this work for you ?
>> It's in the bridge since v4.15.
>
> Hmm, I *think* this is exactly what I need.
> To understand it correctly, I have to set per port group_fwd_mask for both slaves
> of the bridge then it will forward anything (except for PAUSE frames)?
>
Yes, that is the expected behaviour.
> Is there a reason why this knob is not documented in Documentation/ABI/testing/sysfs-class-net?
>
Hmm, I don't think any of the bridge knobs are documented there or any other master device for that
matter. Most of these options are documented in ip-link.8 man page from iproute2, it seems though
this one I've missed to document. I'll prepare a patch for iproute2.
> Thanks,
> //richard
>
>
>
^ permalink raw reply
* Re: [PATCH 1/1] bridge: remove BR_GROUPFWD_RESTRICTED for arbitrary forwarding of reserved addresses
From: Richard Weinberger @ 2018-10-02 15:56 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Ido Schimmel, Stephen Hemminger, Florian Fainelli,
bernhard.thaler, David S. Miller, bridge, netdev, David Gstir,
roopa
In-Reply-To: <09307ccf-02d6-ce63-7030-fcc560e93f23@cumulusnetworks.com>
Nikolay,
Am Dienstag, 2. Oktober 2018, 16:59:31 CEST schrieb Nikolay Aleksandrov:
> Richard please check commit:
> commit 5af48b59f35c
> Author: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> Date: Wed Sep 27 16:12:44 2017 +0300
>
> net: bridge: add per-port group_fwd_mask with less restrictions
>
> We need to be able to transparently forward most link-local frames via
> tunnels (e.g. vxlan, qinq). Currently the bridge's group_fwd_mask has a
> mask which restricts the forwarding of STP and LACP, but we need to be able
> to forward these over tunnels and control that forwarding on a per-port
> basis thus add a new per-port group_fwd_mask option which only disallows
> mac pause frames to be forwarded (they're always dropped anyway).
> The patch does not change the current default situation - all of the others
> are still restricted unless configured for forwarding.
> We have successfully tested this patch with LACP and STP forwarding over
> VxLAN and qinq tunnels.
>
> Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
>
> Will this work for you ?
> It's in the bridge since v4.15.
Hmm, I *think* this is exactly what I need.
To understand it correctly, I have to set per port group_fwd_mask for both slaves
of the bridge then it will forward anything (except for PAUSE frames)?
Is there a reason why this knob is not documented in Documentation/ABI/testing/sysfs-class-net?
Thanks,
//richard
^ permalink raw reply
* [net-next 5/9] ice: Split irq_tracker into sw_irq_tracker and hw_irq_tracker
From: Jeff Kirsher @ 2018-10-02 15:24 UTC (permalink / raw)
To: davem
Cc: Preethi Banala, netdev, nhorman, sassmann, jogreene,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181002152447.11175-1-jeffrey.t.kirsher@intel.com>
From: Preethi Banala <preethi.banala@intel.com>
For the PF driver, when mapping interrupts to queues, we need to request
IRQs from the kernel and we also have to allocate interrupts from
the device.
Similarly, when the VF driver (iavf.ko) initializes, it requests the kernel
IRQs that it needs but it can't directly allocate interrupts in the device.
Instead, it sends a mailbox message to the ice driver, which then allocates
interrupts in the device on the VF driver's behalf.
Currently both these cases end up having to reserve entries in
pf->irq_tracker but irq_tracker itself is sized based on how many vectors
the PF driver needs. Under the right circumstances, the VF driver can fail
to get entries in irq_tracker, which will result in the VF driver failing
probe.
To fix this, sw_irq_tracker and hw_irq_tracker are introduced. The
sw_irq_tracker tracks only the PF's IRQ request and doesn't play any
role in VF init. hw_irq_tracker represents the device's interrupt space.
When interrupts have to be allocated in the device for either PF or VF,
hw_irq_tracker will be looked up to see if the device has run out of
interrupts.
Signed-off-by: Preethi Banala <preethi.banala@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice.h | 21 ++--
drivers/net/ethernet/intel/ice/ice_lib.c | 75 +++++++++-----
drivers/net/ethernet/intel/ice/ice_main.c | 116 +++++++++++++++-------
3 files changed, 148 insertions(+), 64 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 9cce4cb91401..fc6bc1233f10 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -172,7 +172,8 @@ struct ice_vsi {
u32 rx_buf_failed;
u32 rx_page_failed;
int num_q_vectors;
- int base_vector;
+ int sw_base_vector; /* Irq base for OS reserved vectors */
+ int hw_base_vector; /* HW (absolute) index of a vector */
enum ice_vsi_type type;
u16 vsi_num; /* HW (absolute) index of this VSI */
u16 idx; /* software index in pf->vsi[] */
@@ -240,8 +241,14 @@ enum ice_pf_flags {
struct ice_pf {
struct pci_dev *pdev;
+
+ /* OS reserved IRQ details */
struct msix_entry *msix_entries;
- struct ice_res_tracker *irq_tracker;
+ struct ice_res_tracker *sw_irq_tracker;
+
+ /* HW reserved Interrupts for this PF */
+ struct ice_res_tracker *hw_irq_tracker;
+
struct ice_vsi **vsi; /* VSIs created by the driver */
struct ice_sw *first_sw; /* first switch created by firmware */
DECLARE_BITMAP(state, __ICE_STATE_NBITS);
@@ -256,9 +263,11 @@ struct ice_pf {
struct mutex sw_mutex; /* lock for protecting VSI alloc flow */
u32 msg_enable;
u32 hw_csum_rx_error;
- u32 oicr_idx; /* Other interrupt cause vector index */
+ u32 sw_oicr_idx; /* Other interrupt cause SW vector index */
+ u32 num_avail_sw_msix; /* remaining MSIX SW vectors left unclaimed */
+ u32 hw_oicr_idx; /* Other interrupt cause vector HW index */
+ u32 num_avail_hw_msix; /* remaining HW MSIX vectors left unclaimed */
u32 num_lan_msix; /* Total MSIX vectors for base driver */
- u32 num_avail_msix; /* remaining MSIX vectors left unclaimed */
u16 num_lan_tx; /* num lan tx queues setup */
u16 num_lan_rx; /* num lan rx queues setup */
u16 q_left_tx; /* remaining num tx queues left unclaimed */
@@ -293,8 +302,8 @@ struct ice_netdev_priv {
static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi,
struct ice_q_vector *q_vector)
{
- u32 vector = (vsi && q_vector) ? vsi->base_vector + q_vector->v_idx :
- ((struct ice_pf *)hw->back)->oicr_idx;
+ u32 vector = (vsi && q_vector) ? vsi->hw_base_vector + q_vector->v_idx :
+ ((struct ice_pf *)hw->back)->hw_oicr_idx;
int itr = ICE_ITR_NONE;
u32 val;
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index a4dfdf35ceab..8f7ee77cb70b 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1039,9 +1039,9 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
struct ice_pf *pf = vsi->back;
int num_q_vectors = 0;
- if (vsi->base_vector) {
- dev_dbg(&pf->pdev->dev, "VSI %d has non-zero base vector %d\n",
- vsi->vsi_num, vsi->base_vector);
+ if (vsi->sw_base_vector || vsi->hw_base_vector) {
+ dev_dbg(&pf->pdev->dev, "VSI %d has non-zero HW base vector %d or SW base vector %d\n",
+ vsi->vsi_num, vsi->hw_base_vector, vsi->sw_base_vector);
return -EEXIST;
}
@@ -1051,6 +1051,21 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
switch (vsi->type) {
case ICE_VSI_PF:
num_q_vectors = vsi->num_q_vectors;
+ /* reserve slots from OS requested IRQs */
+ vsi->sw_base_vector = ice_get_res(pf, pf->sw_irq_tracker,
+ num_q_vectors, vsi->idx);
+ if (vsi->sw_base_vector < 0) {
+ dev_err(&pf->pdev->dev,
+ "Failed to get tracking for %d SW vectors for VSI %d, err=%d\n",
+ num_q_vectors, vsi->vsi_num,
+ vsi->sw_base_vector);
+ return -ENOENT;
+ }
+ pf->num_avail_sw_msix -= num_q_vectors;
+
+ /* reserve slots from HW interrupts */
+ vsi->hw_base_vector = ice_get_res(pf, pf->hw_irq_tracker,
+ num_q_vectors, vsi->idx);
break;
default:
dev_warn(&vsi->back->pdev->dev, "Unknown VSI type %d\n",
@@ -1058,17 +1073,18 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
break;
}
- if (num_q_vectors)
- vsi->base_vector = ice_get_res(pf, pf->irq_tracker,
- num_q_vectors, vsi->idx);
-
- if (vsi->base_vector < 0) {
+ if (vsi->hw_base_vector < 0) {
dev_err(&pf->pdev->dev,
- "Failed to get tracking for %d vectors for VSI %d, err=%d\n",
- num_q_vectors, vsi->vsi_num, vsi->base_vector);
+ "Failed to get tracking for %d HW vectors for VSI %d, err=%d\n",
+ num_q_vectors, vsi->vsi_num, vsi->hw_base_vector);
+ ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector,
+ vsi->idx);
+ pf->num_avail_sw_msix += num_q_vectors;
return -ENOENT;
}
+ pf->num_avail_hw_msix -= num_q_vectors;
+
return 0;
}
@@ -1554,7 +1570,7 @@ int ice_vsi_cfg_txqs(struct ice_vsi *vsi)
void ice_vsi_cfg_msix(struct ice_vsi *vsi)
{
struct ice_pf *pf = vsi->back;
- u16 vector = vsi->base_vector;
+ u16 vector = vsi->hw_base_vector;
struct ice_hw *hw = &pf->hw;
u32 txq = 0, rxq = 0;
int i, q, itr;
@@ -1762,7 +1778,7 @@ int ice_vsi_stop_tx_rings(struct ice_vsi *vsi)
* the queue to schedule NAPI handler
*/
v_idx = vsi->tx_rings[i]->q_vector->v_idx;
- wr32(hw, GLINT_DYN_CTL(vsi->base_vector + v_idx),
+ wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx),
GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M);
}
status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids,
@@ -1939,7 +1955,12 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
return vsi;
unroll_vector_base:
- ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
+ /* reclaim SW interrupts back to the common pool */
+ ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
+ pf->num_avail_sw_msix += vsi->num_q_vectors;
+ /* reclaim HW interrupt back to the common pool */
+ ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
+ pf->num_avail_hw_msix += vsi->num_q_vectors;
unroll_alloc_q_vector:
ice_vsi_free_q_vectors(vsi);
unroll_vsi_init:
@@ -1960,7 +1981,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
static void ice_vsi_release_msix(struct ice_vsi *vsi)
{
struct ice_pf *pf = vsi->back;
- u16 vector = vsi->base_vector;
+ u16 vector = vsi->hw_base_vector;
struct ice_hw *hw = &pf->hw;
u32 txq = 0;
u32 rxq = 0;
@@ -1992,7 +2013,7 @@ static void ice_vsi_release_msix(struct ice_vsi *vsi)
void ice_vsi_free_irq(struct ice_vsi *vsi)
{
struct ice_pf *pf = vsi->back;
- int base = vsi->base_vector;
+ int base = vsi->sw_base_vector;
if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) {
int i;
@@ -2000,6 +2021,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
if (!vsi->q_vectors || !vsi->irqs_ready)
return;
+ ice_vsi_release_msix(vsi);
+
vsi->irqs_ready = false;
for (i = 0; i < vsi->num_q_vectors; i++) {
u16 vector = i + base;
@@ -2022,7 +2045,6 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
devm_free_irq(&pf->pdev->dev, irq_num,
vsi->q_vectors[i]);
}
- ice_vsi_release_msix(vsi);
}
}
@@ -2110,6 +2132,9 @@ static int ice_search_res(struct ice_res_tracker *res, u16 needed, u16 id)
int start = res->search_hint;
int end = start;
+ if ((start + needed) > res->num_entries)
+ return -ENOMEM;
+
id |= ICE_RES_VALID_BIT;
do {
@@ -2183,9 +2208,9 @@ ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id)
*/
void ice_vsi_dis_irq(struct ice_vsi *vsi)
{
+ int base = vsi->sw_base_vector;
struct ice_pf *pf = vsi->back;
struct ice_hw *hw = &pf->hw;
- int base = vsi->base_vector;
u32 val;
int i;
@@ -2218,8 +2243,8 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)
/* disable each interrupt */
if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) {
- for (i = vsi->base_vector;
- i < (vsi->num_q_vectors + vsi->base_vector); i++)
+ for (i = vsi->hw_base_vector;
+ i < (vsi->num_q_vectors + vsi->hw_base_vector); i++)
wr32(hw, GLINT_DYN_CTL(i), 0);
ice_flush(hw);
@@ -2262,8 +2287,10 @@ int ice_vsi_release(struct ice_vsi *vsi)
ice_vsi_close(vsi);
/* reclaim interrupt vectors back to PF */
- ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
- pf->num_avail_msix += vsi->num_q_vectors;
+ ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
+ pf->num_avail_sw_msix += vsi->num_q_vectors;
+ ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
+ pf->num_avail_hw_msix += vsi->num_q_vectors;
ice_remove_vsi_fltr(&pf->hw, vsi->idx);
ice_vsi_delete(vsi);
@@ -2299,8 +2326,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
return -EINVAL;
ice_vsi_free_q_vectors(vsi);
- ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
- vsi->base_vector = 0;
+ ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
+ ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
+ vsi->sw_base_vector = 0;
+ vsi->hw_base_vector = 0;
ice_vsi_clear_rings(vsi);
ice_vsi_free_arrays(vsi, false);
ice_vsi_set_num_qs(vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index bb42ee643b77..d9f30d15ad65 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -95,7 +95,7 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf)
/* Trigger sw interrupt to revive the queue */
v_idx = tx_ring->q_vector->v_idx;
wr32(&vsi->back->hw,
- GLINT_DYN_CTL(vsi->base_vector + v_idx),
+ GLINT_DYN_CTL(vsi->hw_base_vector + v_idx),
(itr << GLINT_DYN_CTL_ITR_INDX_S) |
GLINT_DYN_CTL_SWINT_TRIG_M |
GLINT_DYN_CTL_INTENA_MSK_M);
@@ -1122,7 +1122,7 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename)
{
int q_vectors = vsi->num_q_vectors;
struct ice_pf *pf = vsi->back;
- int base = vsi->base_vector;
+ int base = vsi->sw_base_vector;
int rx_int_idx = 0;
int tx_int_idx = 0;
int vector, err;
@@ -1203,7 +1203,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
wr32(hw, PFINT_OICR_ENA, val);
/* SW_ITR_IDX = 0, but don't change INTENA */
- wr32(hw, GLINT_DYN_CTL(pf->oicr_idx),
+ wr32(hw, GLINT_DYN_CTL(pf->hw_oicr_idx),
GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M);
}
@@ -1321,12 +1321,15 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf)
ice_flush(&pf->hw);
if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) {
- synchronize_irq(pf->msix_entries[pf->oicr_idx].vector);
+ synchronize_irq(pf->msix_entries[pf->sw_oicr_idx].vector);
devm_free_irq(&pf->pdev->dev,
- pf->msix_entries[pf->oicr_idx].vector, pf);
+ pf->msix_entries[pf->sw_oicr_idx].vector, pf);
}
- ice_free_res(pf->irq_tracker, pf->oicr_idx, ICE_RES_MISC_VEC_ID);
+ pf->num_avail_sw_msix += 1;
+ ice_free_res(pf->sw_irq_tracker, pf->sw_oicr_idx, ICE_RES_MISC_VEC_ID);
+ pf->num_avail_hw_msix += 1;
+ ice_free_res(pf->hw_irq_tracker, pf->hw_oicr_idx, ICE_RES_MISC_VEC_ID);
}
/**
@@ -1356,39 +1359,53 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
if (ice_is_reset_in_progress(pf->state))
goto skip_req_irq;
- /* reserve one vector in irq_tracker for misc interrupts */
- oicr_idx = ice_get_res(pf, pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ /* reserve one vector in sw_irq_tracker for misc interrupts */
+ oicr_idx = ice_get_res(pf, pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
if (oicr_idx < 0)
return oicr_idx;
- pf->oicr_idx = oicr_idx;
+ pf->num_avail_sw_msix -= 1;
+ pf->sw_oicr_idx = oicr_idx;
+
+ /* reserve one vector in hw_irq_tracker for misc interrupts */
+ oicr_idx = ice_get_res(pf, pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ if (oicr_idx < 0) {
+ ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ pf->num_avail_sw_msix += 1;
+ return oicr_idx;
+ }
+ pf->num_avail_hw_msix -= 1;
+ pf->hw_oicr_idx = oicr_idx;
err = devm_request_irq(&pf->pdev->dev,
- pf->msix_entries[pf->oicr_idx].vector,
+ pf->msix_entries[pf->sw_oicr_idx].vector,
ice_misc_intr, 0, pf->int_name, pf);
if (err) {
dev_err(&pf->pdev->dev,
"devm_request_irq for %s failed: %d\n",
pf->int_name, err);
- ice_free_res(pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ pf->num_avail_sw_msix += 1;
+ ice_free_res(pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID);
+ pf->num_avail_hw_msix += 1;
return err;
}
skip_req_irq:
ice_ena_misc_vector(pf);
- val = ((pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
+ val = ((pf->hw_oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
PFINT_OICR_CTL_CAUSE_ENA_M);
wr32(hw, PFINT_OICR_CTL, val);
/* This enables Admin queue Interrupt causes */
- val = ((pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
+ val = ((pf->hw_oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
PFINT_FW_CTL_CAUSE_ENA_M);
wr32(hw, PFINT_FW_CTL, val);
itr_gran = hw->itr_gran_200;
- wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_idx),
+ wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx),
ITR_TO_REG(ICE_ITR_8K, itr_gran));
ice_flush(hw);
@@ -1797,6 +1814,7 @@ static int ice_ena_msix_range(struct ice_pf *pf)
/* reserve vectors for LAN traffic */
pf->num_lan_msix = min_t(int, num_online_cpus(), v_left);
v_budget += pf->num_lan_msix;
+ v_left -= pf->num_lan_msix;
pf->msix_entries = devm_kcalloc(&pf->pdev->dev, v_budget,
sizeof(struct msix_entry), GFP_KERNEL);
@@ -1824,10 +1842,11 @@ static int ice_ena_msix_range(struct ice_pf *pf)
"not enough vectors. requested = %d, obtained = %d\n",
v_budget, v_actual);
if (v_actual >= (pf->num_lan_msix + 1)) {
- pf->num_avail_msix = v_actual - (pf->num_lan_msix + 1);
+ pf->num_avail_sw_msix = v_actual -
+ (pf->num_lan_msix + 1);
} else if (v_actual >= 2) {
pf->num_lan_msix = 1;
- pf->num_avail_msix = v_actual - 2;
+ pf->num_avail_sw_msix = v_actual - 2;
} else {
pci_disable_msix(pf->pdev);
err = -ERANGE;
@@ -1859,13 +1878,33 @@ static void ice_dis_msix(struct ice_pf *pf)
clear_bit(ICE_FLAG_MSIX_ENA, pf->flags);
}
+/**
+ * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme
+ * @pf: board private structure
+ */
+static void ice_clear_interrupt_scheme(struct ice_pf *pf)
+{
+ if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
+ ice_dis_msix(pf);
+
+ if (pf->sw_irq_tracker) {
+ devm_kfree(&pf->pdev->dev, pf->sw_irq_tracker);
+ pf->sw_irq_tracker = NULL;
+ }
+
+ if (pf->hw_irq_tracker) {
+ devm_kfree(&pf->pdev->dev, pf->hw_irq_tracker);
+ pf->hw_irq_tracker = NULL;
+ }
+}
+
/**
* ice_init_interrupt_scheme - Determine proper interrupt scheme
* @pf: board private structure to initialize
*/
static int ice_init_interrupt_scheme(struct ice_pf *pf)
{
- int vectors = 0;
+ int vectors = 0, hw_vectors = 0;
ssize_t size;
if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
@@ -1879,30 +1918,31 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf)
/* set up vector assignment tracking */
size = sizeof(struct ice_res_tracker) + (sizeof(u16) * vectors);
- pf->irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL);
- if (!pf->irq_tracker) {
+ pf->sw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL);
+ if (!pf->sw_irq_tracker) {
ice_dis_msix(pf);
return -ENOMEM;
}
- pf->irq_tracker->num_entries = vectors;
+ /* populate SW interrupts pool with number of OS granted IRQs. */
+ pf->num_avail_sw_msix = vectors;
+ pf->sw_irq_tracker->num_entries = vectors;
- return 0;
-}
+ /* set up HW vector assignment tracking */
+ hw_vectors = pf->hw.func_caps.common_cap.num_msix_vectors;
+ size = sizeof(struct ice_res_tracker) + (sizeof(u16) * hw_vectors);
-/**
- * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme
- * @pf: board private structure
- */
-static void ice_clear_interrupt_scheme(struct ice_pf *pf)
-{
- if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
- ice_dis_msix(pf);
-
- if (pf->irq_tracker) {
- devm_kfree(&pf->pdev->dev, pf->irq_tracker);
- pf->irq_tracker = NULL;
+ pf->hw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL);
+ if (!pf->hw_irq_tracker) {
+ ice_clear_interrupt_scheme(pf);
+ return -ENOMEM;
}
+
+ /* populate HW interrupts pool with number of HW supported irqs. */
+ pf->num_avail_hw_msix = hw_vectors;
+ pf->hw_irq_tracker->num_entries = hw_vectors;
+
+ return 0;
}
/**
@@ -3213,6 +3253,12 @@ static void ice_rebuild(struct ice_pf *pf)
if (err)
goto err_sched_init_port;
+ /* reset search_hint of irq_trackers to 0 since interrupts are
+ * reclaimed and could be allocated from beginning during VSI rebuild
+ */
+ pf->sw_irq_tracker->search_hint = 0;
+ pf->hw_irq_tracker->search_hint = 0;
+
err = ice_vsi_rebuild_all(pf);
if (err) {
dev_err(dev, "ice_vsi_rebuild_all failed\n");
@@ -3610,7 +3656,7 @@ static void ice_tx_timeout(struct net_device *netdev)
if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
val = rd32(&pf->hw,
GLINT_DYN_CTL(tx_ring->q_vector->v_idx +
- tx_ring->vsi->base_vector - 1));
+ tx_ring->vsi->hw_base_vector));
netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n",
vsi->vsi_num, hung_queue, tx_ring->next_to_clean,
--
2.17.1
^ permalink raw reply related
* [net-next 7/9] ice: Align ice_reset_req enum values to hardware reset values
From: Jeff Kirsher @ 2018-10-02 15:24 UTC (permalink / raw)
To: davem
Cc: Brett Creeley, netdev, nhorman, sassmann, jogreene,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181002152447.11175-1-jeffrey.t.kirsher@intel.com>
From: Brett Creeley <brett.creeley@intel.com>
Currently the ice_reset_req enum values have to be translated into
a different set of values that the hardware understands for the same
reset types. Avoid this translation by aligning ice_reset_req enum
values to the ones that the hardware understands.
Also add and else if block to check for ICE_RESET_EMPR and put a dev_dbg
message in the else case.
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_main.c | 5 ++++-
drivers/net/ethernet/intel/ice/ice_type.h | 14 ++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index bb76a0bf2fd1..f51857ead0f3 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1241,8 +1241,11 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data)
pf->corer_count++;
else if (reset == ICE_RESET_GLOBR)
pf->globr_count++;
- else
+ else if (reset == ICE_RESET_EMPR)
pf->empr_count++;
+ else
+ dev_dbg(&pf->pdev->dev, "Invalid reset type %d\n",
+ reset);
/* If a reset cycle isn't already in progress, we set a bit in
* pf->state so that the service task can start a reset/rebuild.
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index 4a64421b77a7..87930f68d3fb 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -150,12 +150,18 @@ struct ice_mac_info {
u8 perm_addr[ETH_ALEN];
};
-/* Various RESET request, These are not tied with HW reset types */
+/* Reset types used to determine which kind of reset was requested. These
+ * defines match what the RESET_TYPE field of the GLGEN_RSTAT register.
+ * ICE_RESET_PFR does not match any RESET_TYPE field in the GLGEN_RSTAT register
+ * because its reset source is different than the other types listed.
+ */
enum ice_reset_req {
+ ICE_RESET_POR = 0,
ICE_RESET_INVAL = 0,
- ICE_RESET_PFR = 1,
- ICE_RESET_CORER = 2,
- ICE_RESET_GLOBR = 3,
+ ICE_RESET_CORER = 1,
+ ICE_RESET_GLOBR = 2,
+ ICE_RESET_EMPR = 3,
+ ICE_RESET_PFR = 4,
};
/* Bus parameters */
--
2.17.1
^ permalink raw reply related
* [net-next 3/9] ice: Implement VSI replay framework
From: Jeff Kirsher @ 2018-10-02 15:24 UTC (permalink / raw)
To: davem
Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <20181002152447.11175-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Currently, switch filters get replayed after reset. In addition to
filters, other VSI attributes (like RSS configuration, Tx scheduler
configuration, etc.) also need to be replayed after reset.
Thus, instead of replaying based on functional blocks (i.e. replay
all filters for all VSIs, followed by RSS configuration replay for
all VSIs, and so on), it makes more sense to have the replay centered
around a VSI. In other words, replay all configurations for a VSI before
moving on to rebuilding the next VSI.
To that effect, this patch introduces a VSI replay framework in a new
function ice_vsi_replay_all. Currently it only replays switch filters,
but it will be expanded in the future to replay additional VSI attributes.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 65 +++++++++++-
drivers/net/ethernet/intel/ice/ice_common.h | 2 +
drivers/net/ethernet/intel/ice/ice_main.c | 44 +++++++-
drivers/net/ethernet/intel/ice/ice_switch.c | 107 ++++++++++++--------
drivers/net/ethernet/intel/ice/ice_switch.h | 8 +-
drivers/net/ethernet/intel/ice/ice_type.h | 3 +
6 files changed, 178 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 62bc717e4a90..4e0ed2364a6b 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -422,7 +422,7 @@ static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
devm_kfree(ice_hw_to_dev(hw), lst_itr);
}
}
-
+ ice_rm_all_sw_replay_rule_info(hw);
devm_kfree(ice_hw_to_dev(hw), sw->recp_list);
devm_kfree(ice_hw_to_dev(hw), sw);
}
@@ -2674,6 +2674,69 @@ ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
ICE_SCHED_NODE_OWNER_LAN);
}
+/**
+ * ice_replay_pre_init - replay pre initialization
+ * @hw: pointer to the hw struct
+ *
+ * Initializes required config data for VSI, FD, ACL, and RSS before replay.
+ */
+static enum ice_status ice_replay_pre_init(struct ice_hw *hw)
+{
+ struct ice_switch_info *sw = hw->switch_info;
+ u8 i;
+
+ /* Delete old entries from replay filter list head if there is any */
+ ice_rm_all_sw_replay_rule_info(hw);
+ /* In start of replay, move entries into replay_rules list, it
+ * will allow adding rules entries back to filt_rules list,
+ * which is operational list.
+ */
+ for (i = 0; i < ICE_SW_LKUP_LAST; i++)
+ list_replace_init(&sw->recp_list[i].filt_rules,
+ &sw->recp_list[i].filt_replay_rules);
+
+ return 0;
+}
+
+/**
+ * ice_replay_vsi - replay VSI configuration
+ * @hw: pointer to the hw struct
+ * @vsi_handle: driver VSI handle
+ *
+ * Restore all VSI configuration after reset. It is required to call this
+ * function with main VSI first.
+ */
+enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
+{
+ enum ice_status status;
+
+ if (!ice_is_vsi_valid(hw, vsi_handle))
+ return ICE_ERR_PARAM;
+
+ /* Replay pre-initialization if there is any */
+ if (vsi_handle == ICE_MAIN_VSI_HANDLE) {
+ status = ice_replay_pre_init(hw);
+ if (status)
+ return status;
+ }
+
+ /* Replay per VSI all filters */
+ status = ice_replay_vsi_all_fltr(hw, vsi_handle);
+ return status;
+}
+
+/**
+ * ice_replay_post - post replay configuration cleanup
+ * @hw: pointer to the hw struct
+ *
+ * Post replay cleanup.
+ */
+void ice_replay_post(struct ice_hw *hw)
+{
+ /* Delete old entries from replay filter list head */
+ ice_rm_all_sw_replay_rule_info(hw);
+}
+
/**
* ice_stat_update40 - read 40 bit stat from the chip and update stat values
* @hw: ptr to the hardware info
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index 01384fb919df..5493266d4204 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -96,6 +96,8 @@ enum ice_status
ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_qgrps,
struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
struct ice_sq_cd *cd);
+enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle);
+void ice_replay_post(struct ice_hw *hw);
void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
void ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
bool prev_stat_loaded, u64 *prev_stat, u64 *cur_stat);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 49fd5911fdc4..8a9301d2a685 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3135,6 +3135,44 @@ static int ice_vsi_rebuild_all(struct ice_pf *pf)
return 0;
}
+/**
+ * ice_vsi_replay_all - replay all VSIs configuration in the PF
+ * @pf: the PF
+ */
+static int ice_vsi_replay_all(struct ice_pf *pf)
+{
+ struct ice_hw *hw = &pf->hw;
+ enum ice_status ret;
+ int i;
+
+ /* loop through pf->vsi array and replay the VSI if found */
+ for (i = 0; i < pf->num_alloc_vsi; i++) {
+ if (!pf->vsi[i])
+ continue;
+
+ ret = ice_replay_vsi(hw, pf->vsi[i]->idx);
+ if (ret) {
+ dev_err(&pf->pdev->dev,
+ "VSI at index %d replay failed %d\n",
+ pf->vsi[i]->idx, ret);
+ return -EIO;
+ }
+
+ /* Re-map HW VSI number, using VSI handle that has been
+ * previously validated in ice_replay_vsi() call above
+ */
+ pf->vsi[i]->vsi_num = ice_get_hw_vsi_num(hw, pf->vsi[i]->idx);
+
+ dev_info(&pf->pdev->dev,
+ "VSI at index %d filter replayed successfully - vsi_num %i\n",
+ pf->vsi[i]->idx, pf->vsi[i]->vsi_num);
+ }
+
+ /* Clean up replay filter after successful re-configuration */
+ ice_replay_post(hw);
+ return 0;
+}
+
/**
* ice_rebuild - rebuild after reset
* @pf: pf to rebuild
@@ -3181,10 +3219,10 @@ static void ice_rebuild(struct ice_pf *pf)
goto err_vsi_rebuild;
}
- ret = ice_replay_all_fltr(&pf->hw);
- if (ret) {
+ /* Replay all VSIs Configuration, including filters after reset */
+ if (ice_vsi_replay_all(pf)) {
dev_err(&pf->pdev->dev,
- "error replaying switch filter rules\n");
+ "error replaying VSI configurations with switch filter rules\n");
goto err_vsi_rebuild;
}
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 57cdaaa16e21..e949224b5282 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -106,6 +106,7 @@ ice_init_def_sw_recp(struct ice_hw *hw)
for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
recps[i].root_rid = i;
INIT_LIST_HEAD(&recps[i].filt_rules);
+ INIT_LIST_HEAD(&recps[i].filt_replay_rules);
mutex_init(&recps[i].filt_rule_lock);
}
@@ -2196,87 +2197,105 @@ void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
}
/**
- * ice_replay_fltr - Replay all the filters stored by a specific list head
+ * ice_replay_vsi_fltr - Replay filters for requested VSI
* @hw: pointer to the hardware structure
- * @list_head: list for which filters needs to be replayed
+ * @vsi_handle: driver VSI handle
* @recp_id: Recipe id for which rules need to be replayed
+ * @list_head: list for which filters need to be replayed
+ *
+ * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
+ * It is required to pass valid VSI handle.
*/
static enum ice_status
-ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct list_head *list_head)
+ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
+ struct list_head *list_head)
{
struct ice_fltr_mgmt_list_entry *itr;
- struct list_head l_head;
enum ice_status status = 0;
+ u16 hw_vsi_id;
if (list_empty(list_head))
return status;
+ hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
- /* Move entries from the given list_head to a temporary l_head so that
- * they can be replayed. Otherwise when trying to re-add the same
- * filter, the function will return already exists
- */
- list_replace_init(list_head, &l_head);
-
- /* Mark the given list_head empty by reinitializing it so filters
- * could be added again by *handler
- */
- list_for_each_entry(itr, &l_head, list_entry) {
+ list_for_each_entry(itr, list_head, list_entry) {
struct ice_fltr_list_entry f_entry;
f_entry.fltr_info = itr->fltr_info;
- if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
+ if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
+ itr->fltr_info.vsi_handle == vsi_handle) {
+ /* update the src in case it is vsi num */
+ if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
+ f_entry.fltr_info.src = hw_vsi_id;
status = ice_add_rule_internal(hw, recp_id, &f_entry);
if (status)
goto end;
continue;
}
-
- /* Add a filter per vsi separately */
- while (1) {
- u16 vsi;
-
- vsi = find_first_bit(itr->vsi_list_info->vsi_map,
- ICE_MAX_VSI);
- if (vsi == ICE_MAX_VSI)
- break;
-
- clear_bit(vsi, itr->vsi_list_info->vsi_map);
- f_entry.fltr_info.fwd_id.hw_vsi_id = vsi;
- f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
- if (recp_id == ICE_SW_LKUP_VLAN)
- status = ice_add_vlan_internal(hw, &f_entry);
- else
- status = ice_add_rule_internal(hw, recp_id,
- &f_entry);
- if (status)
- goto end;
- }
+ if (!test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
+ continue;
+ /* Clearing it so that the logic can add it back */
+ clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
+ f_entry.fltr_info.vsi_handle = vsi_handle;
+ f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
+ /* update the src in case it is vsi num */
+ if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
+ f_entry.fltr_info.src = hw_vsi_id;
+ if (recp_id == ICE_SW_LKUP_VLAN)
+ status = ice_add_vlan_internal(hw, &f_entry);
+ else
+ status = ice_add_rule_internal(hw, recp_id, &f_entry);
+ if (status)
+ goto end;
}
end:
- /* Clear the filter management list */
- ice_rem_sw_rule_info(hw, &l_head);
return status;
}
/**
- * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
+ * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
* @hw: pointer to the hardware structure
+ * @vsi_handle: driver VSI handle
*
- * NOTE: This function does not clean up partially added filters on error.
- * It is up to caller of the function to issue a reset or fail early.
+ * Replays filters for requested VSI via vsi_handle.
*/
-enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
+enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
{
struct ice_switch_info *sw = hw->switch_info;
enum ice_status status = 0;
u8 i;
for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
- struct list_head *head = &sw->recp_list[i].filt_rules;
+ struct list_head *head;
- status = ice_replay_fltr(hw, i, head);
+ head = &sw->recp_list[i].filt_replay_rules;
+ status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
if (status)
return status;
}
return status;
}
+
+/**
+ * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
+ * @hw: pointer to the hw struct
+ *
+ * Deletes the filter replay rules.
+ */
+void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
+{
+ struct ice_switch_info *sw = hw->switch_info;
+ u8 i;
+
+ if (!sw)
+ return;
+
+ for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
+ if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
+ struct list_head *l_head;
+
+ l_head = &sw->recp_list[i].filt_replay_rules;
+ ice_rem_sw_rule_info(hw, l_head);
+ }
+ }
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h
index 50ab036a17f3..7706e9b6003c 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.h
+++ b/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -126,6 +126,7 @@ struct ice_sw_recipe {
/* List of type ice_fltr_mgmt_list_entry */
struct list_head filt_rules;
+ struct list_head filt_replay_rules;
/* linked list of type recipe_list_entry */
struct list_head rg_list;
@@ -200,10 +201,11 @@ enum ice_status ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list);
enum ice_status
ice_cfg_dflt_vsi(struct ice_hw *hw, u16 vsi_handle, bool set, u8 direction);
+enum ice_status ice_init_def_sw_recp(struct ice_hw *hw);
u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle);
+bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle);
-enum ice_status ice_replay_all_fltr(struct ice_hw *hw);
-
-enum ice_status ice_init_def_sw_recp(struct ice_hw *hw);
+enum ice_status ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle);
+void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw);
#endif /* _ICE_SWITCH_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index fa459329c1de..4a64421b77a7 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -18,6 +18,9 @@ static inline bool ice_is_tc_ena(u8 bitmap, u8 tc)
return test_bit(tc, (unsigned long *)&bitmap);
}
+/* Driver always calls main vsi_handle first */
+#define ICE_MAIN_VSI_HANDLE 0
+
/* debug masks - set these bits in hw->debug_mask to control output */
#define ICE_DBG_INIT BIT_ULL(1)
#define ICE_DBG_LINK BIT_ULL(4)
--
2.17.1
^ permalink raw reply related
* [net-next 6/9] ice: Implement ethtool hook for RSS switch
From: Jeff Kirsher @ 2018-10-02 15:24 UTC (permalink / raw)
To: davem
Cc: Md Fahad Iqbal Polash, netdev, nhorman, sassmann, jogreene,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181002152447.11175-1-jeffrey.t.kirsher@intel.com>
From: Md Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
This patch implements ethtool hook for enabling/disabling
RSS. While disabling RSS, the LUT should be cleared. And
the LUT should be reconfigured while enabling RSS.
Signed-off-by: Md Fahad Iqbal Polash <md.fahad.iqbal.polash@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 32 +++++++++++++++++++++++
drivers/net/ethernet/intel/ice/ice_lib.h | 2 ++
drivers/net/ethernet/intel/ice/ice_main.c | 6 +++++
3 files changed, 40 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 8f7ee77cb70b..98e8b7096e47 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1222,6 +1222,38 @@ static void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi)
}
}
+/**
+ * ice_vsi_manage_rss_lut - disable/enable RSS
+ * @vsi: the VSI being changed
+ * @ena: boolean value indicating if this is an enable or disable request
+ *
+ * In the event of disable request for RSS, this function will zero out RSS
+ * LUT, while in the event of enable request for RSS, it will reconfigure RSS
+ * LUT.
+ */
+int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena)
+{
+ int err = 0;
+ u8 *lut;
+
+ lut = devm_kzalloc(&vsi->back->pdev->dev, vsi->rss_table_size,
+ GFP_KERNEL);
+ if (!lut)
+ return -ENOMEM;
+
+ if (ena) {
+ if (vsi->rss_lut_user)
+ memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
+ else
+ ice_fill_rss_lut(lut, vsi->rss_table_size,
+ vsi->rss_size);
+ }
+
+ err = ice_set_rss(vsi, NULL, lut, vsi->rss_table_size);
+ devm_kfree(&vsi->back->pdev->dev, lut);
+ return err;
+}
+
/**
* ice_vsi_cfg_rss_lut_key - Configure RSS params for a VSI
* @vsi: VSI to be configured
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
index 4265464ee3d3..2617afe01c82 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -70,5 +70,7 @@ void ice_vsi_free_tx_rings(struct ice_vsi *vsi);
int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc);
+int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena);
+
irqreturn_t ice_msix_clean_rings(int __always_unused irq, void *data);
#endif /* !_ICE_LIB_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index d9f30d15ad65..bb76a0bf2fd1 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2412,6 +2412,12 @@ static int ice_set_features(struct net_device *netdev,
struct ice_vsi *vsi = np->vsi;
int ret = 0;
+ if (features & NETIF_F_RXHASH && !(netdev->features & NETIF_F_RXHASH))
+ ret = ice_vsi_manage_rss_lut(vsi, true);
+ else if (!(features & NETIF_F_RXHASH) &&
+ netdev->features & NETIF_F_RXHASH)
+ ret = ice_vsi_manage_rss_lut(vsi, false);
+
if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX))
ret = ice_vsi_manage_vlan_stripping(vsi, true);
--
2.17.1
^ permalink raw reply related
* [net-next 9/9] ice: Fix error on driver remove
From: Jeff Kirsher @ 2018-10-02 15:24 UTC (permalink / raw)
To: davem
Cc: Dave Ertman, netdev, nhorman, sassmann, jogreene,
Anirudh Venkataramanan, Jeff Kirsher
In-Reply-To: <20181002152447.11175-1-jeffrey.t.kirsher@intel.com>
From: Dave Ertman <david.m.ertman@intel.com>
If the driver is unloaded when traffic is in progress, errors are
generated. Fix this by releasing qvectors and NAPI handler on remove.
Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_main.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 9638684f75ac..46ccf265c218 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2130,6 +2130,7 @@ static int ice_probe(struct pci_dev *pdev,
static void ice_remove(struct pci_dev *pdev)
{
struct ice_pf *pf = pci_get_drvdata(pdev);
+ int i;
if (!pf)
return;
@@ -2139,6 +2140,11 @@ static void ice_remove(struct pci_dev *pdev)
ice_vsi_release_all(pf);
ice_free_irq_msix_misc(pf);
+ ice_for_each_vsi(pf, i) {
+ if (!pf->vsi[i])
+ continue;
+ ice_vsi_free_q_vectors(pf->vsi[i]);
+ }
ice_clear_interrupt_scheme(pf);
ice_deinit_pf(pf);
ice_deinit_hw(&pf->hw);
--
2.17.1
^ 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