* Re: [GIT] [3.20] NFC update
From: David Miller @ 2015-01-29 6:50 UTC (permalink / raw)
To: sameo; +Cc: netdev
In-Reply-To: <20150129005216.GA1137@ribalta.ger.corp.intel.com>
From: Samuel Ortiz <sameo@linux.intel.com>
Date: Thu, 29 Jan 2015 01:52:16 +0100
> This is the first NFC pull request for 3.20.
>
> With this one we have:
>
> - Secure element support for the ST Micro st21nfca driver. This depends
> on a few HCI internal changes in order for example to support more
> than one secure element per controller.
>
> - ACPI support for NXP's pn544 HCI driver. This controller is found on
> many x86 SoCs and is typically enumerated on the ACPI bus there.
>
> - A few st21nfca and st21nfcb fixes. Since they're not critical fixes,
> I assumed it's too late for a 3.19 inclusion. Please let me know if
> you'd prefer to see them going through a net pull request instead.
Applied, thanks Samuel.
^ permalink raw reply
* Re: [PATCH v2] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: David Miller @ 2015-01-29 6:22 UTC (permalink / raw)
To: roopa; +Cc: netdev, stephen, rami.rosen
In-Reply-To: <1422490991-4033-1-git-send-email-roopa@cumulusnetworks.com>
From: roopa@cumulusnetworks.com
Date: Wed, 28 Jan 2015 16:23:11 -0800
> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
> Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
>
> This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
> handler does not return any bytes in the skb.
>
> Alternately, the skb->len check can be moved inside rtnl_notify.
>
> For the bridge vlan case described in 92081, there is also a fix needed
> in bridge driver to generate a proper notification. Will fix that in
> subsequent patch.
>
> v2: rebase patch on net tree
>
> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net, ethernet, LLVMLinux: Add missing MODULE_DEVICE_TABLE()
From: David Miller @ 2015-01-29 6:42 UTC (permalink / raw)
To: behanw
Cc: sathya.perla, ajit.khaparde, linux-kernel, netdev,
subbu.seetharaman, arnd
In-Reply-To: <1422495374-22835-1-git-send-email-behanw@converseincode.com>
From: Behan Webster <behanw@converseincode.com>
Date: Wed, 28 Jan 2015 17:36:14 -0800
> Missing MODULE_DEVICE_TABLE for pci ids from benet driver found by clang.
>
> Signed-off-by: Behan Webster <behanw@converseincode.com>
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
Why are you removing the device table?
Second of all, your Subject needs to be adjusted, using "net" and
"LLVMLinux" in your subsystem prefix is not appropriate. Simply
"be2net: ", the name of this driver, is sufficient.
^ permalink raw reply
* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Namhyung Kim @ 2015-01-29 6:41 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Steven Rostedt, Ingo Molnar, Arnaldo Carvalho de Melo, Jiri Olsa,
Masami Hiramatsu, Linux API, Network Development, LKML
In-Reply-To: <CAMEtUuz+N52ms4ZFh8+fSGhg1UaXpBdk9RVPU_zBDCjaZ4bj4A@mail.gmail.com>
On Thu, Jan 29, 2015 at 1:40 PM, Alexei Starovoitov <ast@plumgrid.com> wrote:
> On Wed, Jan 28, 2015 at 4:46 PM, Namhyung Kim <namhyung@kernel.org> wrote:
>>>
>>> +static int event_filter_release(struct inode *inode, struct file *filp)
>>> +{
>>> + struct ftrace_event_file *file;
>>> + char buf[2] = "0";
>>> +
>>> + mutex_lock(&event_mutex);
>>> + file = event_file_data(filp);
>>> + if (file) {
>>> + if (file->flags & TRACE_EVENT_FL_BPF) {
>>> + /* auto-disable the filter */
>>> + ftrace_event_enable_disable(file, 0);
>>
>> Hmm.. what if user already enabled an event, attached a bpf filter and
>> then detached the filter - I'm not sure we can always auto-disable
>> it..
>
> why not?
> I think it makes sense auto enable/disable, since that
> is cleaner user experience.
> Otherwise Ctrl-C of the user process will have bpf program dangling.
> not good. If we auto-unload bpf program only, it's equally bad.
> Since Ctrl-C of the process will auto-onload only
> and will keep tracepoint enabled which will be spamming
> the trace buffer.
I think it's not a problem of bpf. An user process can be killed
anytime while it enabed events without bpf. The only thing it should
care is the auto-unload IMHO.
>
>>> +unsigned int trace_filter_call_bpf(struct event_filter *filter, void *ctx)
>>> +{
>>> + unsigned int ret;
>>> +
>>> + if (in_nmi()) /* not supported yet */
>>> + return 0;
>>
>> But doesn't this mean to auto-disable all attached events during NMI
>> as returning 0 will prevent the event going to ring buffer?
>
> well, it means that if tracepoint fired during nmi the program
> won't be called and event won't be sent to trace buffer.
> The program might be broken (like divide by zero) and
> it will self-terminate with 'return 0'
> so zero should be the safest return value that
> causes minimum disturbance to the whole system overall.
I'm okay for not calling bpf program in NMI but not for disabling events.
Suppose an user was collecting an event (including in NMI) and then
[s]he also wanted to run a bpf program. So [s]he wrote a program
always return 1. But after attaching the program, it didn't record
the event in NMI.. Isn't that a problem?
>
>> I think it'd be better to keep an attached event in a soft-disabled
>> state like event trigger and give control of enabling to users..
>
> I think it suffers from the same Ctrl-C issue.
> Say, attaching bpf program activates tracepoint and keeps
> it in soft-disabled. Then user space clears soft-disabled.
> Then user Ctrl-C it. Now bpf program must auto-detach
> and unload, since prog_fd is closing.
> If we don't completely deactivate tracepoint, then
> Ctrl-C will leave the state of the system in the state
> different from it was before user process started running.
> I think we must avoid such situation.
> 'kill pid' should be completely cleaning all resources
> that user process was using.
> Yes. It's different from typical usage of /sys/.../tracing
> that has all global knobs, but, imo, it's cleaner this way.
Right. I think bpf programs belong to a user process but events are
global resource. Maybe you also need to consider attaching bpf
program via perf (ioctl?) interface..
Thanks,
Namhyung
^ permalink raw reply
* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Alexei Starovoitov @ 2015-01-29 6:39 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Namhyung Kim, Steven Rostedt, Ingo Molnar,
Arnaldo Carvalho de Melo, Jiri Olsa, Linux API,
Network Development, LKML
On Wed, Jan 28, 2015 at 9:39 PM, Masami Hiramatsu
<masami.hiramatsu.pt@hitachi.com> wrote:
>
> Maybe, would we need a reference counter for each event? :)
when we would want multiple users to attach different programs
to the same event, then yes.
Right now I'd rather have things simple.
> Actually, ftrace event is not similar to perf-event which ktap
> is based on, ftrace event interface is always exported via
> debugfs, this means users can share the event for different
> usage.
yes.I've been thinking to extend perf_event ioctl to attach programs,
but right now it's only supporting tracepoints and kprobe
seems not trivial to add.
So I went for tracefs style of attaching for now.
> One possible other solution is to add a instance-lock interface
> for each ftrace instance and lock it by bpf. Then, other users
> can not enable/disable the events in the instance.
the user space can synchronize itself via flock. kernel doesn't
need to arbitrate. If one user process attached a program
that auto-enabled an event and another process did
'echo 0 > enable', it's fine. I think it's a feature instead of a bug.
Both users are root anyway.
The more we talk about it, the more I like a new 'bpf' file
approach within tracefs (that I've mentioned in cover letter)
with auto-enable/disable logic to make it clear that
it's different from traditional global 'filter' file.
^ permalink raw reply
* Re: [PATCH] net:wan:Change location of debug printk statement in the function,hss_hdlc_poll
From: Krzysztof Hałasa @ 2015-01-29 6:35 UTC (permalink / raw)
To: Nicholas Krause; +Cc: netdev, linux-kernel
In-Reply-To: <1422143181-4479-1-git-send-email-xerofoify@gmail.com>
Nicholas Krause <xerofoify@gmail.com> writes:
> This changes the location of the printk for montioring if the stucture pointer
> desc of type structure desc has a error count due to failing in the switch
> statement for checking it's status from the default switch case in this switch
> to the area of the function for checking if there is a error count. Due to this
> this part of the function can now be uncommented as it's now needed for printing
> out important information if the structure pointer,desc has a error count for
> debugging purposes.
This error count seems to be secondary to the desc->status. It's isn't
normally logged (RX errors on serial links are quite normal) and only
the "default" case, normally not seen, would be logged (to indicate
unhandled condition). In the "normal" error path, the driver ignores
error count, because there could be several errors counted for a single
erroneous frame (or non-frame).
Also the patch seems to remove the beginning of a preprocessor directive
(#if) without removing its end (#endif). I'd be surprised if it compiles.
> --- a/drivers/net/wan/ixp4xx_hss.c
> +++ b/drivers/net/wan/ixp4xx_hss.c
> @@ -697,7 +697,6 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
> }
>
> desc = rx_desc_ptr(port, n);
> -#if 0 /* FIXME - error_count counts modulo 256, perhaps we should use it */
> if (desc->error_count)
> printk(KERN_DEBUG "%s: hss_hdlc_poll status 0x%02X"
> " errors %u\n", dev->name, desc->status,
> @@ -735,9 +734,7 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
> dev->stats.rx_length_errors++;
> dev->stats.rx_errors++;
> break;
> - default: /* FIXME - remove printk */
> - netdev_err(dev, "hss_hdlc_poll: status 0x%02X errors %u\n",
> - desc->status, desc->error_count);
> + default:
> dev->stats.rx_errors++;
> }
--
Krzysztof Halasa
Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland
^ permalink raw reply
* Re: [PATCH v2] lib/checksum.c: fix carry in csum_tcpudp_nofold
From: David Miller @ 2015-01-29 6:32 UTC (permalink / raw)
To: karl.beldan
Cc: karl.beldan, viro, eric.dumazet, arnd, vapier, netdev,
linux-kernel, stable
In-Reply-To: <1422439091-31413-1-git-send-email-karl.beldan@rivierawaves.com>
From: Karl Beldan <karl.beldan@gmail.com>
Date: Wed, 28 Jan 2015 10:58:11 +0100
> The carry from the 64->32bits folding was dropped, e.g with:
> saddr=0xFFFFFFFF daddr=0xFF0000FF len=0xFFFF proto=0 sum=1,
> csum_tcpudp_nofold returned 0 instead of 1.
>
> Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
Applied, thanks.
^ permalink raw reply
* LOL
From: Paul @ 2015-01-28 21:12 UTC (permalink / raw)
To: netdev
Hahahaha! Is that you on that pic???? :)
http://tinyurl.com/nv3udu4
No more such info? Simply answer <NO>
^ permalink raw reply
* Re: [PATCH net-next v2 0/5] fix stretch ACK bugs in TCP CUBIC and Reno
From: David Miller @ 2015-01-29 6:22 UTC (permalink / raw)
To: ncardwell; +Cc: netdev
In-Reply-To: <1422493299-22114-1-git-send-email-ncardwell@google.com>
From: Neal Cardwell <ncardwell@google.com>
Date: Wed, 28 Jan 2015 20:01:34 -0500
> This patch series fixes the TCP CUBIC and Reno congestion control
> modules to properly handle stretch ACKs in their respective additive
> increase modes, and in the transitions from slow start to additive
> increase.
>
> This finishes the project started by commit 9f9843a751d0a2057 ("tcp:
> properly handle stretch acks in slow start"), which fixed behavior for
> TCP congestion control when handling stretch ACKs in slow start mode.
>
> Motivation: In the Jan 2015 netdev thread 'BW regression after "tcp:
> refine TSO autosizing"', Eyal Perry documented a regression that Eric
> Dumazet determined was caused by improper handling of TCP stretch
> ACKs.
>
> Background: LRO, GRO, delayed ACKs, and middleboxes can cause "stretch
> ACKs" that cover more than the RFC-specified maximum of 2
> packets. These stretch ACKs can cause serious performance shortfalls
> in common congestion control algorithms, like Reno and CUBIC, which
> were designed and tuned years ago with receiver hosts that were not
> using LRO or GRO, and were instead ACKing every other packet.
>
> Testing: at Google we have been using this approach for handling
> stretch ACKs for CUBIC datacenter and Internet traffic for several
> years, with good results.
>
> v2:
> * fixed return type of tcp_slow_start() to be u32 instead of int
Series applied, thanks Neal.
^ permalink raw reply
* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Masami Hiramatsu @ 2015-01-29 5:39 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Namhyung Kim, Steven Rostedt, Ingo Molnar,
Arnaldo Carvalho de Melo, Jiri Olsa, Linux API,
Network Development, LKML
In-Reply-To: <CAMEtUuz+N52ms4ZFh8+fSGhg1UaXpBdk9RVPU_zBDCjaZ4bj4A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
(2015/01/29 13:40), Alexei Starovoitov wrote:
> On Wed, Jan 28, 2015 at 4:46 PM, Namhyung Kim <namhyung-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>
>>> +static int event_filter_release(struct inode *inode, struct file *filp)
>>> +{
>>> + struct ftrace_event_file *file;
>>> + char buf[2] = "0";
>>> +
>>> + mutex_lock(&event_mutex);
>>> + file = event_file_data(filp);
>>> + if (file) {
>>> + if (file->flags & TRACE_EVENT_FL_BPF) {
>>> + /* auto-disable the filter */
>>> + ftrace_event_enable_disable(file, 0);
>>
>> Hmm.. what if user already enabled an event, attached a bpf filter and
>> then detached the filter - I'm not sure we can always auto-disable
>> it..
>
> why not?
> I think it makes sense auto enable/disable, since that
> is cleaner user experience.
Maybe, would we need a reference counter for each event? :)
Actually, ftrace event is not similar to perf-event which ktap
is based on, ftrace event interface is always exported via
debugfs, this means users can share the event for different
usage.
One possible other solution is to add a instance-lock interface
for each ftrace instance and lock it by bpf. Then, other users
can not enable/disable the events in the instance.
Thank you,
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt-FCd8Q96Dh0JBDgjK7y7TUQ@public.gmane.org
^ permalink raw reply
* Re: [PATCH net v2] net: ipv6: allow explicitly choosing optimistic addresses
From: Lorenzo Colitti @ 2015-01-29 5:25 UTC (permalink / raw)
To: Erik Kline; +Cc: netdev@vger.kernel.org, Hannes Frederic Sowa
In-Reply-To: <1422446619-9502-1-git-send-email-ek@google.com>
On Wed, Jan 28, 2015 at 9:03 PM, Erik Kline <ek@google.com> wrote:
> if (ipv6_addr_equal(&ifp->addr, addr) &&
> - !(ifp->flags&IFA_F_TENTATIVE) &&
> + (!(ifp->flags&banned_flags) ||
> + ifp->flags&IFA_F_OPTIMISTIC&~banned_flags) &&
Is this if statement correct?
The intent here is "if ifp has IFA_F_OPTIMISTIC set, then
IFA_F_TENTATIVE is allowed, even if the caller explicitly banned
IFA_F_TENTATIVE", right? Not "if ifp has IFA_F_OPTIMISTIC set, then
any flags are allowed, even ones explicitly baned by the caller". For
example, suppose that:
banned_flags = IFA_F_SECONDARY
ifp->flags = IFA_F_SECONDARY | IFA_F_OPTIMISTIC
In that case, won't the if statement match ifp, even though it
contains a flag that is explicitly banned?
^ permalink raw reply
* RE: cxgb4: CONFIG_CXGB4_DCB?
From: Anish Bhatt @ 2015-01-29 5:16 UTC (permalink / raw)
To: Paul Bolle, Hariprasad S
Cc: Valentin Rothberg, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1422480916.3621.53.camel@x220>
It got to the maintainer nevertheless. Thanks for bringing this to our notice
Paul, fix for this is already in the patchwork queue :
https://patchwork.ozlabs.org/patch/434279/
-Anish
^ permalink raw reply
* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Alexei Starovoitov @ 2015-01-29 4:40 UTC (permalink / raw)
To: Namhyung Kim
Cc: Steven Rostedt, Ingo Molnar, Arnaldo Carvalho de Melo, Jiri Olsa,
Masami Hiramatsu, Linux API, Network Development, LKML
On Wed, Jan 28, 2015 at 4:46 PM, Namhyung Kim <namhyung@kernel.org> wrote:
>>
>> +static int event_filter_release(struct inode *inode, struct file *filp)
>> +{
>> + struct ftrace_event_file *file;
>> + char buf[2] = "0";
>> +
>> + mutex_lock(&event_mutex);
>> + file = event_file_data(filp);
>> + if (file) {
>> + if (file->flags & TRACE_EVENT_FL_BPF) {
>> + /* auto-disable the filter */
>> + ftrace_event_enable_disable(file, 0);
>
> Hmm.. what if user already enabled an event, attached a bpf filter and
> then detached the filter - I'm not sure we can always auto-disable
> it..
why not?
I think it makes sense auto enable/disable, since that
is cleaner user experience.
Otherwise Ctrl-C of the user process will have bpf program dangling.
not good. If we auto-unload bpf program only, it's equally bad.
Since Ctrl-C of the process will auto-onload only
and will keep tracepoint enabled which will be spamming
the trace buffer.
>> +unsigned int trace_filter_call_bpf(struct event_filter *filter, void *ctx)
>> +{
>> + unsigned int ret;
>> +
>> + if (in_nmi()) /* not supported yet */
>> + return 0;
>
> But doesn't this mean to auto-disable all attached events during NMI
> as returning 0 will prevent the event going to ring buffer?
well, it means that if tracepoint fired during nmi the program
won't be called and event won't be sent to trace buffer.
The program might be broken (like divide by zero) and
it will self-terminate with 'return 0'
so zero should be the safest return value that
causes minimum disturbance to the whole system overall.
> I think it'd be better to keep an attached event in a soft-disabled
> state like event trigger and give control of enabling to users..
I think it suffers from the same Ctrl-C issue.
Say, attaching bpf program activates tracepoint and keeps
it in soft-disabled. Then user space clears soft-disabled.
Then user Ctrl-C it. Now bpf program must auto-detach
and unload, since prog_fd is closing.
If we don't completely deactivate tracepoint, then
Ctrl-C will leave the state of the system in the state
different from it was before user process started running.
I think we must avoid such situation.
'kill pid' should be completely cleaning all resources
that user process was using.
Yes. It's different from typical usage of /sys/.../tracing
that has all global knobs, but, imo, it's cleaner this way.
^ permalink raw reply
* Re: [PATCH v2 linux-trace 4/8] samples: bpf: simple tracing example in C
From: Alexei Starovoitov @ 2015-01-29 4:19 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Ingo Molnar, Namhyung Kim, Jiri Olsa,
Masami Hiramatsu, Linux API, Network Development, LKML
On Wed, Jan 28, 2015 at 12:44 PM, Arnaldo Carvalho de Melo
<acme-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
>> > #define memcmp(s1, s2, n) bpf_memcmp(s1, s2, n)
>
>> >> in bpf_helpers.h to have it work?
>
>> yes, that will work just fine.
>> Since it's an example I made it explicit that bpf_memcmp()
>> has memcmp() semantics, but little bit different:
>> int bpf_memcmp(void *unsafe_ptr, void *safe_ptr, int size)
>
> Not knowing about the safe/unsafe pointers (at this point in my
> conceptual eBPF learning process), I would think that it would be easier
> to understand if it would reuse another well known idiom:
>
> #define memcmp_from_user(kernel, user, n) bpf_memcmp(user, kernel, n)
that actually won't be right. It's not reading from user.
'unsafe' means that pointer is not known to be safe
within the program. So far, bpf verifier recognizes pointer
to context, stack and maps. Everything else is unsafe.
Therefore all pointer walking of unknown data structures
need to use bpf_fetch_*() helpers to access memory.
Similarly bpf_memcmp() is used to do memcmp() of
two memory regions: one known to be safe and one
unknown.
> I don't reuse anything I've learned before trying to understand eBPF,
> not I see any well known marker (__user) that would help me understand
> that that pointer needs special treatment/belongs to a different "domain".
I tried to do exactly that actually :)
bpf_fetch_*() helpers suppose to match existing fetch*()
primitives used to do the same pointer walking for kprobes.
Maybe bpf_probe_memcmp() would be a better name?
Hard to tell.
>> bpf_fetch_*() helpers are also explicit in examples.
>> If one need to do a lot of pointer walking, then macro like
>> #define D(P) ((typeof(P))bpf_fetch_ptr(&P))
>> would be easier to use: p = D(D(skb->dev)->ifalias)
>> multiple pointer derefs would look more natural...
>
> And if possible, i.e. if the eBPF compiler would take care of that
> somehow, would indeed be preferred as it looks more natural :-)
yes, on the user space side we have all the freedom.
Note, these examples are using user's bpf_helpers.h
which defines it as:
static int (*bpf_memcmp)(void *unsafe_ptr, void *safe_ptr, int size) =
(void *) BPF_FUNC_memcmp;
so whether we want to call the function bpf_memcmp() or
bpf_probe_memcmp() is up to user space.
The BPF_FUNC_memcmp name is what matters which
is defined in uapi/linux/bpf.h
I'll try to come up with more explicit name...
^ permalink raw reply
* [PATCH net v2] net: ipv6: allow explicitly choosing optimistic addresses
From: Erik Kline @ 2015-01-28 12:03 UTC (permalink / raw)
To: netdev; +Cc: hannes, Erik Kline
RFC 4429 ("Optimistic DAD") states that optimistic addresses
should be treated as deprecated addresses. From section 2.1:
Unless noted otherwise, components of the IPv6 protocol stack
should treat addresses in the Optimistic state equivalently to
those in the Deprecated state, indicating that the address is
available for use but should not be used if another suitable
address is available.
Optimistic addresses are indeed avoided when other addresses are
available (i.e. at source address selection time), but they have
not heretofore been available for things like explicit bind() and
sendmsg() with struct in6_pktinfo, etc.
This change makes optimistic addresses treated more like
deprecated addresses than tentative ones.
Signed-off-by: Erik Kline <ek@google.com>
---
include/net/addrconf.h | 3 +++
net/ipv6/addrconf.c | 13 +++++++++++--
net/ipv6/ndisc.c | 4 +++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index d13573b..80456f7 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -62,6 +62,9 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg);
int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, int strict);
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
+ const struct net_device *dev, int strict,
+ u32 banned_flags);
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f7c8bbe..943da83 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1519,6 +1519,14 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, int strict)
{
+ return ipv6_chk_addr_and_flags(net, addr, dev, strict, IFA_F_TENTATIVE);
+}
+EXPORT_SYMBOL(ipv6_chk_addr);
+
+int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
+ const struct net_device *dev, int strict,
+ u32 banned_flags)
+{
struct inet6_ifaddr *ifp;
unsigned int hash = inet6_addr_hash(addr);
@@ -1527,7 +1535,8 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
if (!net_eq(dev_net(ifp->idev->dev), net))
continue;
if (ipv6_addr_equal(&ifp->addr, addr) &&
- !(ifp->flags&IFA_F_TENTATIVE) &&
+ (!(ifp->flags&banned_flags) ||
+ ifp->flags&IFA_F_OPTIMISTIC&~banned_flags) &&
(dev == NULL || ifp->idev->dev == dev ||
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
rcu_read_unlock_bh();
@@ -1538,7 +1547,7 @@ int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
rcu_read_unlock_bh();
return 0;
}
-EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
struct net_device *dev)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 6828667..113fc6c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -655,7 +655,9 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
int probes = atomic_read(&neigh->probes);
- if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
+ if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr,
+ dev, 1,
+ IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))
saddr = &ipv6_hdr(skb)->saddr;
probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
if (probes < 0) {
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH] Repair soft lockup with monitor mode of ath9k_htc card
From: zhengyuwei @ 2015-01-29 4:09 UTC (permalink / raw)
To: linux-kernel, ath9k-devel, linux-wireless, kvalo, ath9k-devel
Cc: netdev, Yuwei Zheng
From: Yuwei Zheng <zhengyuwei@360.cn>
In the environment with heavy wifi traffic, set the ar9271 into monitor mode, will
trigger a deadloop panic.
The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
[59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
[kworker/0:0:30609]
[59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
[59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
[59013.858522] Kernel panic - not syncing: softlockup: hung tasks
[59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
[59014.046834] bc20: de57b950 60000113
[59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
[59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
[59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
[59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
[59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
[59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
[59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
[59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
[59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
[59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
This bug can be see with low performance board, such as uniprocessor beagle bone board.
Signed-off-by: Yuwei Zheng <zhengyuwei@360.cn>
---
drivers/net/wireless/ath/ath9k/hif_usb.c | 53 ++++++++++++++++++++++----
drivers/net/wireless/ath/ath9k/hif_usb.h | 5 +++
drivers/net/wireless/ath/ath9k/htc.h | 13 +++++++
drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 49 ++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 26 +++++++++++++
5 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 8e7153b..febea5e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -658,7 +658,6 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
default:
goto resubmit;
}
-
if (likely(urb->actual_length != 0)) {
skb_put(skb, urb->actual_length);
ath9k_hif_usb_rx_stream(hif_dev, skb);
@@ -667,12 +666,18 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
resubmit:
skb_reset_tail_pointer(skb);
skb_trim(skb, 0);
-
- usb_anchor_urb(urb, &hif_dev->rx_submitted);
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret) {
- usb_unanchor_urb(urb);
- goto free;
+ if (atomic_read(&hif_dev->rx_urb_submit_delay) > 0) {
+ usb_anchor_urb(urb, &hif_dev->rx_delayed_submitted);
+ ret = tasklet_hrtimer_start(&hif_dev->rx_submit_timer,
+ ktime_set(0, atomic_read(&hif_dev->rx_urb_submit_delay)*1000),
+ HRTIMER_MODE_REL);
+ } else {
+ usb_anchor_urb(urb, &hif_dev->rx_submitted);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret) {
+ usb_unanchor_urb(urb);
+ goto free;
+ }
}
return;
@@ -818,9 +823,37 @@ err:
return -ENOMEM;
}
+static enum hrtimer_restart rx_urb_submit_timer_handler(struct hrtimer *me)
+{
+ struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);
+ struct hif_device_usb *hif_dev = container_of(thr, struct hif_device_usb, rx_submit_timer);
+ struct urb *urb = NULL;
+ struct sk_buff *skb = NULL;
+ int ret;
+
+ while (true) {
+ urb = usb_get_from_anchor(&hif_dev->rx_delayed_submitted);
+ if (urb != NULL) {
+ skb = (struct sk_buff *)urb->context;
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+ if (ret != -EBUSY) {
+ usb_unanchor_urb(urb);
+ dev_kfree_skb_any(skb);
+ urb->context = NULL;
+ }
+ } else {
+ break;
+ }
+ }
+
+ return HRTIMER_NORESTART;
+}
+
static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
{
usb_kill_anchored_urbs(&hif_dev->rx_submitted);
+ usb_kill_anchored_urbs(&hif_dev->rx_delayed_submitted);
+ tasklet_hrtimer_cancel(&hif_dev->rx_submit_timer);
}
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
@@ -830,6 +863,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
int i, ret;
init_usb_anchor(&hif_dev->rx_submitted);
+ init_usb_anchor(&hif_dev->rx_delayed_submitted);
+
spin_lock_init(&hif_dev->rx_lock);
for (i = 0; i < MAX_RX_URB_NUM; i++) {
@@ -871,6 +906,10 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
usb_free_urb(urb);
}
+ /* add for flow control*/
+ atomic_set(&hif_dev->rx_urb_submit_delay, 0);
+ tasklet_hrtimer_init(&hif_dev->rx_submit_timer, rx_urb_submit_timer_handler, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+
return 0;
err_submit:
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 51496e7..56d6be8 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -98,9 +98,14 @@ struct hif_device_usb {
struct hif_usb_tx tx;
struct usb_anchor regout_submitted;
struct usb_anchor rx_submitted;
+ struct usb_anchor rx_delayed_submitted; /* delayed submit anchor */
struct usb_anchor reg_in_submitted;
struct usb_anchor mgmt_submitted;
struct sk_buff *remain_skb;
+
+ struct tasklet_hrtimer rx_submit_timer;/* delayed submit hrtimer */
+ atomic_t rx_urb_submit_delay; /*us*/
+
const char *fw_name;
int rx_remain_len;
int rx_pkt_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 9dde265..453d0a8 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -331,6 +331,10 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+#define TASKLETRX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c++)
+#define TASKLETRX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c += a)
+#define TASKLETRX_STAT_SET(c, a) (hif_dev->htc_handle->drv_priv->debug.taskletrx_stats.c = a)
+
void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
struct ath_rx_status *rs);
@@ -352,11 +356,20 @@ struct ath_skbrx_stats {
u32 skb_dropped;
};
+struct ath_taskletrx_stats {
+ u32 taskletrx_looptimes;
+ u32 taskletrx_highwater;
+ u32 taskletrx_lowwater;
+ u32 taskletrx_watermark_triggered;
+ u32 taskletrx_urb_submit_delay;
+};
+
struct ath9k_debug {
struct dentry *debugfs_phy;
struct ath_tx_stats tx_stats;
struct ath_rx_stats rx_stats;
struct ath_skbrx_stats skbrx_stats;
+ struct ath_taskletrx_stats taskletrx_stats;
};
void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index 8cef1ed..7c8322e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -286,6 +286,51 @@ static const struct file_operations fops_skb_rx = {
.llseek = default_llseek,
};
+static ssize_t read_file_tasklet_rx(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath9k_htc_priv *priv = file->private_data;
+ char *buf;
+ unsigned int len = 0, size = 1500;
+ ssize_t retval = 0;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "Loop times",
+ priv->debug.taskletrx_stats.taskletrx_looptimes);
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "High watermark",
+ priv->debug.taskletrx_stats.taskletrx_highwater);
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "Low watermark",
+ priv->debug.taskletrx_stats.taskletrx_lowwater);
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "WM triggered",
+ priv->debug.taskletrx_stats.taskletrx_watermark_triggered);
+
+ len += scnprintf(buf + len, size - len,
+ "%20s : %10u\n", "URB delay",
+ priv->debug.taskletrx_stats.taskletrx_urb_submit_delay);
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static const struct file_operations fops_tasklet_rx = {
+ .read = read_file_tasklet_rx,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
static ssize_t read_file_slot(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -518,7 +563,11 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_skb_rx);
+ debugfs_create_file("tasklet_rx", S_IRUSR, priv->debug.debugfs_phy,
+ priv, &fops_tasklet_rx);
+
ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
+
ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index a0f58e2..f5e6217 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1061,7 +1061,28 @@ void ath9k_rx_tasklet(unsigned long data)
unsigned long flags;
struct ieee80211_hdr *hdr;
+ /* add for adaptive flow control*/
+ int looptimes = 0;
+ int highwatermark = ATH9K_HTC_RXBUF*3/4;
+ int lowwatermark = ATH9K_HTC_RXBUF/4;
+ unsigned int delay = 0;
+
+ struct htc_target *htc = priv->htc;
+ struct hif_device_usb *hif_dev = htc->hif_dev;
+
+ TASKLETRX_STAT_SET(taskletrx_highwater, highwatermark);
+ TASKLETRX_STAT_SET(taskletrx_lowwater, lowwatermark);
+
do {
+ looptimes++;
+ TASKLETRX_STAT_SET(taskletrx_looptimes, looptimes);
+ if (looptimes > highwatermark) {
+ delay = looptimes*10;
+ atomic_set(&hif_dev->rx_urb_submit_delay, delay);
+ TASKLETRX_STAT_INC(taskletrx_watermark_triggered);
+ TASKLETRX_STAT_SET(taskletrx_urb_submit_delay, delay);
+ }
+
spin_lock_irqsave(&priv->rx.rxbuflock, flags);
list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
if (tmp_buf->in_process) {
@@ -1072,6 +1093,11 @@ void ath9k_rx_tasklet(unsigned long data)
if (rxbuf == NULL) {
spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
+ if (looptimes < lowwatermark) {
+ atomic_set(&hif_dev->rx_urb_submit_delay, 0);
+ TASKLETRX_STAT_SET(taskletrx_urb_submit_delay, 0);
+ }
+
break;
}
--
1.9.1
^ permalink raw reply related
* [PATCH] net: ipv6: Make address flushing on ifdown optional - v2
From: David Ahern @ 2015-01-29 4:01 UTC (permalink / raw)
To: netdev; +Cc: David Ahern, Hannes Frederic Sowa
Currently, all ipv6 addresses are flushed when the interface is configured
down, even static address:
[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global tentative
valid_lft forever preferred_lft forever
[root@f20 ~]# ip link set dev eth1 up
[root@f20 ~]# ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
Add a new sysctl to make this behavior optional. The new setting defaults to
flush all addresses to maintain backwards compatibility. When the setting is
reset static addresses are not flushed:
[root@f20 ~]# echo 0 > /proc/sys/net/ipv6/conf/eth1/flush_addr_on_down
[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global tentative
valid_lft forever preferred_lft forever
[root@f20 ~]# ip link set dev eth1 up
[root@f20 ~]# ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
inet6 2000:11:1:1::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::4:11ff:fe22:3301/64 scope link
valid_lft forever preferred_lft forever
v2:
- only keep static addresses as suggested by Hannes
- added new managed flag to track configured addresses
- on ifdown do not remove from configured address from inet6_addr_lst
- on ifdown reset the TENTATIVE flag and set state to DAD so that DAD is
redone when link is brought up again
Suggested-by: Hannes Frederic Sowa <hannes@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Hannes Frederic Sowa <hannes@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
---
include/linux/ipv6.h | 1 +
include/net/if_inet6.h | 1 +
include/uapi/linux/ipv6.h | 1 +
net/ipv6/addrconf.c | 55 ++++++++++++++++++++++++++++++++++++++---------
4 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 2805062c013f..b91b7c8be023 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -53,6 +53,7 @@ struct ipv6_devconf {
__s32 ndisc_notify;
__s32 suppress_frag_ndisc;
__s32 accept_ra_mtu;
+ __s32 flush_addr_on_down;
void *sysctl;
};
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 98e5f9578f86..3b6323111f77 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -72,6 +72,7 @@ struct inet6_ifaddr {
int regen_count;
bool tokenized;
+ bool managed;
struct rcu_head rcu;
struct in6_addr peer_addr;
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 437a6a4b125a..ed10d4ba8340 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -170,6 +170,7 @@ enum {
DEVCONF_ACCEPT_RA_FROM_LOCAL,
DEVCONF_USE_OPTIMISTIC,
DEVCONF_ACCEPT_RA_MTU,
+ DEVCONF_FLUSH_ON_DOWN,
DEVCONF_MAX
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7dcc065e2160..e0e82aad2116 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.accept_dad = 1,
.suppress_frag_ndisc = 1,
.accept_ra_mtu = 1,
+ .flush_addr_on_down = 1,
};
static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -240,6 +241,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.accept_dad = 1,
.suppress_frag_ndisc = 1,
.accept_ra_mtu = 1,
+ .flush_addr_on_down = 1,
};
/* Check if a valid qdisc is available */
@@ -870,6 +872,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
ifa->prefered_lft = prefered_lft;
ifa->cstamp = ifa->tstamp = jiffies;
ifa->tokenized = false;
+ ifa->managed = false;
ifa->rt = rt;
@@ -2510,6 +2513,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
valid_lft, prefered_lft);
if (!IS_ERR(ifp)) {
+ ifp->managed = true;
+
if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) {
addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
expires, flags);
@@ -3032,8 +3037,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
{
struct net *net = dev_net(dev);
struct inet6_dev *idev;
- struct inet6_ifaddr *ifa;
+ struct inet6_ifaddr *ifa, *tmp;
int state, i;
+ struct list_head del_list;
ASSERT_RTNL();
@@ -3067,9 +3073,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
restart:
hlist_for_each_entry_rcu(ifa, h, addr_lst) {
if (ifa->idev == idev) {
- hlist_del_init_rcu(&ifa->addr_lst);
addrconf_del_dad_work(ifa);
- goto restart;
+ if (how || idev->cnf.flush_addr_on_down ||
+ !ifa->managed) {
+ hlist_del_init_rcu(&ifa->addr_lst);
+ goto restart;
+ }
}
}
spin_unlock_bh(&addrconf_hash_lock);
@@ -3103,14 +3112,35 @@ restart:
write_lock_bh(&idev->lock);
}
- while (!list_empty(&idev->addr_list)) {
- ifa = list_first_entry(&idev->addr_list,
+ INIT_LIST_HEAD(&del_list);
+ list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
+ /*
+ * on NETDEV_DOWN events do not flush managed (user configured)
+ * addresses unless configured to do so. If the address is not
+ * deleted reset flags and state such that DAD is re-done on a
+ * subsequent link up.
+ */
+ if (!how && !idev->cnf.flush_addr_on_down && ifa->managed) {
+ if (!(ifa->flags & IFA_F_NODAD)) {
+ ifa->flags |= IFA_F_TENTATIVE;
+ ifa->state = INET6_IFADDR_STATE_DAD;
+ }
+ } else {
+ list_del(&ifa->if_list);
+ list_add(&ifa->if_list, &del_list);
+ }
+ }
+
+ write_unlock_bh(&idev->lock);
+
+ while (!list_empty(&del_list)) {
+ ifa = list_first_entry(&del_list,
struct inet6_ifaddr, if_list);
+
addrconf_del_dad_work(ifa);
list_del(&ifa->if_list);
- write_unlock_bh(&idev->lock);
spin_lock_bh(&ifa->state_lock);
state = ifa->state;
@@ -3122,12 +3152,8 @@ restart:
inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
}
in6_ifa_put(ifa);
-
- write_lock_bh(&idev->lock);
}
- write_unlock_bh(&idev->lock);
-
/* Step 5: Discard anycast and multicast list */
if (how) {
ipv6_ac_destroy_dev(idev);
@@ -4383,6 +4409,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local;
array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu;
+ array[DEVCONF_FLUSH_ON_DOWN] = cnf->flush_addr_on_down;
}
static inline size_t inet6_ifla6_size(void)
@@ -5269,6 +5296,14 @@ static struct addrconf_sysctl_table
.proc_handler = proc_dointvec,
},
{
+ .procname = "flush_addr_on_down",
+ .data = &ipv6_devconf.flush_addr_on_down,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+
+ },
+ {
/* sentinel */
}
},
--
1.9.3
^ permalink raw reply related
* [PATCH net-next] pkt_sched: fq: remove useless TIME_WAIT check
From: Eric Dumazet @ 2015-01-28 14:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
TIME_WAIT sockets are not owning any skb.
ip_send_unicast_reply() and tcp_v6_send_response() both use
regular sockets.
We can safely remove a test in sch_fq and save one cache line miss,
as sk_state is far away from sk_pacing_rate.
Tested at Google for about one year.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_fq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 9b05924cc386ecc2cdb9816be27e439637fb37b3..2a50f5c62070a81ae37d871aac2626555128fd38 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -1,7 +1,7 @@
/*
* net/sched/sch_fq.c Fair Queue Packet Scheduler (per flow pacing)
*
- * Copyright (C) 2013 Eric Dumazet <edumazet@google.com>
+ * Copyright (C) 2013-2015 Eric Dumazet <edumazet@google.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -471,7 +471,7 @@ begin:
goto out;
rate = q->flow_max_rate;
- if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT)
+ if (skb->sk)
rate = min(skb->sk->sk_pacing_rate, rate);
if (rate != ~0U) {
^ permalink raw reply related
* Re: [Patch iproute2] skbedit: print action too
From: Cong Wang @ 2015-01-29 3:51 UTC (permalink / raw)
To: Dennis Chen; +Cc: netdev, Jamal Hadi Salim, Stephen Hemminger
In-Reply-To: <CA+U0gViQrppOQXsKwDHWOF5oWs61j6Hbck5o2LnMXMectm64xw@mail.gmail.com>
On Wed, Jan 28, 2015 at 7:49 PM, Dennis Chen <kernel.org.gnu@gmail.com> wrote:
>
> Hello cong, seems no big benifit I can see for the patch...
>
You need to understand skbedit action.
^ permalink raw reply
* Re: [Patch iproute2] skbedit: print action too
From: Dennis Chen @ 2015-01-29 3:49 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev, Jamal Hadi Salim, Stephen Hemminger
In-Reply-To: <1422485562-15572-1-git-send-email-xiyou.wangcong@gmail.com>
On Thu, Jan 29, 2015 at 6:52 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
> ---
> tc/m_skbedit.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
> index 36323a9..c5deee0 100644
> --- a/tc/m_skbedit.c
> +++ b/tc/m_skbedit.c
> @@ -193,7 +193,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
> fprintf(f, " mark %d", *mark);
> }
>
> - fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
> + fprintf(f, " %s\n\t index %d ref %d bind %d", action_n2a(p->action, b1, sizeof (b1)), p->index, p->refcnt, p->bindcnt);
>
> if (show_stats) {
> if (tb[TCA_SKBEDIT_TM]) {
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Hello cong, seems no big benifit I can see for the patch...
--
Den
^ permalink raw reply
* RE: [PATCHv3 ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: David Laight @ 2015-01-28 9:53 UTC (permalink / raw)
To: 'David Miller'
Cc: fan.du@intel.com, steffen.klassert@secunet.com,
herbert@gondor.apana.org.au, netdev@vger.kernel.org,
fengyuleidian0615@gmail.com
In-Reply-To: <20150127.112406.159033030097516231.davem@davemloft.net>
From: David Miller
> From: David Laight <David.Laight@ACULAB.COM>
> Date: Tue, 27 Jan 2015 09:46:21 +0000
>
> > From: Fan Du
> >> structure like xfrm_usersa_info or xfrm_userpolicy_info
> >> has different sizeof when compiled as 32bits and 64bits
> >> due to not appending pack attribute in their definition.
> >
> > Don't 'pack' the structure, just ensure that all the fields
> > are fixed sized and on their natural boundary.
>
> This horse went out of the door more than a decade ago, we can't
> change the layout of any of these structures and must at some point
> add code to translate instead.
>From the other mail it might just be tail-padding.
So any adaption code is easy.
David
^ permalink raw reply
* Re: A problem about ICMP packet-too-big message handler
From: Yang Yingliang @ 2015-01-29 3:16 UTC (permalink / raw)
To: Steffen Klassert; +Cc: netdev, David S. Miller
In-Reply-To: <20150128121026.GM13046@secunet.com>
On 2015/1/28 20:10, Steffen Klassert wrote:
> On Tue, Jan 27, 2015 at 08:58:53PM +0800, Yang Yingliang wrote:
>> Hi,
>>
>> My kernel is 3.10 LTS.
>>
>> I got a problem here about handling ICMP packet-too-big message.
>>
>> Before sending a packet-too-big packet :
>>
>> # ip -6 route list table local
>> local ::1 dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80::1 dev lo metric 0 //It does not have expire value
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:2 dev lo metric 0
>> local fe80::5054:ff:fe12:3456 dev lo metric 0
>>
>>
>> After sending a packet-too-big packet
>>
>> ip -6 route list table local
>> local ::1 dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80:: dev lo metric 0
>> local fe80::1 dev lo metric 0 expires _597_ //It has expire value
>
> Is this route still present after the expiration time is elapsed?
>
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:0 dev lo metric 0
>> local fe80::200:ff:fe00:2 dev lo metric 0
>> local fe80::5054:ff:fe12:3456 dev lo metric 0
>>
>> When time is up, I can't ping fe80::1 .
>> Is it ok or a bug ?
>
> This looks pretty similar to a bug I discovered recently.
> In my case, a ipv6 host route dissapeared 10 minutes after
> a PMTU event. As a result, this host was not reachable
> anymore.
>
> This happens because we don't clone host routes before
> we use them. If a PMTU event happens, the original route
> is marked with an expire value. After the expiration time
> is elapsed, the original route is deleted and we loose
> conectivity to the host.
>
> I'm currently testing patches to fix this. With these
> patches the ipv6 host routes are cloned if they are
> gateway routes, i.e. if PMTU events can happen.
>
> I fear it will not fix your case because PMTU events are
> not expected to happen at local fe80 routes.
I found current kernel will do ip6_update_pmtu() anyway after
receiving an ICMPV6_PKT_TOOBIG type packet in icmpv6_err().
Does it need some more condition ? Like this:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index a5e95199585e..7c0a28add109 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -89,8 +89,10 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
/* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
struct net *net = dev_net(skb->dev);
+ const struct ipv6hdr *iph = (struct ipv6hdr *) skb->data;
- if (type == ICMPV6_PKT_TOOBIG)
+ if (type == ICMPV6_PKT_TOOBIG &&
+ !(ipv6_addr_type(&iph->daddr) & IPV6_ADDR_LINKLOCAL))
ip6_update_pmtu(skb, net, info, 0, 0);
else if (type == NDISC_REDIRECT)
ip6_redirect(skb, net, skb->dev->ifindex, 0);
Regards,
Yang
^ permalink raw reply related
* [PATCH net] ppp: deflate: never return len larger than output buffer
From: Florian Westphal @ 2015-01-28 9:56 UTC (permalink / raw)
To: netdev; +Cc: Florian Westphal
When we've run out of space in the output buffer to store more data, we
will call zlib_deflate with a NULL output buffer until we've consumed
remaining input.
When this happens, olen contains the size the output buffer would have
consumed iff we'd have had enough room.
This can later cause skb_over_panic when ppp_generic skb_put()s
the returned length.
Reported-by: Iain Douglas <centos@1n6.org.uk>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c
index 602c625..b5edc7f 100644
--- a/drivers/net/ppp/ppp_deflate.c
+++ b/drivers/net/ppp/ppp_deflate.c
@@ -246,7 +246,7 @@ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
/*
* See if we managed to reduce the size of the packet.
*/
- if (olen < isize) {
+ if (olen < isize && olen <= osize) {
state->stats.comp_bytes += olen;
state->stats.comp_packets++;
} else {
--
2.0.5
^ permalink raw reply related
* Re: [PATCH] bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify
From: roopa @ 2015-01-28 14:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stephen, rami.rosen
In-Reply-To: <54C8E62C.5040603@cumulusnetworks.com>
On 1/28/15, 5:37 AM, roopa wrote:
> On 1/27/15, 11:05 PM, David Miller wrote:
>> From: roopa@cumulusnetworks.com
>> Date: Tue, 27 Jan 2015 21:46:24 -0800
>>
>>> From: Roopa Prabhu <roopa@cumulusnetworks.com>
>>>
>>> Reported in: https://bugzilla.kernel.org/show_bug.cgi?id=92081
>>>
>>> This patch avoids calling rtnl_notify if the device ndo_bridge_getlink
>>> handler does not return any bytes in the skb.
>>>
>>> Alternately, the skb->len check can be moved inside rtnl_notify.
>>>
>>> For the bridge vlan case described in 92081, there is also a fix needed
>>> in bridge driver to generate a proper notification. Will fix that in
>>> subsequent patch.
>>>
>>> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>> This doesn't apply to the 'net' tree, is there something I missed?
> sorry, that's me. This should be net-next. Resubmitting with net-next
> in the PATCH line.
>
A few more details ...
....This bug exists in 'net' tree (and I believe previous releases) as
well.
However my patch was generated on net-next, And there are other changes
in the related area in net-next tree hence the patch will not apply on
'net'.
Looks like its better for me to regenerate and submit against 'net'.
will do.
Thanks,
Roopa
^ permalink raw reply
* Re: [patch net-next] hisilicon: add some missing curly braces
From: Ding Tianhong @ 2015-01-29 2:50 UTC (permalink / raw)
To: Dan Carpenter
Cc: Zhangfei Gao, David S. Miller, Arnd Bergmann, netdev,
kernel-janitors
In-Reply-To: <20150128185833.GA10259@mwanda>
On 2015/1/29 2:58, Dan Carpenter wrote:
> The if block was supposed to have curly braces. In the current code we
> complain about dropped rx packets when we shouldn't.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
Acked-by: Ding Tianhong <dingtianhong@huawei.com>
Good catch. thanks;
Hi David, this patch looks good to me, and I was preparing a series patches for hip04,
I could add this patch to the series or you could apply this alone as your wish.:)
Ding
> diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
> index 525214e..c02b81b 100644
> --- a/drivers/net/ethernet/hisilicon/hip04_eth.c
> +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
> @@ -567,10 +567,11 @@ static irqreturn_t hip04_mac_interrupt(int irq, void *dev_id)
> writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT);
>
> if (unlikely(ists & DEF_INT_ERR)) {
> - if (ists & (RCV_NOBUF | RCV_DROP))
> + if (ists & (RCV_NOBUF | RCV_DROP)) {
> stats->rx_errors++;
> stats->rx_dropped++;
> netdev_err(ndev, "rx drop\n");
> + }
> if (ists & TX_DROP) {
> stats->tx_dropped++;
> netdev_err(ndev, "tx drop\n");
>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox