* Re: [PATCH V3] net: stmmac: socfpga: Remove re-registration of reset controller
From: Dinh Nguyen @ 2016-04-21 14:39 UTC (permalink / raw)
To: Marek Vasut, netdev
Cc: peppe.cavallaro, alexandre.torgue, Matthew Gerlach,
David S . Miller
In-Reply-To: <1461240710-5381-1-git-send-email-marex@denx.de>
On 04/21/2016 07:11 AM, Marek Vasut wrote:
> Both socfpga_dwmac_parse_data() in dwmac-socfpga.c and stmmac_dvr_probe()
> in stmmac_main.c functions call devm_reset_control_get() to register an
> reset controller for the stmmac. This results in an attempt to register
> two reset controllers for the same non-shared reset line.
>
> The first attempt to register the reset controller works fine. The second
> attempt fails with warning from the reset controller core, see below.
> The warning is produced because the reset line is non-shared and thus
> it is allowed to have only up-to one reset controller associated with
> that reset line, not two or more.
>
> The solution has multiple parts. First, the original socfpga_dwmac_init()
> is tweaked to use reset controller pointer from the stmmac_priv (private
> data of the stmmac core) instead of the local instance, which was used
> before. The local re-registration of the reset controller is removed.
>
> Next, the socfpga_dwmac_init() is moved after stmmac_dvr_probe() in the
> probe function. This order is legal according to Altera and it makes the
> code much easier, since there is no need to temporarily register and
> unregister the reset controller ; the reset controller is already registered
> by the stmmac_dvr_probe().
>
> Finally, plat_dat->exit and socfpga_dwmac_exit() is no longer necessary,
> since the functionality is already performed by the stmmac core.
>
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 1 at drivers/reset/core.c:187 __of_reset_control_get+0x218/0x270
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc4-next-20160419-00015-gabb2477-dirty #4
> Hardware name: Altera SOCFPGA
> [<c010f290>] (unwind_backtrace) from [<c010b82c>] (show_stack+0x10/0x14)
> [<c010b82c>] (show_stack) from [<c0373da4>] (dump_stack+0x94/0xa8)
> [<c0373da4>] (dump_stack) from [<c011bcc0>] (__warn+0xec/0x104)
> [<c011bcc0>] (__warn) from [<c011bd88>] (warn_slowpath_null+0x20/0x28)
> [<c011bd88>] (warn_slowpath_null) from [<c03a6eb4>] (__of_reset_control_get+0x218/0x270)
> [<c03a6eb4>] (__of_reset_control_get) from [<c03a701c>] (__devm_reset_control_get+0x54/0x90)
> [<c03a701c>] (__devm_reset_control_get) from [<c041fa30>] (stmmac_dvr_probe+0x1b4/0x8e8)
> [<c041fa30>] (stmmac_dvr_probe) from [<c04298c8>] (socfpga_dwmac_probe+0x1b8/0x28c)
> [<c04298c8>] (socfpga_dwmac_probe) from [<c03d6ffc>] (platform_drv_probe+0x4c/0xb0)
> [<c03d6ffc>] (platform_drv_probe) from [<c03d54ec>] (driver_probe_device+0x224/0x2bc)
> [<c03d54ec>] (driver_probe_device) from [<c03d5630>] (__driver_attach+0xac/0xb0)
> [<c03d5630>] (__driver_attach) from [<c03d382c>] (bus_for_each_dev+0x6c/0xa0)
> [<c03d382c>] (bus_for_each_dev) from [<c03d4ad4>] (bus_add_driver+0x1a4/0x21c)
> [<c03d4ad4>] (bus_add_driver) from [<c03d60ac>] (driver_register+0x78/0xf8)
> [<c03d60ac>] (driver_register) from [<c0101760>] (do_one_initcall+0x40/0x170)
> [<c0101760>] (do_one_initcall) from [<c0800e38>] (kernel_init_freeable+0x1dc/0x27c)
> [<c0800e38>] (kernel_init_freeable) from [<c05d1bd4>] (kernel_init+0x8/0x114)
> [<c05d1bd4>] (kernel_init) from [<c01076f8>] (ret_from_fork+0x14/0x3c)
> ---[ end trace 059d2fbe87608fa9 ]---
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Matthew Gerlach <mgerlach@opensource.altera.com>
> Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
> Cc: David S. Miller <davem@davemloft.net>
> ---
> V2: Add missing stmmac_rst = NULL; into socfpga_dwmac_init_probe()
> V3: Greatly simplify the code by moving socfpga_dwmac_init() after
> stmmac_dvr_probe(), which is legal. This removes the need for
> temporary registration of the reset controller, which is super.
>
Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com>
Thanks,
Dinh
^ permalink raw reply
* Re: [PATCH v2] MAINTAINERS: net: add entry for TI Ethernet Switch drivers
From: Tony Lindgren @ 2016-04-21 14:33 UTC (permalink / raw)
To: Mugunthan V N
Cc: Grygorii Strashko, netdev, linux-kernel, David S. Miller,
Sekhar Nori, linux-omap, Richard Cochran
In-Reply-To: <5718B6EF.5000207@ti.com>
* Mugunthan V N <mugunthanvnm@ti.com> [160421 04:19]:
> On Thursday 21 April 2016 03:43 PM, Grygorii Strashko wrote:
> > Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW
> > (am33/am43/am57/dr7/davinci) to ensure that related patches
> > will go through dedicated linux-omap list.
> >
> > Also add Mugunthan as maintainer and myself as the reviewer.
> >
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: Tony Lindgren <tony@atomide.com>
> > Cc: Mugunthan V N <mugunthanvnm@ti.com>
> > Cc: Richard Cochran <richardcochran@gmail.com>
> > Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>
> Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Looks good to me too thanks:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* Re: [PATCH net-next] perf, bpf: minimize the size of perf_trace_() tracepoint handler
From: Steven Rostedt @ 2016-04-21 14:12 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Alexei Starovoitov, David S . Miller, Ingo Molnar,
Daniel Borkmann, Arnaldo Carvalho de Melo, Wang Nan, Josef Bacik,
Brendan Gregg, netdev, linux-kernel, kernel-team
In-Reply-To: <20160421140255.GH3430@twins.programming.kicks-ass.net>
On Thu, 21 Apr 2016 16:02:55 +0200
Peter Zijlstra <peterz@infradead.org> wrote:
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>
> David, please take through the net tree as this depends on prior patches
> by Alexei that are already in your tree.
Yes please!
Acked-by: Steven Rostedt <rostedt@goodmis.org>
-- Steve
^ permalink raw reply
* Re: [PATCH net-next] perf, bpf: minimize the size of perf_trace_() tracepoint handler
From: Peter Zijlstra @ 2016-04-21 14:02 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David S . Miller, Steven Rostedt, Ingo Molnar, Daniel Borkmann,
Arnaldo Carvalho de Melo, Wang Nan, Josef Bacik, Brendan Gregg,
netdev, linux-kernel, kernel-team
In-Reply-To: <1461035510-2810305-1-git-send-email-ast@fb.com>
On Mon, Apr 18, 2016 at 08:11:50PM -0700, Alexei Starovoitov wrote:
> move trace_call_bpf() into helper function to minimize the size
> of perf_trace_*() tracepoint handlers.
> text data bss dec hex filename
> 10541679 5526646 2945024 19013349 1221ee5 vmlinux_before
> 10509422 5526646 2945024 18981092 121a0e4 vmlinux_after
>
> It may seem that perf_fetch_caller_regs() can also be moved,
> but that is incorrect, since ip/sp will be wrong.
>
> bpf+tracepoint performance is not affected, since
> perf_swevent_put_recursion_context() is now inlined.
> export_symbol_gpl can also be dropped.
>
> No measurable change in normal perf tracepoints.
>
> Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> ---
> include/linux/trace_events.h | 5 +++++
> include/trace/perf.h | 13 +++----------
> kernel/events/core.c | 20 +++++++++++++++++++-
> 3 files changed, 27 insertions(+), 11 deletions(-)
>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
David, please take through the net tree as this depends on prior patches
by Alexei that are already in your tree.
^ permalink raw reply
* [PATCH net-next v1 1/1] tipc: fix stale links after re-enabling bearer
From: Parthasarathy Bhuvaragan @ 2016-04-21 13:51 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
Commit 42b18f605fea ("tipc: refactor function tipc_link_timeout()"),
introduced a bug which prevents sending of probe messages during
link synchronization phase. This leads to hanging links, if the
bearer is disabled/enabled after links are up.
In this commit, we send the probe messages correctly.
Fixes: 42b18f605fea ("tipc: refactor function tipc_link_timeout()")
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/link.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2e28a7d7e802..7059c94f33c5 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -721,8 +721,7 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
mtyp = STATE_MSG;
state = bc_acked != bc_snt;
probe = l->silent_intv_cnt;
- if (probe)
- l->silent_intv_cnt++;
+ l->silent_intv_cnt++;
break;
case LINK_RESET:
setup = l->rst_cnt++ <= 4;
--
2.1.4
------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
^ permalink raw reply related
* Re: linux-next: zillions of lockdep whinges in include/net/sock.h:1408
From: Hannes Frederic Sowa @ 2016-04-21 13:49 UTC (permalink / raw)
To: Eric Dumazet, Valdis.Kletnieks; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <1461245496.7627.17.camel@edumazet-glaptop3.roam.corp.google.com>
On 21.04.2016 15:31, Eric Dumazet wrote:
> On Thu, 2016-04-21 at 05:05 -0400, Valdis.Kletnieks@vt.edu wrote:
>> On Thu, 21 Apr 2016 09:42:12 +0200, Hannes Frederic Sowa said:
>>> Hi,
>>>
>>> On Thu, Apr 21, 2016, at 02:30, Valdis Kletnieks wrote:
>>>> linux-next 20160420 is whining at an incredible rate - in 20 minutes of
>>>> uptime, I piled up some 41,000 hits from all over the place (cleaned up
>>>> to skip the CPU and PID so the list isn't quite so long):
>>>
>>> Thanks for the report. Can you give me some more details:
>>>
>>> Is this an nfs socket? Do you by accident know if this socket went
>>> through xs_reclassify_socket at any point? We do hold the appropriate
>>> locks at that point but I fear that the lockdep reinitialization
>>> confused lockdep.
>>
>> It wasn't an NFS socket, as NFS wasn't even active at the time. I'm reasonably
>> sure that multiple sockets were in play, given that tcp_v6_rcv and
>> udpv6_queue_rcv_skb were both implicated. I strongly suspect that pretty much
>> any IPv6 traffic could do it - the frequency dropped off quite a bit when I
>> closed firefox, which is usually a heavy network hitter on my laptop.
>
>
> Looks like the following patch is needed, can you try it please ?
>
> Thanks !
>
> diff --git a/include/net/sock.h b/include/net/sock.h
> index d997ec13a643..db8301c76d50 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -1350,7 +1350,8 @@ static inline bool lockdep_sock_is_held(const struct sock *csk)
> {
> struct sock *sk = (struct sock *)csk;
>
> - return lockdep_is_held(&sk->sk_lock) ||
> + return !debug_locks ||
> + lockdep_is_held(&sk->sk_lock) ||
> lockdep_is_held(&sk->sk_lock.slock);
> }
> #endif
I would prefer to add debug_locks at the WARN_ON level, like
WARN_ON(debug_locks && !lockdep_sock_is_held(sk)), but I am not sure if
this fixes the initial splat.
Thanks Eric!
^ permalink raw reply
* Re: [PATCH V2] net: ethernet: mellanox: correct page conversion
From: Or Gerlitz @ 2016-04-21 13:45 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Linux Netdev List, Sinan Kaya,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
timur-sgV2jX0FEOL9JmXXK+q4OQ, cov-sgV2jX0FEOL9JmXXK+q4OQ,
Yishai Hadas, Haggai Abramovsky, Eran Ben Elisha
In-Reply-To: <20160421133903.GA19633-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
On Thu, Apr 21, 2016 at 4:39 PM, Christoph Hellwig <hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org> wrote:
> On Thu, Apr 21, 2016 at 04:37:42PM +0300, Or Gerlitz wrote:
>> On Wed, Apr 20, 2016 at 9:40 PM, Eran Ben Elisha
>> <eranlinuxmellanox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> >> It is been 1.5 years since I reported the problem. We came up with three
>> >> different solutions this week. I'd like to see a version of the solution
>> >> to get merged until Mellanox comes up with a better solution with another
>> >> patch. My proposal is to use this one.
>>
>> > We will post our suggestion here in the following days.
>>
>> To update, Haggai A from our driver team is working on a patch. He is
>> providing a copy for
>> testing over ARM to the folks that reported on the problem and will
>> post it here early next week.
>
> Any chance you could give feedback to the patch I posted this week?
I missed your patch, looking on it now down this thread, I think
Haggai's patch is very much similar to yours, he's also touching some
more code in the IB driver.
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V2] net: ethernet: mellanox: correct page conversion
From: Christoph Hellwig @ 2016-04-21 13:39 UTC (permalink / raw)
To: Or Gerlitz
Cc: Linux Netdev List, Sinan Kaya, Christoph Hellwig,
linux-rdma@vger.kernel.org, timur, cov, Yishai Hadas,
Haggai Abramovsky, Eran Ben Elisha
In-Reply-To: <CAJ3xEMiZ-L5OSogx_3fTSOt-chvYJw6ANtbxYJi5TFR-_H4U-g@mail.gmail.com>
On Thu, Apr 21, 2016 at 04:37:42PM +0300, Or Gerlitz wrote:
> On Wed, Apr 20, 2016 at 9:40 PM, Eran Ben Elisha
> <eranlinuxmellanox@gmail.com> wrote:
> >> It is been 1.5 years since I reported the problem. We came up with three
> >> different solutions this week. I'd like to see a version of the solution
> >> to get merged until Mellanox comes up with a better solution with another
> >> patch. My proposal is to use this one.
>
> > We will post our suggestion here in the following days.
>
> To update, Haggai A from our driver team is working on a patch. He is
> providing a copy for
> testing over ARM to the folks that reported on the problem and will
> post it here early next week.
Any chance you could give feedback to the patch I posted this week?
^ permalink raw reply
* Re: [PATCH V2] net: ethernet: mellanox: correct page conversion
From: Or Gerlitz @ 2016-04-21 13:37 UTC (permalink / raw)
To: Linux Netdev List
Cc: Sinan Kaya, Christoph Hellwig,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
timur-sgV2jX0FEOL9JmXXK+q4OQ, cov-sgV2jX0FEOL9JmXXK+q4OQ,
Yishai Hadas, Haggai Abramovsky, Eran Ben Elisha
In-Reply-To: <CAKHjkjmYNLABO10V1DZQmZ_zczjbfDZU0TDPHoMmv_1FMi9_gA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Apr 20, 2016 at 9:40 PM, Eran Ben Elisha
<eranlinuxmellanox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> It is been 1.5 years since I reported the problem. We came up with three
>> different solutions this week. I'd like to see a version of the solution
>> to get merged until Mellanox comes up with a better solution with another
>> patch. My proposal is to use this one.
> We will post our suggestion here in the following days.
To update, Haggai A from our driver team is working on a patch. He is
providing a copy for
testing over ARM to the folks that reported on the problem and will
post it here early next week.
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: linux-next: zillions of lockdep whinges in include/net/sock.h:1408
From: Eric Dumazet @ 2016-04-21 13:31 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Hannes Frederic Sowa, David S. Miller, netdev, linux-kernel
In-Reply-To: <43037.1461229555@turing-police.cc.vt.edu>
On Thu, 2016-04-21 at 05:05 -0400, Valdis.Kletnieks@vt.edu wrote:
> On Thu, 21 Apr 2016 09:42:12 +0200, Hannes Frederic Sowa said:
> > Hi,
> >
> > On Thu, Apr 21, 2016, at 02:30, Valdis Kletnieks wrote:
> > > linux-next 20160420 is whining at an incredible rate - in 20 minutes of
> > > uptime, I piled up some 41,000 hits from all over the place (cleaned up
> > > to skip the CPU and PID so the list isn't quite so long):
> >
> > Thanks for the report. Can you give me some more details:
> >
> > Is this an nfs socket? Do you by accident know if this socket went
> > through xs_reclassify_socket at any point? We do hold the appropriate
> > locks at that point but I fear that the lockdep reinitialization
> > confused lockdep.
>
> It wasn't an NFS socket, as NFS wasn't even active at the time. I'm reasonably
> sure that multiple sockets were in play, given that tcp_v6_rcv and
> udpv6_queue_rcv_skb were both implicated. I strongly suspect that pretty much
> any IPv6 traffic could do it - the frequency dropped off quite a bit when I
> closed firefox, which is usually a heavy network hitter on my laptop.
Looks like the following patch is needed, can you try it please ?
Thanks !
diff --git a/include/net/sock.h b/include/net/sock.h
index d997ec13a643..db8301c76d50 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1350,7 +1350,8 @@ static inline bool lockdep_sock_is_held(const struct sock *csk)
{
struct sock *sk = (struct sock *)csk;
- return lockdep_is_held(&sk->sk_lock) ||
+ return !debug_locks ||
+ lockdep_is_held(&sk->sk_lock) ||
lockdep_is_held(&sk->sk_lock.slock);
}
#endif
^ permalink raw reply related
* Re: switchdev fib offload issues
From: Roopa Prabhu @ 2016-04-21 13:00 UTC (permalink / raw)
To: Hannes Frederic Sowa
Cc: Jiri Pirko, netdev, davem, idosch, eladr, yotamg, ogerlitz,
nikolay, jhs, john.fastabend, rami.rosen, gospo, stephen, sfeldma,
dsa, f.fainelli, andrew, vivien.didelot, tgraf, aduyck
In-Reply-To: <571516C7.6070301@stressinduktion.org>
On 4/18/16, 10:17 AM, Hannes Frederic Sowa wrote:
> Hi Jiri,
>
> On 18.04.2016 17:47, Jiri Pirko wrote:
>> Proposed solutions (ideas):
>> 1) per-netns. Add a procfs file:
>> /proc/sys/net/ipv4/route/fib_offload_error_policy
>> with values: "evict" - default, current behaviour
>> "fail" - propagate offload error to user
>> The policy value would be stored in struct net.
> >
>> 2) per-VRF/table
>> When user creates a VRF master, he specifies a table ID
>> this VRF is going to use. I propose to extend this so
>> he can pass a policy ("evict"/"fail").
>> The policy value would be stored in struct fib_table or
>> struct fib6_table. The problem is that vfr only saves
>> table ID, allocates dst but does not actually create
>> table. That might be created later. But I think this
>> could be resolved.
>>
>> 3) per-VFR/master_netdev
>> In this case, the policy would be also set during
>> the creation of VFR master. From user perspective,
>> this looks same as 2)
>> The policy value would be stored in struct net_vrf (vrf private).
>
> I agree that a fail policy is probably the way forward regarding the issues you outlined.
>
> One question though:
>
> Shouldn't the policy by an attribute of the switch, e.g. configurable by devlink (maybe also not the right place)? Not sure how user space can otherwise make correct assumptions about the state of the switch and initiate proper countermeasures (e.g. reducing the smallest prefix length installed to hardware).
>
I am with hannes here. If we introduce a policy, I think it should be global or per switchdev instance (possibly via devlink).
This would be a system policy (set via the administrator) and the user or app does not need to know about it.
^ permalink raw reply
* Re: [RFC PATCH] gro: Partly revert "net: gro: allow to build full sized skb"
From: Eric Dumazet @ 2016-04-21 12:59 UTC (permalink / raw)
To: Steffen Klassert; +Cc: Sowmini Varadhan, netdev
In-Reply-To: <20160421074042.GF3347@gauss.secunet.com>
On Thu, 2016-04-21 at 09:40 +0200, Steffen Klassert wrote:
> This partly reverts the below mentioned patch because on
> forwarding, such skbs can't be offloaded to a NIC.
>
> We need this to get IPsec GRO for forwarding to work properly,
> otherwise the GRO aggregated packets get segmented again by
> the GSO layer. Although discovered when implementing IPsec GRO,
> this is a general problem in the forwarding path.
>
> -------------------------------------------------------------------------
> commit 8a29111c7ca68d928dfab58636f3f6acf0ac04f7
> Author: Eric Dumazet <edumazet@google.com>
> Date: Tue Oct 8 09:02:23 2013 -0700
>
> net: gro: allow to build full sized skb
>
> skb_gro_receive() is currently limited to 16 or 17 MSS per GRO skb,
> typically 24616 bytes, because it fills up to MAX_SKB_FRAGS frags.
>
> It's relatively easy to extend the skb using frag_list to allow
> more frags to be appended into the last sk_buff.
>
> This still builds very efficient skbs, and allows reaching 45 MSS per
> skb.
>
> (45 MSS GRO packet uses one skb plus a frag_list containing 2 additional
> sk_buff)
>
> High speed TCP flows benefit from this extension by lowering TCP stack
> cpu usage (less packets stored in receive queue, less ACK packets
> processed)
>
> Forwarding setups could be hurt, as such skbs will need to be
> linearized, although its not a new problem, as GRO could already
> provide skbs with a frag_list.
>
> We could make the 65536 bytes threshold a tunable to mitigate this.
>
> (First time we need to linearize skb in skb_needs_linearize(), we could
> lower the tunable to ~16*1460 so that following skb_gro_receive() calls
> build smaller skbs)
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---------------------------------------------------------------------------
>
> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
> ---
>
> Hi Eric, this is a followup on our discussion at the netdev
> conference. Would you still be ok with this revert, or do
> you think there is a better solution in sight?
Note that some GRO enabled drivers would still generate frag_list.
(This happens if they are using skb with some TCP payload in skb->head
and skb->head was allocated with kmalloc())
We have sysctl_max_skb_frags sysctl, we might have a sysctl
enabling/disabling GRO from building any frag_list.
Or simply reuse an existing one, like /proc/sys/net/ipv4/ip_forward ?)
Here at Google, we increased MAX_SKB_FRAGS, but this is a rather
intrusive change to be upstreamed :(
^ permalink raw reply
* Re: rtl8xxxu: hide unused tables
From: Kalle Valo @ 2016-04-21 12:46 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Jes Sorensen, Arnd Bergmann, Jakub Sitnicki, linux-wireless,
netdev, linux-kernel
In-Reply-To: <1461016782-2640046-1-git-send-email-arnd@arndb.de>
> The references to some arrays in the rtl8xxxu driver were moved inside
> of an #ifdef, but the symbols remain outside, resulting in build warnings:
>
> rtl8xxxu/rtl8xxxu.c:1506:33: error: 'rtl8188ru_radioa_1t_highpa_table' defined but not used
> rtl8xxxu/rtl8xxxu.c:1431:33: error: 'rtl8192cu_radioa_1t_init_table' defined but not used
> rtl8xxxu/rtl8xxxu.c:1407:33: error: 'rtl8192cu_radiob_2t_init_table' defined but not used
> rtl8xxxu/rtl8xxxu.c:1332:33: error: 'rtl8192cu_radioa_2t_init_table' defined but not used
> rtl8xxxu/rtl8xxxu.c:239:35: error: 'rtl8192c_power_base' defined but not used
> rtl8xxxu/rtl8xxxu.c:217:35: error: 'rtl8188r_power_base' defined but not used
>
> This adds an extra #ifdef around them to shut up the warnings.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Fixes: 2fc0b8e5a17d ("rtl8xxxu: Add TX power base values for gen1 parts")
> Fixes: 4062b8ffec36 ("rtl8xxxu: Move PHY RF init into device specific functions")
Thanks, applied to wireless-drivers-next.git.
Kalle Valo
^ permalink raw reply
* Re: qdisc spin lock
From: Eric Dumazet @ 2016-04-21 12:41 UTC (permalink / raw)
To: Michael Ma; +Cc: Cong Wang, Linux Kernel Network Developers
In-Reply-To: <CAAmHdhy_foFw6udQnFk+KUNUjt+zCPRbq5QDBcw0gZ_-jmb4ow@mail.gmail.com>
On Wed, 2016-04-20 at 22:51 -0700, Michael Ma wrote:
> 2016-04-20 15:34 GMT-07:00 Eric Dumazet <eric.dumazet@gmail.com>:
> > On Wed, 2016-04-20 at 14:24 -0700, Michael Ma wrote:
> >> 2016-04-08 7:19 GMT-07:00 Eric Dumazet <eric.dumazet@gmail.com>:
> >> > On Thu, 2016-03-31 at 16:48 -0700, Michael Ma wrote:
> >> >> I didn't really know that multiple qdiscs can be isolated using MQ so
> >> >> that each txq can be associated with a particular qdisc. Also we don't
> >> >> really have multiple interfaces...
> >> >>
> >> >> With this MQ solution we'll still need to assign transmit queues to
> >> >> different classes by doing some math on the bandwidth limit if I
> >> >> understand correctly, which seems to be less convenient compared with
> >> >> a solution purely within HTB.
> >> >>
> >> >> I assume that with this solution I can still share qdisc among
> >> >> multiple transmit queues - please let me know if this is not the case.
> >> >
> >> > Note that this MQ + HTB thing works well, unless you use a bonding
> >> > device. (Or you need the MQ+HTB on the slaves, with no way of sharing
> >> > tokens between the slaves)
> >>
> >> Actually MQ+HTB works well for small packets - like flow of 512 byte
> >> packets can be throttled by HTB using one txq without being affected
> >> by other flows with small packets. However I found using this solution
> >> large packets (10k for example) will only achieve very limited
> >> bandwidth. In my test I used MQ to assign one txq to a HTB which sets
> >> rate at 1Gbit/s, 512 byte packets can achieve the ceiling rate by
> >> using 30 threads. But sending 10k packets using 10 threads has only 10
> >> Mbit/s with the same TC configuration. If I increase burst and cburst
> >> of HTB to some extreme large value (like 50MB) the ceiling rate can be
> >> hit.
> >>
> >> The strange thing is that I don't see this problem when using HTB as
> >> the root. So txq number seems to be a factor here - however it's
> >> really hard to understand why would it only affect larger packets. Is
> >> this a known issue? Any suggestion on how to investigate the issue
> >> further? Profiling shows that the cpu utilization is pretty low.
> >
> > You could try
> >
> > perf record -a -g -e skb:kfree_skb sleep 5
> > perf report
> >
> > So that you see where the packets are dropped.
> >
> > Chances are that your UDP sockets SO_SNDBUF is too big, and packets are
> > dropped at qdisc enqueue time, instead of having backpressure.
> >
>
> Thanks for the hint - how should I read the perf report? Also we're
> using TCP socket in this testing - TCP window size is set to 70kB.
But how are you telling TCP to send 10k packets ?
AFAIK you can not : TCP happily aggregates packets in write queue
(see current MSG_EOR discussion)
I suspect a bug in your tc settings.
^ permalink raw reply
* [PATCH iproute2] ss: add SK_MEMINFO_DROPS display
From: Eric Dumazet @ 2016-04-21 12:19 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
SK_MEMINFO_DROPS is added in linux-4.7 for TCP, UDP and SCTP
skmem will display the socket drop count using d prefix as in :
$ ss -tm src :22 | more
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 10.246.7.151:ssh 172.20.10.101:50759
skmem:(r0,rb8388608,t0,tb8388608,f1792,w2304,o0,bl0,d0)
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/sock_diag.h | 1 +
misc/ss.c | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index dafcb89..901231e 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -20,6 +20,7 @@ enum {
SK_MEMINFO_WMEM_QUEUED,
SK_MEMINFO_OPTMEM,
SK_MEMINFO_BACKLOG,
+ SK_MEMINFO_DROPS,
SK_MEMINFO_VARS,
};
diff --git a/misc/ss.c b/misc/ss.c
index deefc96..3258584 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1905,6 +1905,10 @@ static void print_skmeminfo(struct rtattr *tb[], int attrtype)
(SK_MEMINFO_BACKLOG + 1) * sizeof(__u32))
printf(",bl%u", skmeminfo[SK_MEMINFO_BACKLOG]);
+ if (RTA_PAYLOAD(tb[attrtype]) >=
+ (SK_MEMINFO_DROPS + 1) * sizeof(__u32))
+ printf(",d%u", skmeminfo[SK_MEMINFO_DROPS]);
+
printf(")");
}
^ permalink raw reply related
* [RFC][PATCH] net: stmmac: Call custom init from stmmac_dvr_probe
From: Marek Vasut @ 2016-04-21 12:12 UTC (permalink / raw)
To: netdev
Cc: peppe.cavallaro, alexandre.torgue, Marek Vasut, Maxime Ripard,
Chen-Yu Tsai, Matthew Gerlach, Dinh Nguyen, David S . Miller
Each and every driver which implements custom plat_data->init function
calls it exactly before stmmac_dvr_probe(). Trim down the code duplication
by calling the plat_data->init function from stmmac_dvr_probe() instead.
The stmmac_dvr_probe() does not have access to struct platform_device ,
since not all callers register the driver as a platform device. Analyzing
the ->init and ->exit functions, the platform_device is only used on in
one instance, on loongson, and only to access private data. Thus, replace
the platform device with net_device in both .init and .exit first and fix
up the code slightly to deal with this change.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Matthew Gerlach <mgerlach@opensource.altera.com>
Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
Cc: David S. Miller <davem@davemloft.net>
---
arch/blackfin/mach-bf609/boards/ezkit.c | 2 +-
arch/mips/loongson32/common/platform.c | 6 +++---
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 7 -------
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 8 ++------
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 15 +++------------
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 8 ++------
drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 8 ++------
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +++++++++++++
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 8 +++-----
include/linux/stmmac.h | 5 +++--
10 files changed, 32 insertions(+), 48 deletions(-)
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index aad5d74..3454fe2 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -122,7 +122,7 @@ static struct stmmac_dma_cfg eth_dma_cfg = {
.pbl = 2,
};
-int stmmac_ptp_clk_init(struct platform_device *pdev, void *priv)
+int stmmac_ptp_clk_init(struct net_device *ndev, void *priv)
{
bfin_write32(PADS0_EMAC_PTP_CLKSEL, 0);
return 0;
diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c
index f2c714d..e746df7 100644
--- a/arch/mips/loongson32/common/platform.c
+++ b/arch/mips/loongson32/common/platform.c
@@ -125,14 +125,14 @@ static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
.pbl = 1,
};
-int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
+int ls1x_eth_mux_init(struct net_device *ndev, void *priv)
{
- struct plat_stmmacenet_data *plat_dat = NULL;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ struct plat_stmmacenet_data *plat_dat = priv->plat;
u32 val;
val = __raw_readl(LS1X_MUX_CTRL1);
- plat_dat = dev_get_platdata(&pdev->dev);
if (plat_dat->bus_id) {
__raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
GMAC1_USE_UART0, LS1X_MUX_CTRL0);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index b1e5f24..3107a71 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -46,13 +46,6 @@ static int dwmac_generic_probe(struct platform_device *pdev)
plat_dat->unicast_filter_entries = 1;
}
- /* Custom initialisation (if needed) */
- if (plat_dat->init) {
- ret = plat_dat->init(pdev, plat_dat->bsp_priv);
- if (ret)
- return ret;
- }
-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 0cd3ecf..3b5a59d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -529,7 +529,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
return bsp_priv;
}
-static int rk_gmac_init(struct platform_device *pdev, void *priv)
+static int rk_gmac_init(struct net_device *ndev, void *priv)
{
struct rk_priv_data *bsp_priv = priv;
int ret;
@@ -545,7 +545,7 @@ static int rk_gmac_init(struct platform_device *pdev, void *priv)
return 0;
}
-static void rk_gmac_exit(struct platform_device *pdev, void *priv)
+static void rk_gmac_exit(struct net_device *ndev, void *priv)
{
struct rk_priv_data *gmac = priv;
@@ -596,10 +596,6 @@ static int rk_gmac_probe(struct platform_device *pdev)
if (IS_ERR(plat_dat->bsp_priv))
return PTR_ERR(plat_dat->bsp_priv);
- ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
- if (ret)
- return ret;
-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 784eb53..97f5615 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -184,17 +184,12 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
return 0;
}
-static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
+static int socfpga_dwmac_init(struct net_device *ndev, void *priv)
{
struct socfpga_dwmac *dwmac = priv;
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct stmmac_priv *stpriv = NULL;
+ struct stmmac_priv *stpriv = netdev_priv(ndev);
int ret = 0;
- if (!ndev)
- return -EINVAL;
-
- stpriv = netdev_priv(ndev);
if (!stpriv)
return -EINVAL;
@@ -264,11 +259,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
plat_dat->init = socfpga_dwmac_init;
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
- ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- if (!ret)
- ret = socfpga_dwmac_init(pdev, dwmac);
-
- return ret;
+ return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}
static const struct of_device_id socfpga_dwmac_match[] = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 58c05ac..049d1dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -228,7 +228,7 @@ static void stid127_fix_retime_src(void *priv, u32 spd)
regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
}
-static int sti_dwmac_init(struct platform_device *pdev, void *priv)
+static int sti_dwmac_init(struct net_device *ndev, void *priv)
{
struct sti_dwmac *dwmac = priv;
struct regmap *regmap = dwmac->regmap;
@@ -254,7 +254,7 @@ static int sti_dwmac_init(struct platform_device *pdev, void *priv)
return 0;
}
-static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
+static void sti_dwmac_exit(struct net_device *ndev, void *priv)
{
struct sti_dwmac *dwmac = priv;
@@ -361,10 +361,6 @@ static int sti_dwmac_probe(struct platform_device *pdev)
plat_dat->exit = sti_dwmac_exit;
plat_dat->fix_mac_speed = data->fix_retime_src;
- ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
- if (ret)
- return ret;
-
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index adff463..5a21574 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -36,7 +36,7 @@ struct sunxi_priv_data {
#define SUN7I_GMAC_GMII_RGMII_RATE 125000000
#define SUN7I_GMAC_MII_RATE 25000000
-static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
+static int sun7i_gmac_init(struct net_device *ndev, void *priv)
{
struct sunxi_priv_data *gmac = priv;
int ret;
@@ -65,7 +65,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
return 0;
}
-static void sun7i_gmac_exit(struct platform_device *pdev, void *priv)
+static void sun7i_gmac_exit(struct net_device *ndev, void *priv)
{
struct sunxi_priv_data *gmac = priv;
@@ -149,10 +149,6 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
plat_dat->exit = sun7i_gmac_exit;
plat_dat->fix_mac_speed = sun7i_fix_speed;
- ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
- if (ret)
- return ret;
-
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b87edb7..a62cbe31 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3260,6 +3260,13 @@ int stmmac_dvr_probe(struct device *device,
if (priv->stmmac_rst)
reset_control_deassert(priv->stmmac_rst);
+ /* Custom initialisation (if needed) */
+ if (plat_dat->init) {
+ ret = plat_dat->init(ndev, plat_dat->bsp_priv);
+ if (ret)
+ return ret;
+ }
+
/* Init MAC and get the capabilities */
ret = stmmac_hw_init(priv);
if (ret)
@@ -3357,6 +3364,7 @@ EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
int stmmac_dvr_remove(struct net_device *ndev)
{
struct stmmac_priv *priv = netdev_priv(ndev);
+ struct plat_stmmacenet_data *plat_dat = priv->plat;
pr_info("%s:\n\tremoving driver", __func__);
@@ -3366,6 +3374,11 @@ int stmmac_dvr_remove(struct net_device *ndev)
stmmac_set_mac(priv->ioaddr, false);
netif_carrier_off(ndev);
unregister_netdev(ndev);
+
+ /* Custom de-initialisation (if needed) */
+ if (plat_dat->exit)
+ plat_dat->exit(ndev, plat_dat->bsp_priv);
+
if (priv->stmmac_rst)
reset_control_assert(priv->stmmac_rst);
clk_disable_unprepare(priv->pclk);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index effaa4f..7473433 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -389,7 +389,7 @@ int stmmac_pltfr_remove(struct platform_device *pdev)
int ret = stmmac_dvr_remove(ndev);
if (priv->plat->exit)
- priv->plat->exit(pdev, priv->plat->bsp_priv);
+ priv->plat->exit(ndev, priv->plat->bsp_priv);
return ret;
}
@@ -408,11 +408,10 @@ static int stmmac_pltfr_suspend(struct device *dev)
int ret;
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
- struct platform_device *pdev = to_platform_device(dev);
ret = stmmac_suspend(ndev);
if (priv->plat->exit)
- priv->plat->exit(pdev, priv->plat->bsp_priv);
+ priv->plat->exit(ndev, priv->plat->bsp_priv);
return ret;
}
@@ -428,10 +427,9 @@ static int stmmac_pltfr_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
- struct platform_device *pdev = to_platform_device(dev);
if (priv->plat->init)
- priv->plat->init(pdev, priv->plat->bsp_priv);
+ priv->plat->init(ndev, priv->plat->bsp_priv);
return stmmac_resume(ndev);
}
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index ffdaca9..ddd4342 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -27,6 +27,7 @@
#define __STMMAC_PLATFORM_DATA
#include <linux/platform_device.h>
+#include <linux/netdevice.h>
#define STMMAC_RX_COE_NONE 0
#define STMMAC_RX_COE_TYPE1 1
@@ -133,8 +134,8 @@ struct plat_stmmacenet_data {
int rx_fifo_size;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void (*bus_setup)(void __iomem *ioaddr);
- int (*init)(struct platform_device *pdev, void *priv);
- void (*exit)(struct platform_device *pdev, void *priv);
+ int (*init)(struct net_device *ndev, void *priv);
+ void (*exit)(struct net_device *ndev, void *priv);
void *bsp_priv;
struct stmmac_axi *axi;
int has_gmac4;
--
2.7.0
^ permalink raw reply related
* [PATCH V3] net: stmmac: socfpga: Remove re-registration of reset controller
From: Marek Vasut @ 2016-04-21 12:11 UTC (permalink / raw)
To: netdev
Cc: peppe.cavallaro, alexandre.torgue, Marek Vasut, Matthew Gerlach,
Dinh Nguyen, David S . Miller
Both socfpga_dwmac_parse_data() in dwmac-socfpga.c and stmmac_dvr_probe()
in stmmac_main.c functions call devm_reset_control_get() to register an
reset controller for the stmmac. This results in an attempt to register
two reset controllers for the same non-shared reset line.
The first attempt to register the reset controller works fine. The second
attempt fails with warning from the reset controller core, see below.
The warning is produced because the reset line is non-shared and thus
it is allowed to have only up-to one reset controller associated with
that reset line, not two or more.
The solution has multiple parts. First, the original socfpga_dwmac_init()
is tweaked to use reset controller pointer from the stmmac_priv (private
data of the stmmac core) instead of the local instance, which was used
before. The local re-registration of the reset controller is removed.
Next, the socfpga_dwmac_init() is moved after stmmac_dvr_probe() in the
probe function. This order is legal according to Altera and it makes the
code much easier, since there is no need to temporarily register and
unregister the reset controller ; the reset controller is already registered
by the stmmac_dvr_probe().
Finally, plat_dat->exit and socfpga_dwmac_exit() is no longer necessary,
since the functionality is already performed by the stmmac core.
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1 at drivers/reset/core.c:187 __of_reset_control_get+0x218/0x270
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc4-next-20160419-00015-gabb2477-dirty #4
Hardware name: Altera SOCFPGA
[<c010f290>] (unwind_backtrace) from [<c010b82c>] (show_stack+0x10/0x14)
[<c010b82c>] (show_stack) from [<c0373da4>] (dump_stack+0x94/0xa8)
[<c0373da4>] (dump_stack) from [<c011bcc0>] (__warn+0xec/0x104)
[<c011bcc0>] (__warn) from [<c011bd88>] (warn_slowpath_null+0x20/0x28)
[<c011bd88>] (warn_slowpath_null) from [<c03a6eb4>] (__of_reset_control_get+0x218/0x270)
[<c03a6eb4>] (__of_reset_control_get) from [<c03a701c>] (__devm_reset_control_get+0x54/0x90)
[<c03a701c>] (__devm_reset_control_get) from [<c041fa30>] (stmmac_dvr_probe+0x1b4/0x8e8)
[<c041fa30>] (stmmac_dvr_probe) from [<c04298c8>] (socfpga_dwmac_probe+0x1b8/0x28c)
[<c04298c8>] (socfpga_dwmac_probe) from [<c03d6ffc>] (platform_drv_probe+0x4c/0xb0)
[<c03d6ffc>] (platform_drv_probe) from [<c03d54ec>] (driver_probe_device+0x224/0x2bc)
[<c03d54ec>] (driver_probe_device) from [<c03d5630>] (__driver_attach+0xac/0xb0)
[<c03d5630>] (__driver_attach) from [<c03d382c>] (bus_for_each_dev+0x6c/0xa0)
[<c03d382c>] (bus_for_each_dev) from [<c03d4ad4>] (bus_add_driver+0x1a4/0x21c)
[<c03d4ad4>] (bus_add_driver) from [<c03d60ac>] (driver_register+0x78/0xf8)
[<c03d60ac>] (driver_register) from [<c0101760>] (do_one_initcall+0x40/0x170)
[<c0101760>] (do_one_initcall) from [<c0800e38>] (kernel_init_freeable+0x1dc/0x27c)
[<c0800e38>] (kernel_init_freeable) from [<c05d1bd4>] (kernel_init+0x8/0x114)
[<c05d1bd4>] (kernel_init) from [<c01076f8>] (ret_from_fork+0x14/0x3c)
---[ end trace 059d2fbe87608fa9 ]---
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Matthew Gerlach <mgerlach@opensource.altera.com>
Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
Cc: David S. Miller <davem@davemloft.net>
---
V2: Add missing stmmac_rst = NULL; into socfpga_dwmac_init_probe()
V3: Greatly simplify the code by moving socfpga_dwmac_init() after
stmmac_dvr_probe(), which is legal. This removes the need for
temporary registration of the reset controller, which is super.
---
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 50 +++++++---------------
1 file changed, 16 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 76d671e..784eb53 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -49,7 +49,6 @@ struct socfpga_dwmac {
u32 reg_shift;
struct device *dev;
struct regmap *sys_mgr_base_addr;
- struct reset_control *stmmac_rst;
void __iomem *splitter_base;
bool f2h_ptp_ref_clk;
};
@@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
struct device_node *np_splitter;
struct resource res_splitter;
- dwmac->stmmac_rst = devm_reset_control_get(dev,
- STMMAC_RESOURCE_NAME);
- if (IS_ERR(dwmac->stmmac_rst)) {
- dev_info(dev, "Could not get reset control!\n");
- if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- dwmac->stmmac_rst = NULL;
- }
-
dwmac->interface = of_get_phy_mode(np);
sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
@@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
return 0;
}
-static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
-{
- struct socfpga_dwmac *dwmac = priv;
-
- /* On socfpga platform exit, assert and hold reset to the
- * enet controller - the default state after a hard reset.
- */
- if (dwmac->stmmac_rst)
- reset_control_assert(dwmac->stmmac_rst);
-}
-
static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
{
- struct socfpga_dwmac *dwmac = priv;
+ struct socfpga_dwmac *dwmac = priv;
struct net_device *ndev = platform_get_drvdata(pdev);
struct stmmac_priv *stpriv = NULL;
int ret = 0;
- if (ndev)
- stpriv = netdev_priv(ndev);
+ if (!ndev)
+ return -EINVAL;
+
+ stpriv = netdev_priv(ndev);
+ if (!stpriv)
+ return -EINVAL;
/* Assert reset to the enet controller before changing the phy mode */
- if (dwmac->stmmac_rst)
- reset_control_assert(dwmac->stmmac_rst);
+ if (stpriv->stmmac_rst)
+ reset_control_assert(stpriv->stmmac_rst);
/* Setup the phy mode in the system manager registers according to
* devicetree configuration
@@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
/* Deassert reset for the phy configuration to be sampled by
* the enet controller, and operation to start in requested mode
*/
- if (dwmac->stmmac_rst)
- reset_control_deassert(dwmac->stmmac_rst);
+ if (stpriv->stmmac_rst)
+ reset_control_deassert(stpriv->stmmac_rst);
/* Before the enet controller is suspended, the phy is suspended.
* This causes the phy clock to be gated. The enet controller is
@@ -245,7 +228,7 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
* control register 0, and can be modified by the phy driver
* framework.
*/
- if (stpriv && stpriv->phydev)
+ if (stpriv->phydev)
phy_resume(stpriv->phydev);
return ret;
@@ -279,14 +262,13 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
plat_dat->bsp_priv = dwmac;
plat_dat->init = socfpga_dwmac_init;
- plat_dat->exit = socfpga_dwmac_exit;
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
- ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv);
- if (ret)
- return ret;
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (!ret)
+ ret = socfpga_dwmac_init(pdev, dwmac);
- return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ return ret;
}
static const struct of_device_id socfpga_dwmac_match[] = {
--
2.7.0
^ permalink raw reply related
* Re: bridge not learning from locally sent gratuitous ARP?
From: Toshiaki Makita @ 2016-04-21 11:58 UTC (permalink / raw)
To: Patrick Schaaf; +Cc: netdev
In-Reply-To: <CAJ26g5T65eXWBQBZzRb=hzr+29dUUnWxfN=GUu=ouQJVKZiVGQ@mail.gmail.com>
> So, assuming that proives stable, I have a workaround - but one that
> needs knowlege of A) the unterlying interface (brport) to fondle, and
> B) the macvlan MAC address that needs adding. keepalived couldn't
> easily do that "in code" because it does not know what sits under the
> bridge.
>
> Naive question: shouldn't that work automatically, i.e. macvlan when
> sitting on to of a bridge, doing that internally?
I'll think of this, thank you.
Toshiaki Makita
^ permalink raw reply
* Re: [PATCH V2] net: stmmac: socfpga: Remove re-registration of reset controller
From: Marek Vasut @ 2016-04-21 11:51 UTC (permalink / raw)
To: Dinh Nguyen, netdev
Cc: peppe.cavallaro, alexandre.torgue, Matthew Gerlach,
David S . Miller
In-Reply-To: <57183E7B.5050804@opensource.altera.com>
On 04/21/2016 04:44 AM, Dinh Nguyen wrote:
>
>
> On 04/20/2016 05:27 PM, Marek Vasut wrote:
>> On 04/20/2016 11:17 PM, Dinh Nguyen wrote:
>>> On 04/19/2016 07:05 PM, Marek Vasut wrote:
>>>> Both socfpga_dwmac_parse_data() in dwmac-socfpga.c and stmmac_dvr_probe()
>>>> in stmmac_main.c functions call devm_reset_control_get() to register an
>>>> reset controller for the stmmac. This results in an attempt to register
>>>> two reset controllers for the same non-shared reset line.
>>>>
>>>> The first attempt to register the reset controller works fine. The second
>>>> attempt fails with warning from the reset controller core, see below.
>>>> The warning is produced because the reset line is non-shared and thus
>>>> it is allowed to have only up-to one reset controller associated with
>>>> that reset line, not two or more.
>>>>
>>>> The solution is not great. Since the hardware needs to toggle the reset
>>>> before calling stmmac_dvr_probe() to perform mandatory preconfiguration,
>>>> this patch splits socfpga_dwmac_init_probe() from socfpga_dwmac_init().
>>>>
>>>> The socfpga_dwmac_init_probe() temporarily registers the reset controller,
>>>> performs the pre-configuration and unregisters the reset controller again.
>>>> This function is only called from the socfpga_dwmac_probe().
>>>>
>>>> The original socfpga_dwmac_init() is tweaked to use reset controller
>>>> pointer from the stmmac_priv (private data of the stmmac core) instead
>>>> of the local instance, which was used before.
>>>>
>>>> Finally, plat_dat->exit and socfpga_dwmac_exit() is no longer necessary,
>>>> since the functionality is already performed by the stmmac core.
>>>>
>>>> ------------[ cut here ]------------
>>>> WARNING: CPU: 0 PID: 1 at drivers/reset/core.c:187 __of_reset_control_get+0x218/0x270
>>>> Modules linked in:
>>>> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc4-next-20160419-00015-gabb2477-dirty #4
>>>> Hardware name: Altera SOCFPGA
>>>> [<c010f290>] (unwind_backtrace) from [<c010b82c>] (show_stack+0x10/0x14)
>>>> [<c010b82c>] (show_stack) from [<c0373da4>] (dump_stack+0x94/0xa8)
>>>> [<c0373da4>] (dump_stack) from [<c011bcc0>] (__warn+0xec/0x104)
>>>> [<c011bcc0>] (__warn) from [<c011bd88>] (warn_slowpath_null+0x20/0x28)
>>>> [<c011bd88>] (warn_slowpath_null) from [<c03a6eb4>] (__of_reset_control_get+0x218/0x270)
>>>> [<c03a6eb4>] (__of_reset_control_get) from [<c03a701c>] (__devm_reset_control_get+0x54/0x90)
>>>> [<c03a701c>] (__devm_reset_control_get) from [<c041fa30>] (stmmac_dvr_probe+0x1b4/0x8e8)
>>>> [<c041fa30>] (stmmac_dvr_probe) from [<c04298c8>] (socfpga_dwmac_probe+0x1b8/0x28c)
>>>> [<c04298c8>] (socfpga_dwmac_probe) from [<c03d6ffc>] (platform_drv_probe+0x4c/0xb0)
>>>> [<c03d6ffc>] (platform_drv_probe) from [<c03d54ec>] (driver_probe_device+0x224/0x2bc)
>>>> [<c03d54ec>] (driver_probe_device) from [<c03d5630>] (__driver_attach+0xac/0xb0)
>>>> [<c03d5630>] (__driver_attach) from [<c03d382c>] (bus_for_each_dev+0x6c/0xa0)
>>>> [<c03d382c>] (bus_for_each_dev) from [<c03d4ad4>] (bus_add_driver+0x1a4/0x21c)
>>>> [<c03d4ad4>] (bus_add_driver) from [<c03d60ac>] (driver_register+0x78/0xf8)
>>>> [<c03d60ac>] (driver_register) from [<c0101760>] (do_one_initcall+0x40/0x170)
>>>> [<c0101760>] (do_one_initcall) from [<c0800e38>] (kernel_init_freeable+0x1dc/0x27c)
>>>> [<c0800e38>] (kernel_init_freeable) from [<c05d1bd4>] (kernel_init+0x8/0x114)
>>>> [<c05d1bd4>] (kernel_init) from [<c01076f8>] (ret_from_fork+0x14/0x3c)
>>>> ---[ end trace 059d2fbe87608fa9 ]---
>>>>
>>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>>> Cc: Matthew Gerlach <mgerlach@opensource.altera.com>
>>>> Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
>>>> Cc: David S. Miller <davem@davemloft.net>
>>>> ---
>>>> V2: Add missing stmmac_rst = NULL; into socfpga_dwmac_init_probe()
>>>> ---
>>>> .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 70 ++++++++++++----------
>>>> 1 file changed, 39 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
>>>> index 76d671e..5885a2e 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
>>>> @@ -49,7 +49,6 @@ struct socfpga_dwmac {
>>>> u32 reg_shift;
>>>> struct device *dev;
>>>> struct regmap *sys_mgr_base_addr;
>>>> - struct reset_control *stmmac_rst;
>>>> void __iomem *splitter_base;
>>>> bool f2h_ptp_ref_clk;
>>>> };
>>>> @@ -92,15 +91,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
>>>> struct device_node *np_splitter;
>>>> struct resource res_splitter;
>>>>
>>>> - dwmac->stmmac_rst = devm_reset_control_get(dev,
>>>> - STMMAC_RESOURCE_NAME);
>>>> - if (IS_ERR(dwmac->stmmac_rst)) {
>>>> - dev_info(dev, "Could not get reset control!\n");
>>>> - if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER)
>>>> - return -EPROBE_DEFER;
>>>> - dwmac->stmmac_rst = NULL;
>>>> - }
>>>> -
>>>> dwmac->interface = of_get_phy_mode(np);
>>>>
>>>> sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
>>>> @@ -194,30 +184,23 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
>>>> return 0;
>>>> }
>>>>
>>>> -static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
>>>> -{
>>>> - struct socfpga_dwmac *dwmac = priv;
>>>> -
>>>> - /* On socfpga platform exit, assert and hold reset to the
>>>> - * enet controller - the default state after a hard reset.
>>>> - */
>>>> - if (dwmac->stmmac_rst)
>>>> - reset_control_assert(dwmac->stmmac_rst);
>>>> -}
>>>> -
>>>> static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>> {
>>>> - struct socfpga_dwmac *dwmac = priv;
>>>> + struct socfpga_dwmac *dwmac = priv;
>>>> struct net_device *ndev = platform_get_drvdata(pdev);
>>>> struct stmmac_priv *stpriv = NULL;
>>>> int ret = 0;
>>>>
>>>> - if (ndev)
>>>> - stpriv = netdev_priv(ndev);
>>>> + if (!ndev)
>>>> + return -EINVAL;
>>>> +
>>>> + stpriv = netdev_priv(ndev);
>>>> + if (!stpriv)
>>>> + return -EINVAL;
>>>>
>>>> /* Assert reset to the enet controller before changing the phy mode */
>>>> - if (dwmac->stmmac_rst)
>>>> - reset_control_assert(dwmac->stmmac_rst);
>>>> + if (stpriv->stmmac_rst)
>>>> + reset_control_assert(stpriv->stmmac_rst);
>>>>
>>>> /* Setup the phy mode in the system manager registers according to
>>>> * devicetree configuration
>>>> @@ -227,8 +210,8 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>> /* Deassert reset for the phy configuration to be sampled by
>>>> * the enet controller, and operation to start in requested mode
>>>> */
>>>> - if (dwmac->stmmac_rst)
>>>> - reset_control_deassert(dwmac->stmmac_rst);
>>>> + if (stpriv->stmmac_rst)
>>>> + reset_control_deassert(stpriv->stmmac_rst);
>>>>
>>>> /* Before the enet controller is suspended, the phy is suspended.
>>>> * This causes the phy clock to be gated. The enet controller is
>>>> @@ -245,12 +228,38 @@ static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
>>>> * control register 0, and can be modified by the phy driver
>>>> * framework.
>>>> */
>>>> - if (stpriv && stpriv->phydev)
>>>> + if (stpriv->phydev)
>>>> phy_resume(stpriv->phydev);
>>>>
>>>> return ret;
>>>> }
>>>>
>>>> +static int socfpga_dwmac_init_probe(struct socfpga_dwmac *dwmac)
>>>> +{
>>>> + struct reset_control *stmmac_rst;
>>>> + int ret;
>>>> +
>>>> + stmmac_rst = reset_control_get(dwmac->dev, STMMAC_RESOURCE_NAME);
>>>> + if (IS_ERR(stmmac_rst)) {
>>>> + dev_info(dwmac->dev, "Could not get reset control!\n");
>>>> + if (PTR_ERR(stmmac_rst) == -EPROBE_DEFER)
>>>> + return -EPROBE_DEFER;
>>>> + stmmac_rst = NULL;
>>>> + }
>>>> +
>>>> + if (stmmac_rst)
>>>> + reset_control_assert(stmmac_rst);
>>>> +
>>>> + ret = socfpga_dwmac_setup(dwmac);
>>>> +
>>>> + if (stmmac_rst) {
>>>> + reset_control_deassert(stmmac_rst);
>>>> + reset_control_put(stmmac_rst);
>>>> + }
>>>> +
>>>> + return ret;
>>>> +}
>>>
>>> I don't think you this function because...
>>>
>>>> +
>>>> static int socfpga_dwmac_probe(struct platform_device *pdev)
>>>> {
>>>> struct plat_stmmacenet_data *plat_dat;
>>>> @@ -279,10 +288,9 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
>>>>
>>>> plat_dat->bsp_priv = dwmac;
>>>> plat_dat->init = socfpga_dwmac_init;
>>>> - plat_dat->exit = socfpga_dwmac_exit;
>>>> plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
>>>>
>>>> - ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv);
>>>> + ret = socfpga_dwmac_init_probe(dwmac);
>>>> if (ret)
>>>> return ret;
>>>>
>>>>
>>>
>>> if you modify the patch to call stmmac_dvr_probe() before calling
>>> socfpga_dwmac_init(), then you would already have the reset control
>>> information.
>>
>> I was under the impression that you must call socfpga_dwmac_init()
>> before stmmac_dvr_probe() for whatever hardware-related reason. If
>> you are absolutely certain this is not necessary, then that's just
>> perfect and the patch can be simplified even further -- just remove
>> the call to socfpga_dwmac_init() from probe altogether , the dwmac
>> core code will call plat_dat->init at the end of probe .
>>
>> So shall we do that ? I am happy to spin V3 like that if you confirm
>> that it's legal to do things in the aforementioned order.
>>
>
> AFAICT, I don't see any reason why the socfpga_dwmac_init() has to go
> before the stmmac_dvr_probe(). I tested this by using U-Boot to put the
> PHY modes in the system manager into a different mode, and put the
> ethernet IP into reset. Linux was able to use ethernet just fine with
> the aformentioned order.
Ha, the dwmac code does not call the ->init, so you have to call it from
the socfpga-dwmac probe afterall. I will send a V3 now and do
it just like you suggested. I will send a RFC for calling ->init and
->exit from the stmmac common code too.
> So yes, please spin V3.
>
> Thanks,
> Dinh
>
--
Best regards,
Marek Vasut
^ permalink raw reply
* Re: bridge not learning from locally sent gratuitous ARP?
From: Patrick Schaaf @ 2016-04-21 11:32 UTC (permalink / raw)
To: Toshiaki Makita; +Cc: netdev
In-Reply-To: <5718AC0A.8090009@lab.ntt.co.jp>
On Thu, Apr 21, 2016 at 12:31 PM, Toshiaki Makita
<makita.toshiaki@lab.ntt.co.jp> wrote:
> On 2016/04/21 15:37, Patrick Schaaf wrote:
> (I understand the problem happens only if you use macvlan on the bridge device. If wrong, correct me.)
That is my understanding, yes. That macvlan device is created by
keepalived, which I use for VRRP, via its use_vmac + vmac_xmit_base
settings.
> Please use "bridge fdb show" instead of "brctl showmacs". brctl is an
> old tool and has limitation in showing fdb entries.
Learn a new thing every day! Thanks, that's good to know.
> I guess your bridge doesn't have the mac address of the macvlan device
> in its fdb. If you can confirm that by bridge command, then add an entry
> by hand.
>
> # bridge fdb add <addr of macvlan> dev <brport> master
> <brport> can be any device that belongs to the bridge.
> This command (without "temp" option) installs an fdb entry that forwards
> frames to the bridge device.
The "bridge" command operates solely on bridge ports (not on the
bridge itself), as far as I can see. Checking the member interfaces,
indeed I cannot find an entry for the macvlan interface VMAC.
The macvlan interface itself is NOT a brport.
So I add that permanent entry to the underlying ethernet link of that bridge.
Seems to work - I can still ping the virtual IP address behind that
VMAC, so the macvlan interface continues to do what it should - and
running tcpdump on the tap brport to openvpn, I see these test pings
when the fdb entry has not been set, but I no longer see them after
the bridge fdb add.
So, assuming that proives stable, I have a workaround - but one that
needs knowlege of A) the unterlying interface (brport) to fondle, and
B) the macvlan MAC address that needs adding. keepalived couldn't
easily do that "in code" because it does not know what sits under the
bridge.
Naive question: shouldn't that work automatically, i.e. macvlan when
sitting on to of a bridge, doing that internally?
Anyway, thanks for the pointers to the workaround, much appreciated!
best regards
Patrick
^ permalink raw reply
* Re: bridge not learning from locally sent gratuitous ARP?
From: Toshiaki Makita @ 2016-04-21 10:31 UTC (permalink / raw)
To: Patrick Schaaf, netdev
In-Reply-To: <CAJ26g5SKzs=+0MmanfC4Hfuti_jLo5R=e6T6imNc98rXVsA1ug@mail.gmail.com>
On 2016/04/21 15:37, Patrick Schaaf wrote:
> Dear netdev,
Hi,
>
> I've got a peculiar issue, and hope for clarification / workarounds here.
>
> Scenario:
> - a bridge interface br0, over some ethernet base
> - a macvlan interface br0-vrrp on top, set up by keepalived, with VRRP VMAC
> - keepalived regularly sending gratuitous ARP with that VRRP VMAC
> - (new) an additional tap interface in br0, for an openvpn link
>
> In principle, everything is working fine. The base keepalived setup
> has been in operation for a long time, running directly over a VLAN
> interface. The conversion to a bridge interface is also working
> without any issues by itself. The additional tap to openvpn, and the
> VPN setup it realizes, is also working fine, in principle...
>
> Issue:
> - openvpn runs at 100% CPU ....
> - because it it sent all packets destined to the VRRP VMAC
> - because that VMAC is not in the br0 learned MAC address table (brctl showmacs)
> - thus the (production webserver outbound...) traffic is flooded to
> all br0 ports
>
> Diagnosis I did so far:
> - with tcpdump, verified that I can see the gratuitous ARPs on both the macvlan
> and bridge interface.
> - verified that "brctl showmacs" does not contain the VRRP VMAC
> - identical setup for a different VLAN with almost no traffic to the
> VMAC, has openvpn running without the huge CPU consumption
> - straced the openvpn daemon with the issue, seeing the packet rate
> expected as tap reads / sends to the remote site
>
> Kernel:
> 3.14.48 (vanilla)
> keepalived 1.2.13 (with repeated gratuitous ARP support patched in)
>
> Can anybody shed a light on how to cope with this issue?
(I understand the problem happens only if you use macvlan on the bridge
device. If wrong, correct me.)
Please use "bridge fdb show" instead of "brctl showmacs". brctl is an
old tool and has limitation in showing fdb entries.
I guess your bridge doesn't have the mac address of the macvlan device
in its fdb. If you can confirm that by bridge command, then add an entry
by hand.
# bridge fdb add <addr of macvlan> dev <brport> master
<brport> can be any device that belongs to the bridge.
This command (without "temp" option) installs an fdb entry that forwards
frames to the bridge device.
Some more analysis:
- bridge adds the fdb entry of br0 mac address permanently. bridge never
learns source mac addresses of frames sent from br0.
- bridge seems not to have an ability to propagate the mac address of
its upper device into fdb.
- vlan device has the same mac address as its real device by default, so
it does not cause the problem.
--
Toshiaki Makita
^ permalink raw reply
* Re: [PATCH v2] MAINTAINERS: net: add entry for TI Ethernet Switch drivers
From: Mugunthan V N @ 2016-04-21 11:18 UTC (permalink / raw)
To: Grygorii Strashko, netdev, linux-kernel, David S. Miller
Cc: Sekhar Nori, linux-omap, Tony Lindgren, Richard Cochran
In-Reply-To: <1461233636-18667-1-git-send-email-grygorii.strashko@ti.com>
On Thursday 21 April 2016 03:43 PM, Grygorii Strashko wrote:
> Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW
> (am33/am43/am57/dr7/davinci) to ensure that related patches
> will go through dedicated linux-omap list.
>
> Also add Mugunthan as maintainer and myself as the reviewer.
>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> Cc: Richard Cochran <richardcochran@gmail.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Regards
Mugunthan V N
^ permalink raw reply
* Re: [PATCHv2] wlcore: spi: add wl18xx support
From: Mark Brown @ 2016-04-21 11:11 UTC (permalink / raw)
To: Reizer, Eyal
Cc: kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
���� �����,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <8665E2433BC68541A24DFFCA87B70F5B360C2E14-1tpBd5JUCm6IQmiDNMet8wC/G2K4zDHf@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 856 bytes --]
On Thu, Apr 21, 2016 at 11:07:37AM +0000, Reizer, Eyal wrote:
> * (i) If the transfer isn't the last one in the message, this flag is
> * used to make the chipselect briefly go inactive in the middle of the
> * message. Toggling chipselect in this way may be needed to terminate
> * a chip command, letting a single spi_message perform all of group of
> * chip transactions together.
> Now, in my case I need the CS pin to go inactive and stay inactive during the transfer
> of the next byte for completing the SPI init correctly (sending the extra clock cycles while CS is inactive)
> If I read the above correctly, CS will only briefly go inactive but will when the next byte
> is sent it will be active again.
> What am I missing?
No, it changes the state. The main use case is a brief bounce but
you can use it for other things.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply
* RE: [PATCHv2] wlcore: spi: add wl18xx support
From: Reizer, Eyal @ 2016-04-21 11:07 UTC (permalink / raw)
To: Mark Brown
Cc: kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
���� �����,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20160419184627.GG3217-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
>
> > Thanks! Glad the illustration helped.
> > I will try it out again as if i recall cotrectly, i did try that l, and it didnt produce
> the correct waveform, but perhaps i didnt understand the usage of
> .cs_change correctly.
> > Will double check anyway.
>
> It could also be a bug in your controller driver, it's common for them to not
> handle cs_change correctly (at least those that open code the message loop,
> obviously modern ones just factor this out into the core).
Tried looking into using cs_change and not sure I understand how it would do what I need.
According to, include/linux/spi/spi.h:
* All SPI transfers start with the relevant chipselect active. Normally
* it stays selected until after the last transfer in a message. Drivers
* can affect the chipselect signal using cs_change.
*
* (i) If the transfer isn't the last one in the message, this flag is
* used to make the chipselect briefly go inactive in the middle of the
* message. Toggling chipselect in this way may be needed to terminate
* a chip command, letting a single spi_message perform all of group of
* chip transactions together.
Now, in my case I need the CS pin to go inactive and stay inactive during the transfer
of the next byte for completing the SPI init correctly (sending the extra clock cycles while CS is inactive)
If I read the above correctly, CS will only briefly go inactive but will when the next byte
is sent it will be active again.
What am I missing?
Best Regards,
Eyal
^ permalink raw reply
* [patch net 3/3] bridge: mdb: Marking port-group as offloaded
From: Jiri Pirko @ 2016-04-21 10:52 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, ogerlitz, stephen, nikolay
In-Reply-To: <1461235965-3930-1-git-send-email-jiri@resnulli.us>
From: Elad Raz <eladr@mellanox.com>
There is a race-condition when updating the mdb offload flag without using
the mulicast_lock. This reverts commit 9e8430f8d60d98 ("bridge: mdb:
Passing the port-group pointer to br_mdb module").
This patch marks offloaded MDB entry as "offload" by changing the port-
group flags and marks it as MDB_PG_FLAGS_OFFLOAD.
When switchdev PORT_MDB succeeded and adds a multicast group, a completion
callback is been invoked "br_mdb_complete". The completion function
locks the multicast_lock and finds the right net_bridge_port_group and
marks it as offloaded.
Fixes: 9e8430f8d60d98 ("bridge: mdb: Passing the port-group pointer to br_mdb module")
Reported-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Elad Raz <eladr@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
net/bridge/br_mdb.c | 91 +++++++++++++++++++++++++++++++++--------------
net/bridge/br_multicast.c | 8 +++--
net/bridge/br_private.h | 4 +--
3 files changed, 71 insertions(+), 32 deletions(-)
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index b258120..7dbc80d 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -256,9 +256,45 @@ static inline size_t rtnl_mdb_nlmsg_size(void)
+ nla_total_size(sizeof(struct br_mdb_entry));
}
-static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
- int type, struct net_bridge_port_group *pg)
+struct br_mdb_complete_info {
+ struct net_bridge_port *port;
+ struct br_ip ip;
+};
+
+static void br_mdb_complete(struct net_device *dev, int err, void *priv)
{
+ struct br_mdb_complete_info *data = priv;
+ struct net_bridge_port_group __rcu **pp;
+ struct net_bridge_port_group *p;
+ struct net_bridge_mdb_htable *mdb;
+ struct net_bridge_mdb_entry *mp;
+ struct net_bridge_port *port = data->port;
+ struct net_bridge *br = port->br;
+
+ if (err)
+ goto err;
+
+ spin_lock_bh(&br->multicast_lock);
+ mdb = mlock_dereference(br->mdb, br);
+ mp = br_mdb_ip_get(mdb, &data->ip);
+ if (!mp)
+ goto out;
+ for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
+ pp = &p->next) {
+ if (p->port != port)
+ continue;
+ p->flags |= MDB_PG_FLAGS_OFFLOAD;
+ }
+out:
+ spin_unlock_bh(&br->multicast_lock);
+err:
+ kfree(priv);
+}
+
+static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
+ struct br_mdb_entry *entry, int type)
+{
+ struct br_mdb_complete_info *complete_info;
struct switchdev_obj_port_mdb mdb = {
.obj = {
.id = SWITCHDEV_OBJ_ID_PORT_MDB,
@@ -281,9 +317,14 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
mdb.obj.orig_dev = port_dev;
if (port_dev && type == RTM_NEWMDB) {
- err = switchdev_port_obj_add(port_dev, &mdb.obj);
- if (!err && pg)
- pg->flags |= MDB_PG_FLAGS_OFFLOAD;
+ complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
+ if (complete_info) {
+ complete_info->port = p;
+ __mdb_entry_to_br_ip(entry, &complete_info->ip);
+ mdb.obj.complete_priv = complete_info;
+ mdb.obj.complete = br_mdb_complete;
+ switchdev_port_obj_add(port_dev, &mdb.obj);
+ }
} else if (port_dev && type == RTM_DELMDB) {
switchdev_port_obj_del(port_dev, &mdb.obj);
}
@@ -304,21 +345,21 @@ errout:
rtnl_set_sk_err(net, RTNLGRP_MDB, err);
}
-void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg,
- int type)
+void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
+ struct br_ip *group, int type, u8 flags)
{
struct br_mdb_entry entry;
memset(&entry, 0, sizeof(entry));
- entry.ifindex = pg->port->dev->ifindex;
- entry.addr.proto = pg->addr.proto;
- entry.addr.u.ip4 = pg->addr.u.ip4;
+ entry.ifindex = port->dev->ifindex;
+ entry.addr.proto = group->proto;
+ entry.addr.u.ip4 = group->u.ip4;
#if IS_ENABLED(CONFIG_IPV6)
- entry.addr.u.ip6 = pg->addr.u.ip6;
+ entry.addr.u.ip6 = group->u.ip6;
#endif
- entry.vid = pg->addr.vid;
- __mdb_entry_fill_flags(&entry, pg->flags);
- __br_mdb_notify(dev, &entry, type, pg);
+ entry.vid = group->vid;
+ __mdb_entry_fill_flags(&entry, flags);
+ __br_mdb_notify(dev, port, &entry, type);
}
static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
@@ -463,8 +504,7 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
- struct br_ip *group, unsigned char state,
- struct net_bridge_port_group **pg)
+ struct br_ip *group, unsigned char state)
{
struct net_bridge_mdb_entry *mp;
struct net_bridge_port_group *p;
@@ -495,7 +535,6 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
if (unlikely(!p))
return -ENOMEM;
rcu_assign_pointer(*pp, p);
- *pg = p;
if (state == MDB_TEMPORARY)
mod_timer(&p->timer, now + br->multicast_membership_interval);
@@ -503,8 +542,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
}
static int __br_mdb_add(struct net *net, struct net_bridge *br,
- struct br_mdb_entry *entry,
- struct net_bridge_port_group **pg)
+ struct br_mdb_entry *entry)
{
struct br_ip ip;
struct net_device *dev;
@@ -525,7 +563,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
__mdb_entry_to_br_ip(entry, &ip);
spin_lock_bh(&br->multicast_lock);
- ret = br_mdb_add_group(br, p, &ip, entry->state, pg);
+ ret = br_mdb_add_group(br, p, &ip, entry->state);
spin_unlock_bh(&br->multicast_lock);
return ret;
}
@@ -533,7 +571,6 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct net *net = sock_net(skb->sk);
- struct net_bridge_port_group *pg;
struct net_bridge_vlan_group *vg;
struct net_device *dev, *pdev;
struct br_mdb_entry *entry;
@@ -563,15 +600,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
if (br_vlan_enabled(br) && vg && entry->vid == 0) {
list_for_each_entry(v, &vg->vlan_list, vlist) {
entry->vid = v->vid;
- err = __br_mdb_add(net, br, entry, &pg);
+ err = __br_mdb_add(net, br, entry);
if (err)
break;
- __br_mdb_notify(dev, entry, RTM_NEWMDB, pg);
+ __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
}
} else {
- err = __br_mdb_add(net, br, entry, &pg);
+ err = __br_mdb_add(net, br, entry);
if (!err)
- __br_mdb_notify(dev, entry, RTM_NEWMDB, pg);
+ __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
}
return err;
@@ -659,12 +696,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
entry->vid = v->vid;
err = __br_mdb_del(br, entry);
if (!err)
- __br_mdb_notify(dev, entry, RTM_DELMDB, NULL);
+ __br_mdb_notify(dev, p, entry, RTM_DELMDB);
}
} else {
err = __br_mdb_del(br, entry);
if (!err)
- __br_mdb_notify(dev, entry, RTM_DELMDB, NULL);
+ __br_mdb_notify(dev, p, entry, RTM_DELMDB);
}
return err;
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index a4c15df..191ea66 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -283,7 +283,8 @@ static void br_multicast_del_pg(struct net_bridge *br,
rcu_assign_pointer(*pp, p->next);
hlist_del_init(&p->mglist);
del_timer(&p->timer);
- br_mdb_notify(br->dev, p, RTM_DELMDB);
+ br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB,
+ p->flags);
call_rcu_bh(&p->rcu, br_multicast_free_pg);
if (!mp->ports && !mp->mglist &&
@@ -705,7 +706,7 @@ static int br_multicast_add_group(struct net_bridge *br,
if (unlikely(!p))
goto err;
rcu_assign_pointer(*pp, p);
- br_mdb_notify(br->dev, p, RTM_NEWMDB);
+ br_mdb_notify(br->dev, port, group, RTM_NEWMDB, 0);
found:
mod_timer(&p->timer, now + br->multicast_membership_interval);
@@ -1461,7 +1462,8 @@ br_multicast_leave_group(struct net_bridge *br,
hlist_del_init(&p->mglist);
del_timer(&p->timer);
call_rcu_bh(&p->rcu, br_multicast_free_pg);
- br_mdb_notify(br->dev, p, RTM_DELMDB);
+ br_mdb_notify(br->dev, port, group, RTM_DELMDB,
+ p->flags);
if (!mp->ports && !mp->mglist &&
netif_running(br->dev))
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1b5d145..d9da857 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -560,8 +560,8 @@ br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
unsigned char flags);
void br_mdb_init(void);
void br_mdb_uninit(void);
-void br_mdb_notify(struct net_device *dev, struct net_bridge_port_group *pg,
- int type);
+void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
+ struct br_ip *group, int type, u8 flags);
void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
int type);
--
2.5.5
^ 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