* RE: [PATCH] net: remove sock_iocb
From: Jon Maloy @ 2015-01-29 12:13 UTC (permalink / raw)
To: David Miller, viro@ZenIV.linux.org.uk; +Cc: hch@lst.de, netdev@vger.kernel.org
In-Reply-To: <20150129.000125.1532086382063848714.davem@davemloft.net>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of David Miller
> Sent: January-29-15 3:01 AM
> To: viro@ZenIV.linux.org.uk
> Cc: hch@lst.de; netdev@vger.kernel.org
> Subject: Re: [PATCH] net: remove sock_iocb
>
> From: Al Viro <viro@ZenIV.linux.org.uk>
> Date: Thu, 29 Jan 2015 07:57:21 +0000
>
> > You know, that's getting _really_ interesting. The thing is, now
> > there's only one ->sendmsg() instance using iocb argument at all, and
> > it's a really weird one. TIPC. Which only compares it with NULL, and
> > that - to tell the normal calls (== done by sock_sendmsg()
> > et.al.) from tipc_{accept,connect}()-generated ones. And the way it's
> > used is
> > if (iocb)
> > lock_sock(sk);
> > in tipc_send_stream(). IOW, "tipc_accept() and tipc_connect() would
> > like to use the guts of tipc_send_stream(), but they are already
> > holding the socket locked; let's just pass NULL iocb (which
> > net/socket.c never does) to tell it to leave the fucking lock alone, thank you
> very much".
> >
> > And no ->recvmsg() are using iocb at all now. How about we take the
> > guts of tipc_send_stream() into a helper function and have
> > tipc_accept/connect use _that_?
Sounds reasonable. We'll look into this.
///jon
Then we could drop iocb argument
> > completely and for ->sendmsg() it would be the difference between 4
> > and 3 arguments, which has interesting effects on certain register-starved
> architectures...
> >
> > While we are at it, size (both for sendmsg and recvmsg) is always
> > equal to iov_iter_count(&msg->msg_iter), so that's not the only
> > redundant argument there...
>
> No objections from me.
> --
> 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
^ permalink raw reply
* Re: [PATCH v2 linux-trace 1/8] tracing: attach eBPF programs to tracepoints and syscalls
From: Namhyung Kim @ 2015-01-29 12:35 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: <CAMEtUuzSDYYWneoTy9=AmMa9=x4owWbWsXod=Do54+yj4Je3=Q@mail.gmail.com>
On Thu, Jan 29, 2015 at 4:04 PM, Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org> wrote:
> On Wed, Jan 28, 2015 at 10:41 PM, Namhyung Kim <namhyung-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>
>> 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.
>
> ok. I think it does indeed make sense to decouple the logic.
> We can add 'auto_enable' file to achieve desired Ctrl-C behavior.
> While the 'auto_enable' file is open the event will be enabled
> and writes to 'enable' file will be ignored.
> As soon as file closes, the event is auto-disabled.
> Then user space will use 'bpf' file to attach/auto-unload
> and 'auto_enable' file together.
> Seem there would be a use for such 'auto_enable'
> without bpf as well.
Why do you want such an 'auto_enable' feature? I guess it's enough
just to keep an event in the soft-disabled state and run a bpf program
before the check.
>
>> 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?
>
> ok, I think 'if (in_nmi()) return 1;' will work then, right?
> Or you're thinking something else ?
Nope, returning 1 would be okay..
>
>> 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..
>
> yes. I did. Please see my reply to Masami.
> ioctl only works for tracepoints.
What was the problem of kprobes then? :)
Thanks,
Namhyung
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-01-29 13:14 UTC (permalink / raw)
To: Michal Kazior; +Cc: linux-wireless, Network Development, eyalpe
In-Reply-To: <CA+BoTQkVu23P3EOmY_Q3E1GJnWsyF==Pawz4iPOS_Bq5dvfO5Q@mail.gmail.com>
On Thu, 2015-01-29 at 12:48 +0100, Michal Kazior wrote:
> Hi,
>
> I'm not subscribed to netdev list and I can't find the message-id so I
> can't reply directly to the original thread `BW regression after "tcp:
> refine TSO autosizing"`.
>
> I've noticed a big TCP performance drop with ath10k
> (drivers/net/wireless/ath/ath10k) on 3.19-rc5. Instead of 500mbps I
> get 250mbps in my testbed.
>
> After bisecting I ended up at `tcp: refine TSO autosizing`. Reverting
> `tcp: refine TSO autosizing` and `tcp: Do not apply TSO segment limit
> to non-TSO packets` (for conflict free reverts) fixes the problem.
>
> My testing setup is as follows:
>
> a) ath10k AP, github.com/kvalo/ath/tree/master 3.19-rc5, w/ reverts
> b) ath10k STA connected to (a), github.com/kvalo/ath/tree/master
> 3.19-rc5, w/ reverts
> c) (b) w/o reverts
>
> Devices are 3x3 (AP) and 2x2 (Client) and are RF cabled. 11ac@80MHz
> 2x2 has 866mbps modulation rate. In practice this should deliver
> ~700mbps of real UDP traffic.
>
> Here are some numbers:
>
> UDP: (b) -> (a): 672mbps
> UDP: (a) -> (b): 687mbps
> TCP: (b) -> (a): 526mbps
> TCP: (a) -> (b): 500mbps
>
> UDP: (c) -> (a): 669mbps*
> UDP: (a) -> (c): 689mbps*
> TCP: (c) -> (a): 240mbps**
> TCP: (a) -> (c): 490mbps*
>
> * no changes/within error margin
> ** the performance drop
>
> I'm using iperf:
> UDP: iperf -i1 -s -u vs iperf -i1 -c XX -u -B 200M -P5 -t 20
> TCP: iperf -i1 -s vs iperf -i1 -c XX -P5 -t 20
>
> Result values were obtained at the receiver side.
>
> Iperf reports a few frames lost and out-of-order at each UDP test
> start (during first second) but later has no packet loss and no
> out-of-order. This shouldn't have any effect on a TCP session, right?
>
> The device delivers batched up tx/rx completions (no way to change
> that). I suppose this could be an issue for timing sensitive
> algorithms. Also keep in mind 802.11n and 802.11ac devices have frame
> aggregation windows so there's an inherent extra (and non-uniform)
> latency when compared to, e.g. ethernet devices.
>
> The driver doesn't have GRO. I have an internal patch which implements
> it. It improves overall TCP traffic (more stable, up to 600mbps TCP
> which is ~100mbps more than without GRO) but the TCP: (c) -> (a)
> performance drop remains unaffected regardless.
>
> I've tried applying stretch ACK patchset (v2) on both machines and
> re-run the above tests. I got no measurable difference in performance.
>
> I've also run these tests with iwlwifi 7260 (also a 2x2) as (b) and
> (c). It didn't seem to be affected by the TSO patch at all (it runs at
> ~360mbps of TCP regardless of the TSO patch).
>
> Any hints/ideas?
>
Hi Michal
This patch restored original TSQ behavior, because the 1ms worth of data
per flow had totally destroyed TSQ intent.
vi +630 Documentation/networking/ip-sysctl.txt
tcp_limit_output_bytes - INTEGER
Controls TCP Small Queue limit per tcp socket.
TCP bulk sender tends to increase packets in flight until it
gets losses notifications. With SNDBUF autotuning, this can
result in a large amount of packets queued in qdisc/device
on the local machine, hurting latency of other flows, for
typical pfifo_fast qdiscs.
tcp_limit_output_bytes limits the number of bytes on qdisc
or device to reduce artificial RTT/cwnd and reduce bufferbloat.
Default: 131072
This is why I suggested to Eyal Perry to change the TX interrupt
mitigation parameters as in :
ethtool -C eth0 tx-frames 4 rx-frames 4
With this change and the stretch ack fixes, I got 37Gbps of throughput
on a single flow, on a 40Gbit NIC (mlx4)
If a driver needs to buffer more than tcp_limit_output_bytes=131072 to
get line rate, I suggest that you either :
1) tweak tcp_limit_output_bytes, but its not practical from a driver.
2) change the driver, knowing what are its exact requirements, by
removing a fraction of skb->truesize at ndo_start_xmit() time as in :
if ((skb->destructor == sock_wfree ||
skb->restuctor == tcp_wfree) &&
skb->sk) {
u32 fraction = skb->truesize / 2;
skb->truesize -= fraction;
atomic_sub(fraction, &skb->sk->sk_wmem_alloc);
}
Thanks.
^ permalink raw reply
* Re: [PATCH net] net: sctp: fix passing wrong parameter header to param_type2af in sctp_process_param
From: Vlad Yasevich @ 2015-01-29 13:27 UTC (permalink / raw)
To: Daniel Borkmann, davem; +Cc: netdev, linux-sctp, Saran Maruti Ramanara
In-Reply-To: <1422525958-5737-1-git-send-email-dborkman@redhat.com>
On 01/29/2015 05:05 AM, Daniel Borkmann wrote:
> From: Saran Maruti Ramanara <saran.neti@telus.com>
>
> When making use of RFC5061, section 4.2.4. for setting the primary IP
> address, we're passing a wrong parameter header to param_type2af(),
> resulting always in NULL being returned.
>
> At this point, param.p points to a sctp_addip_param struct, containing
> a sctp_paramhdr (type = 0xc004, length = var), and crr_id as a correlation
> id. Followed by that, as also presented in RFC5061 section 4.2.4., comes
> the actual sctp_addr_param, which also contains a sctp_paramhdr, but
> this time with the correct type SCTP_PARAM_IPV{4,6}_ADDRESS that
> param_type2af() can make use of. Since we already hold a pointer to
> addr_param from previous line, just reuse it for param_type2af().
>
> Fixes: d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT")
> Signed-off-by: Saran Maruti Ramanara <saran.neti@telus.com>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Thanks
-vlad
> ---
> net/sctp/sm_make_chunk.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index e49e231..06320c8 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -2608,7 +2608,7 @@ do_addr_param:
>
> addr_param = param.v + sizeof(sctp_addip_param_t);
>
> - af = sctp_get_af_specific(param_type2af(param.p->type));
> + af = sctp_get_af_specific(param_type2af(addr_param->p.type));
> if (af == NULL)
> break;
>
>
^ permalink raw reply
* Re: [PATCH v2 3/3] lib/string_helpers.c: Change semantics of string_escape_mem
From: Andy Shevchenko @ 2015-01-29 13:29 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Andrew Morton, Trond Myklebust, J. Bruce Fields, David S. Miller,
linux-kernel, linux-nfs, netdev
In-Reply-To: <1422525801-26560-4-git-send-email-linux@rasmusvillemoes.dk>
On Thu, 2015-01-29 at 11:03 +0100, Rasmus Villemoes wrote:
Thanks for an update.
Few comments below.
> The current semantics of string_escape_mem are inadequate for one of
> its two current users, vsnprintf(). If that is to honour its contract,
> it must know how much space would be needed for the entire escaped
> buffer, and string_escape_mem provides no way of obtaining that (short
> of allocating a large enough buffer (~4 times input string) to let it
> play with, and that's definitely a big no-no inside vsnprintf).
>
> So change the semantics for string_escape_mem to be more
> snprintf-like: Return the size of the output that would be generated
> if the destination buffer was big enough, but of course still only
> write to the part of dst it is allowed to, and don't do
> '\0'-termination. It is then up to the caller to detect whether output
> was truncated and to append a '\0' if desired.
>
> This also fixes a bug in the escaped_string() helper function, which
> used to unconditionally pass a length of "end-buf" to
> string_escape_mem(); since the latter doesn't check osz for being
> insanely large, it would happily write to dst. For example,
> kasprintf(GFP_KERNEL, "something and then %pE", ...); is an easy way
> to trigger an oops.
>
> In test-string_helpers.c, I removed the now meaningless -ENOMEM test,
> and replaced it with testing for getting the expected return value
> even if the buffer is too small. Also ensure that nothing is written
> when osz==0.
'osz == 0'
>
> In net/sunrpc/cache.c, I think qword_add still has the same
> semantics. Someone should definitely double-check this.
> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> ---
> include/linux/string_helpers.h | 10 +++++-----
> lib/string_helpers.c | 25 ++++++++-----------------
> lib/test-string_helpers.c | 37 ++++++++++++++++---------------------
> lib/vsprintf.c | 2 +-
> net/sunrpc/cache.c | 8 +++++---
> 5 files changed, 35 insertions(+), 47 deletions(-)
>
> diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
> index 6eb567ac56bc..7a082aa183a8 100644
> --- a/include/linux/string_helpers.h
> +++ b/include/linux/string_helpers.h
> @@ -47,22 +47,22 @@ static inline int string_unescape_any_inplace(char *buf)
> #define ESCAPE_ANY_NP (ESCAPE_ANY | ESCAPE_NP)
> #define ESCAPE_HEX 0x20
>
> -int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
> +size_t string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
> unsigned int flags, const char *esc);
>
> -static inline int string_escape_mem_any_np(const char *src, size_t isz,
> - char **dst, size_t osz, const char *esc)
> +static inline size_t string_escape_mem_any_np(const char *src, size_t isz,
> + char *dst, size_t osz, const char *esc)
> {
> return string_escape_mem(src, isz, dst, osz, ESCAPE_ANY_NP, esc);
> }
>
> -static inline int string_escape_str(const char *src, char **dst, size_t sz,
> +static inline size_t string_escape_str(const char *src, char *dst, size_t sz,
> unsigned int flags, const char *esc)
> {
> return string_escape_mem(src, strlen(src), dst, sz, flags, esc);
> }
>
> -static inline int string_escape_str_any_np(const char *src, char **dst,
> +static inline size_t string_escape_str_any_np(const char *src, char *dst,
> size_t sz, const char *esc)
> {
> return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, esc);
> diff --git a/lib/string_helpers.c b/lib/string_helpers.c
> index e14dd8555760..05d4a583d20e 100644
> --- a/lib/string_helpers.c
> +++ b/lib/string_helpers.c
> @@ -414,20 +414,17 @@ static bool escape_hex(unsigned char c, char **dst, char *end)
> * it if needs.
> *
> * Return:
> - * The amount of the characters processed to the destination buffer, or
> - * %-ENOMEM if the size of buffer is not enough to put an escaped character is
> - * returned.
> - *
> - * Even in the case of error @dst pointer will be updated to point to the byte
> - * after the last processed character.
> + * The total size of the escaped output that would be generated for
> + * the given input and flags. To check whether the output was
> + * truncated, compare the return value to osz. There is room left in
> + * dst for a '\0' terminator if and only if ret < osz.
> */
> -int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
> - unsigned int flags, const char *esc)
> +size_t string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
> + unsigned int flags, const char *esc)
I prefer to leave the prototype the same. int for return is okay. dst
should be updated accordingly.
> {
> - char *p = *dst;
> + char *p = dst;
> char *end = p + osz;
> bool is_dict = esc && *esc;
> - int ret;
>
> while (isz--) {
> unsigned char c = *src++;
> @@ -466,13 +463,7 @@ int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
>
> escape_passthrough(c, &p, end);
> }
> - if (p > end) {
> - *dst = end;
> - return -ENOMEM;
> - }
>
> - ret = p - *dst;
> - *dst = p;
> - return ret;
> + return p - dst;
> }
> EXPORT_SYMBOL(string_escape_mem);
> diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
> index ab0d30e1e18f..5f95114a2f86 100644
> --- a/lib/test-string_helpers.c
> +++ b/lib/test-string_helpers.c
> @@ -264,12 +264,12 @@ static __init void test_string_escape(const char *name,
> const struct test_string_2 *s2,
> unsigned int flags, const char *esc)
> {
> - int q_real = 512;
> - char *out_test = kmalloc(q_real, GFP_KERNEL);
> - char *out_real = kmalloc(q_real, GFP_KERNEL);
> + size_t out_size = 512;
> + char *out_test = kmalloc(out_size, GFP_KERNEL);
> + char *out_real = kmalloc(out_size, GFP_KERNEL);
> char *in = kmalloc(256, GFP_KERNEL);
> - char *buf = out_real;
> - int p = 0, q_test = 0;
> + size_t p = 0, q_test = 0;
> + size_t q_real;
>
> if (!out_test || !out_real || !in)
> goto out;
> @@ -301,29 +301,26 @@ static __init void test_string_escape(const char *name,
> q_test += len;
> }
>
> - q_real = string_escape_mem(in, p, &buf, q_real, flags, esc);
> + q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
>
> test_string_check_buf(name, flags, in, p, out_real, q_real, out_test,
> q_test);
> +
> + memset(out_real, 'Z', out_size);
> + q_real = string_escape_mem(in, p, out_real, 0, flags, esc);
> + if (q_real != q_test)
> + pr_warn("Test '%s' failed: flags = %u, osz = 0, expected %zu, got %zu\n",
> + name, flags, q_test, q_real);
> + if (memchr_inv(out_real, 'Z', out_size))
> + pr_warn("Test '%s' failed: osz = 0 but string_escape_mem wrote to the buffer\n",
> + name);
Could it be a part of nomem test still?
> +
> out:
> kfree(in);
> kfree(out_real);
> kfree(out_test);
> }
>
> -static __init void test_string_escape_nomem(void)
> -{
> - char *in = "\eb \\C\007\"\x90\r]";
> - char out[64], *buf = out;
> - int rc = -ENOMEM, ret;
> -
> - ret = string_escape_str_any_np(in, &buf, strlen(in), NULL);
> - if (ret == rc)
> - return;
> -
> - pr_err("Test 'escape nomem' failed: got %d instead of %d\n", ret, rc);
> -}
> -
> static int __init test_string_helpers_init(void)
> {
> unsigned int i;
> @@ -342,8 +339,6 @@ static int __init test_string_helpers_init(void)
> for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++)
> test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
>
> - test_string_escape_nomem();
> -
> return -EINVAL;
> }
> module_init(test_string_helpers_init);
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 3568e3906777..d02c394b5b58 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -1160,7 +1160,7 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
> len = spec.field_width < 0 ? 1 : spec.field_width;
>
> /* Ignore the error. We print as many characters as we can */
> - string_escape_mem(addr, len, &buf, end - buf, flags, NULL);
> + buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL);
So, the problem is when we have end < buf, right?
How about to move this check out of the call parameters?
[Keep in might the original prototype]
if (buf < end)
string_escape_mem(addr, len, &buf, end - buf, flags, NULL);
else
string_escape_mem(addr, len, &buf, 0, flags, NULL);
I don't know if it's a good idea to check this inside
string_escape_mem(). Possible not.
>
> return buf;
> }
> diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
> index 33fb105d4352..22c4418057f4 100644
> --- a/net/sunrpc/cache.c
> +++ b/net/sunrpc/cache.c
> @@ -1068,12 +1068,14 @@ void qword_add(char **bpp, int *lp, char *str)
> {
> char *bp = *bpp;
> int len = *lp;
> - int ret;
> + int ret, written;
>
> if (len < 0) return;
>
> - ret = string_escape_str(str, &bp, len, ESCAPE_OCTAL, "\\ \n\t");
> - if (ret < 0 || ret == len)
> + ret = string_escape_str(str, bp, len, ESCAPE_OCTAL, "\\ \n\t");
> + written = min(ret, len);
> + bp += written;
> + if (ret >= len)
> len = -1;
> else {
> len -= ret;
For this part the comment from J. Bruce is needed.
There is one more user, i.e. fs/proc/array.c::task_name().
In all of them we have to amend a prepend commentary. Like changing
'Ignore the error' to 'Ignore the overflow'.
--
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy
^ permalink raw reply
* Fw: [Bug 92281] New: Raspberry Pi crashes under network load
From: Stephen Hemminger @ 2015-01-29 13:36 UTC (permalink / raw)
To: netdev
Begin forwarded message:
Date: Thu, 29 Jan 2015 05:26:08 -0800
From: "bugzilla-daemon@bugzilla.kernel.org" <bugzilla-daemon@bugzilla.kernel.org>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Subject: [Bug 92281] New: Raspberry Pi crashes under network load
https://bugzilla.kernel.org/show_bug.cgi?id=92281
Bug ID: 92281
Summary: Raspberry Pi crashes under network load
Product: Networking
Version: 2.5
Kernel Version: Linux raspberrypi 3.12.35+ #730 PREEMPT Fri Dec 19
18:31:24 GMT 2014 armv6l
Hardware: ARM
OS: Linux
Tree: PREEMPT_RT
Status: NEW
Severity: normal
Priority: P1
Component: IPV4
Assignee: shemminger@linux-foundation.org
Reporter: morphex@gmail.com
Regression: No
Created attachment 165141
--> https://bugzilla.kernel.org/attachment.cgi?id=165141&action=edit
First kernel panic
I've setup a Raspberry PI as a simple router, which connects to a WiFi access
point. My desktop is then connected to the RPI using an ethernet cable, and the
Raspberry Pi has an USB Ethernet dongle.
I've attached pictures of the screen on two different kernel panics.
Here's the USB setup:
Bus 001 Device 002: ID 05e3:0606 Genesys Logic, Inc. USB 2.0 Hub / D-Link
DUB-H4 USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0bda:8176 Realtek Semiconductor Corp. RTL8188CUS 802.11n
WLAN Adapter
Bus 001 Device 004: ID 09da:054f A4 Tech Co., Ltd
Bus 001 Device 005: ID 0fe6:9700 Kontron (Industrial Computer Source / ICS
Advent) DM9601 Fast Ethernet Adapter
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* RE: [PATCHv3, ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: David Laight @ 2015-01-29 13:56 UTC (permalink / raw)
To: 'nicolas.dichtel@6wind.com', Fan Du,
steffen.klassert@secunet.com
Cc: herbert@gondor.apana.org.au, davem@davemloft.net,
netdev@vger.kernel.org, fengyuleidian0615@gmail.com
In-Reply-To: <54CA0B9F.8080104@6wind.com>
From: Nicolas Dichtel
> Le 27/01/2015 10:00, Fan Du a crit :
> > 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.
> > This will result in broken SA and SP information when user
> > trying to configure them through netlink interface.
> >
> > Inform user land about this situation instead of keeping
> > silent, the upper test scripts would behave accordingly.
> >
> > Quotes from: http://marc.info/?l=linux-netdev&m=142226348715503&w=2
> >>
> >> Before a clean solution show up, I think it's better to warn user in some way
> >> like http://patchwork.ozlabs.org/patch/323842/ did. Otherwise, many people
> >> who stuck there will always spend time and try to fix this issue in whatever way.
> >
> > Yes, this is the first thing we should do. I'm willing to accept a patch
> >
> > Signed-off-by: Fan Du <fan.du@intel.com>
> A way to solve this problem was to provide to userland a xfrm compat header
> file, which match the ABI of the kernel. Something like:
>
> #include <linux/xfrm.h>
>
> #define xfrm_usersa_info xfrm_usersa_info_64
> #define xfrm_usersa_info_compat xfrm_usersa_info
> struct xfrm_usersa_info_compat {
> struct xfrm_selector sel;
> struct xfrm_id id;
> xfrm_address_t saddr;
> struct xfrm_lifetime_cfg lft;
> struct xfrm_lifetime_cur curlft;
> struct xfrm_stats stats;
> __u32 seq;
> __u32 reqid;
> __u16 family;
> __u8 mode;
> __u8 replay_window;
> __u8 flags;
> __u8 hole1;
> __u32 hole2;
> };
>
> The point I try to make is that patching userland apps allows to use xfrm on a
> 32bits userland / 64bits kernel.
>
> If I understand well your patch, it will not be possible anymore, all messages
> will be rejected. And this may break existing apps.
Probably OTT in this case.
IIRC the only actual difference if the 'end padding'.
So the wrapper need only ensure the copyin/out isn't too long.
Probably worth compile-time checks for the size.
If the structure is being copied to user then zero values need assigning
to the pad fields (unless read from user).
David
^ permalink raw reply
* Re: [PATCHv3, ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: Nicolas Dichtel @ 2015-01-29 14:14 UTC (permalink / raw)
To: David Laight, Fan Du, steffen.klassert@secunet.com
Cc: herbert@gondor.apana.org.au, davem@davemloft.net,
netdev@vger.kernel.org, fengyuleidian0615@gmail.com
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1CAD56B0@AcuExch.aculab.com>
Le 29/01/2015 14:56, David Laight a écrit :
> From: Nicolas Dichtel
>> Le 27/01/2015 10:00, Fan Du a crit :
>>> 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.
>>> This will result in broken SA and SP information when user
>>> trying to configure them through netlink interface.
>>>
>>> Inform user land about this situation instead of keeping
>>> silent, the upper test scripts would behave accordingly.
>>>
>>> Quotes from: http://marc.info/?l=linux-netdev&m=142226348715503&w=2
>>>>
>>>> Before a clean solution show up, I think it's better to warn user in some way
>>>> like http://patchwork.ozlabs.org/patch/323842/ did. Otherwise, many people
>>>> who stuck there will always spend time and try to fix this issue in whatever way.
>>>
>>> Yes, this is the first thing we should do. I'm willing to accept a patch
>>>
>>> Signed-off-by: Fan Du <fan.du@intel.com>
>> A way to solve this problem was to provide to userland a xfrm compat header
>> file, which match the ABI of the kernel. Something like:
>>
>> #include <linux/xfrm.h>
>>
>> #define xfrm_usersa_info xfrm_usersa_info_64
>> #define xfrm_usersa_info_compat xfrm_usersa_info
>> struct xfrm_usersa_info_compat {
>> struct xfrm_selector sel;
>> struct xfrm_id id;
>> xfrm_address_t saddr;
>> struct xfrm_lifetime_cfg lft;
>> struct xfrm_lifetime_cur curlft;
>> struct xfrm_stats stats;
>> __u32 seq;
>> __u32 reqid;
>> __u16 family;
>> __u8 mode;
>> __u8 replay_window;
>> __u8 flags;
>> __u8 hole1;
>> __u32 hole2;
>> };
>>
>> The point I try to make is that patching userland apps allows to use xfrm on a
>> 32bits userland / 64bits kernel.
>>
>> If I understand well your patch, it will not be possible anymore, all messages
>> will be rejected. And this may break existing apps.
>
> Probably OTT in this case.
> IIRC the only actual difference if the 'end padding'.
> So the wrapper need only ensure the copyin/out isn't too long.
It was just an example for one struct. Some other structures need to be
patched (eg struct xfrm_userspi_info uses struct xfrm_usersa_info).
And some attributes may follow this structure which will be padded to
be aligned.
The point was more to show that the existing interface can be used (and cannot
be used after the patch).
Regards,
Nicolas
^ permalink raw reply
* Re: [PATCH v2 3/3] lib/string_helpers.c: Change semantics of string_escape_mem
From: Rasmus Villemoes @ 2015-01-29 14:29 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Andrew Morton, Trond Myklebust, J. Bruce Fields, David S. Miller,
linux-kernel, linux-nfs, netdev
In-Reply-To: <1422538178.31903.325.camel@linux.intel.com>
On Thu, Jan 29 2015, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>> *
>> * Return:
>> - * The amount of the characters processed to the destination buffer, or
>> - * %-ENOMEM if the size of buffer is not enough to put an escaped character is
>> - * returned.
>> - *
>> - * Even in the case of error @dst pointer will be updated to point to the byte
>> - * after the last processed character.
>> + * The total size of the escaped output that would be generated for
>> + * the given input and flags. To check whether the output was
>> + * truncated, compare the return value to osz. There is room left in
>> + * dst for a '\0' terminator if and only if ret < osz.
>> */
>> -int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
>> - unsigned int flags, const char *esc)
>> +size_t string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
>> + unsigned int flags, const char *esc)
>
> I prefer to leave the prototype the same. int for return is okay. dst
> should be updated accordingly.
Please explain exactly what you think the return value should be, and
what *dst should be set to.
>> {
>> - char *p = *dst;
>> + char *p = dst;
>> char *end = p + osz;
>> bool is_dict = esc && *esc;
>> - int ret;
>>
>> while (isz--) {
>> unsigned char c = *src++;
>> @@ -466,13 +463,7 @@ int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz,
>>
>> escape_passthrough(c, &p, end);
>> }
>> - if (p > end) {
>> - *dst = end;
>> - return -ENOMEM;
>> - }
>>
>> - ret = p - *dst;
>> - *dst = p;
>> - return ret;
>> + return p - dst;
>> }
>> EXPORT_SYMBOL(string_escape_mem);
>> diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c
>> index ab0d30e1e18f..5f95114a2f86 100644
>> --- a/lib/test-string_helpers.c
>> +++ b/lib/test-string_helpers.c
>> @@ -264,12 +264,12 @@ static __init void test_string_escape(const char *name,
>> const struct test_string_2 *s2,
>> unsigned int flags, const char *esc)
>> {
>> - int q_real = 512;
>> - char *out_test = kmalloc(q_real, GFP_KERNEL);
>> - char *out_real = kmalloc(q_real, GFP_KERNEL);
>> + size_t out_size = 512;
>> + char *out_test = kmalloc(out_size, GFP_KERNEL);
>> + char *out_real = kmalloc(out_size, GFP_KERNEL);
>> char *in = kmalloc(256, GFP_KERNEL);
>> - char *buf = out_real;
>> - int p = 0, q_test = 0;
>> + size_t p = 0, q_test = 0;
>> + size_t q_real;
>>
>> if (!out_test || !out_real || !in)
>> goto out;
>> @@ -301,29 +301,26 @@ static __init void test_string_escape(const char *name,
>> q_test += len;
>> }
>>
>> - q_real = string_escape_mem(in, p, &buf, q_real, flags, esc);
>> + q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
>>
>> test_string_check_buf(name, flags, in, p, out_real, q_real, out_test,
>> q_test);
>> +
>> + memset(out_real, 'Z', out_size);
>> + q_real = string_escape_mem(in, p, out_real, 0, flags, esc);
>> + if (q_real != q_test)
>> + pr_warn("Test '%s' failed: flags = %u, osz = 0, expected %zu, got %zu\n",
>> + name, flags, q_test, q_real);
>> + if (memchr_inv(out_real, 'Z', out_size))
>> + pr_warn("Test '%s' failed: osz = 0 but string_escape_mem wrote to the buffer\n",
>> + name);
>
> Could it be a part of nomem test still?
What nomem test? string_escape_mem with snprintf-like semantics cannot
return an error; that has to be checked by the caller.
>> +
>> out:
>> kfree(in);
>> kfree(out_real);
>> kfree(out_test);
>> }
>>
>> -static __init void test_string_escape_nomem(void)
>> -{
>> - char *in = "\eb \\C\007\"\x90\r]";
>> - char out[64], *buf = out;
>> - int rc = -ENOMEM, ret;
>> -
>> - ret = string_escape_str_any_np(in, &buf, strlen(in), NULL);
>> - if (ret == rc)
>> - return;
>> -
>> - pr_err("Test 'escape nomem' failed: got %d instead of %d\n", ret, rc);
>> -}
>> -
>> static int __init test_string_helpers_init(void)
>> {
>> unsigned int i;
>> @@ -342,8 +339,6 @@ static int __init test_string_helpers_init(void)
>> for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++)
>> test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
>>
>> - test_string_escape_nomem();
>> -
>> return -EINVAL;
>> }
>> module_init(test_string_helpers_init);
>> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
>> index 3568e3906777..d02c394b5b58 100644
>> --- a/lib/vsprintf.c
>> +++ b/lib/vsprintf.c
>> @@ -1160,7 +1160,7 @@ char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec,
>> len = spec.field_width < 0 ? 1 : spec.field_width;
>>
>> /* Ignore the error. We print as many characters as we can */
>> - string_escape_mem(addr, len, &buf, end - buf, flags, NULL);
>> + buf += string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, flags, NULL);
>
> So, the problem is when we have end < buf, right?
> How about to move this check out of the call parameters?
>
> [Keep in might the original prototype]
>
> if (buf < end)
> string_escape_mem(addr, len, &buf, end - buf, flags, NULL);
> else
> string_escape_mem(addr, len, &buf, 0, flags, NULL);
In that case, I just did the same as is done for %pV, and prefer to keep
it that way.
>> diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
>> index 33fb105d4352..22c4418057f4 100644
>> --- a/net/sunrpc/cache.c
>> +++ b/net/sunrpc/cache.c
>> @@ -1068,12 +1068,14 @@ void qword_add(char **bpp, int *lp, char *str)
>> {
>> char *bp = *bpp;
>> int len = *lp;
>> - int ret;
>> + int ret, written;
>>
>> if (len < 0) return;
>>
>> - ret = string_escape_str(str, &bp, len, ESCAPE_OCTAL, "\\ \n\t");
>> - if (ret < 0 || ret == len)
>> + ret = string_escape_str(str, bp, len, ESCAPE_OCTAL, "\\ \n\t");
>> + written = min(ret, len);
>> + bp += written;
>> + if (ret >= len)
>> len = -1;
>> else {
>> len -= ret;
>
> For this part the comment from J. Bruce is needed.
>
> There is one more user, i.e. fs/proc/array.c::task_name().
>
> In all of them we have to amend a prepend commentary. Like changing
> 'Ignore the error' to 'Ignore the overflow'.
I hadn't looked for users in -next. I'll leave it to you to amend that
patch before it hits mainline.
Rasmus
^ permalink raw reply
* [PATCH] rhashtable: Make selftest modular
From: Geert Uytterhoeven @ 2015-01-29 14:40 UTC (permalink / raw)
To: Thomas Graf, David S. Miller; +Cc: netdev, linux-kernel, Geert Uytterhoeven
Allow the selftest on the resizable hash table to be built modular, just
like all other tests that do not depend on DEBUG_KERNEL.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
This is against -next
Tested on m68k and arm.
lib/Kconfig.debug | 2 +-
lib/Makefile | 1 +
lib/rhashtable.c | 205 ---------------------------------------------
lib/test_rhashtable.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 229 insertions(+), 206 deletions(-)
create mode 100644 lib/test_rhashtable.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 68668f65ac0d26aa..385553a9e0e45d23 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1605,7 +1605,7 @@ config TEST_KSTRTOX
tristate "Test kstrto*() family of functions at runtime"
config TEST_RHASHTABLE
- bool "Perform selftest on resizable hash table"
+ tristate "Perform selftest on resizable hash table"
default n
help
Enable this option to test the rhashtable functions at boot.
diff --git a/lib/Makefile b/lib/Makefile
index b1dbda74ef65aeff..4755d43f3f4020d4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_TEST_LKM) += test_module.o
obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
obj-$(CONFIG_TEST_BPF) += test_bpf.o
obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
+obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index bc2d0d80d1f91e73..c41e21096373156a 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -935,208 +935,3 @@ void rhashtable_destroy(struct rhashtable *ht)
mutex_unlock(&ht->mutex);
}
EXPORT_SYMBOL_GPL(rhashtable_destroy);
-
-/**************************************************************************
- * Self Test
- **************************************************************************/
-
-#ifdef CONFIG_TEST_RHASHTABLE
-
-#define TEST_HT_SIZE 8
-#define TEST_ENTRIES 2048
-#define TEST_PTR ((void *) 0xdeadbeef)
-#define TEST_NEXPANDS 4
-
-struct test_obj {
- void *ptr;
- int value;
- struct rhash_head node;
-};
-
-static int __init test_rht_lookup(struct rhashtable *ht)
-{
- unsigned int i;
-
- for (i = 0; i < TEST_ENTRIES * 2; i++) {
- struct test_obj *obj;
- bool expected = !(i % 2);
- u32 key = i;
-
- obj = rhashtable_lookup(ht, &key);
-
- if (expected && !obj) {
- pr_warn("Test failed: Could not find key %u\n", key);
- return -ENOENT;
- } else if (!expected && obj) {
- pr_warn("Test failed: Unexpected entry found for key %u\n",
- key);
- return -EEXIST;
- } else if (expected && obj) {
- if (obj->ptr != TEST_PTR || obj->value != i) {
- pr_warn("Test failed: Lookup value mismatch %p!=%p, %u!=%u\n",
- obj->ptr, TEST_PTR, obj->value, i);
- return -EINVAL;
- }
- }
- }
-
- return 0;
-}
-
-static void test_bucket_stats(struct rhashtable *ht, bool quiet)
-{
- unsigned int cnt, rcu_cnt, i, total = 0;
- struct rhash_head *pos;
- struct test_obj *obj;
- struct bucket_table *tbl;
-
- tbl = rht_dereference_rcu(ht->tbl, ht);
- for (i = 0; i < tbl->size; i++) {
- rcu_cnt = cnt = 0;
-
- if (!quiet)
- pr_info(" [%#4x/%zu]", i, tbl->size);
-
- rht_for_each_entry_rcu(obj, pos, tbl, i, node) {
- cnt++;
- total++;
- if (!quiet)
- pr_cont(" [%p],", obj);
- }
-
- rht_for_each_entry_rcu(obj, pos, tbl, i, node)
- rcu_cnt++;
-
- if (rcu_cnt != cnt)
- pr_warn("Test failed: Chain count mismach %d != %d",
- cnt, rcu_cnt);
-
- if (!quiet)
- pr_cont("\n [%#x] first element: %p, chain length: %u\n",
- i, tbl->buckets[i], cnt);
- }
-
- pr_info(" Traversal complete: counted=%u, nelems=%u, entries=%d\n",
- total, atomic_read(&ht->nelems), TEST_ENTRIES);
-
- if (total != atomic_read(&ht->nelems) || total != TEST_ENTRIES)
- pr_warn("Test failed: Total count mismatch ^^^");
-}
-
-static int __init test_rhashtable(struct rhashtable *ht)
-{
- struct bucket_table *tbl;
- struct test_obj *obj;
- struct rhash_head *pos, *next;
- int err;
- unsigned int i;
-
- /*
- * Insertion Test:
- * Insert TEST_ENTRIES into table with all keys even numbers
- */
- pr_info(" Adding %d keys\n", TEST_ENTRIES);
- for (i = 0; i < TEST_ENTRIES; i++) {
- struct test_obj *obj;
-
- obj = kzalloc(sizeof(*obj), GFP_KERNEL);
- if (!obj) {
- err = -ENOMEM;
- goto error;
- }
-
- obj->ptr = TEST_PTR;
- obj->value = i * 2;
-
- rhashtable_insert(ht, &obj->node);
- }
-
- rcu_read_lock();
- test_bucket_stats(ht, true);
- test_rht_lookup(ht);
- rcu_read_unlock();
-
- for (i = 0; i < TEST_NEXPANDS; i++) {
- pr_info(" Table expansion iteration %u...\n", i);
- mutex_lock(&ht->mutex);
- rhashtable_expand(ht);
- mutex_unlock(&ht->mutex);
-
- rcu_read_lock();
- pr_info(" Verifying lookups...\n");
- test_rht_lookup(ht);
- rcu_read_unlock();
- }
-
- for (i = 0; i < TEST_NEXPANDS; i++) {
- pr_info(" Table shrinkage iteration %u...\n", i);
- mutex_lock(&ht->mutex);
- rhashtable_shrink(ht);
- mutex_unlock(&ht->mutex);
-
- rcu_read_lock();
- pr_info(" Verifying lookups...\n");
- test_rht_lookup(ht);
- rcu_read_unlock();
- }
-
- rcu_read_lock();
- test_bucket_stats(ht, true);
- rcu_read_unlock();
-
- pr_info(" Deleting %d keys\n", TEST_ENTRIES);
- for (i = 0; i < TEST_ENTRIES; i++) {
- u32 key = i * 2;
-
- obj = rhashtable_lookup(ht, &key);
- BUG_ON(!obj);
-
- rhashtable_remove(ht, &obj->node);
- kfree(obj);
- }
-
- return 0;
-
-error:
- tbl = rht_dereference_rcu(ht->tbl, ht);
- for (i = 0; i < tbl->size; i++)
- rht_for_each_entry_safe(obj, pos, next, tbl, i, node)
- kfree(obj);
-
- return err;
-}
-
-static int __init test_rht_init(void)
-{
- struct rhashtable ht;
- struct rhashtable_params params = {
- .nelem_hint = TEST_HT_SIZE,
- .head_offset = offsetof(struct test_obj, node),
- .key_offset = offsetof(struct test_obj, value),
- .key_len = sizeof(int),
- .hashfn = jhash,
- .nulls_base = (3U << RHT_BASE_SHIFT),
- .grow_decision = rht_grow_above_75,
- .shrink_decision = rht_shrink_below_30,
- };
- int err;
-
- pr_info("Running resizable hashtable tests...\n");
-
- err = rhashtable_init(&ht, ¶ms);
- if (err < 0) {
- pr_warn("Test failed: Unable to initialize hashtable: %d\n",
- err);
- return err;
- }
-
- err = test_rhashtable(&ht);
-
- rhashtable_destroy(&ht);
-
- return err;
-}
-
-subsys_initcall(test_rht_init);
-
-#endif /* CONFIG_TEST_RHASHTABLE */
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
new file mode 100644
index 0000000000000000..1dfeba73fc743718
--- /dev/null
+++ b/lib/test_rhashtable.c
@@ -0,0 +1,227 @@
+/*
+ * Resizable, Scalable, Concurrent Hash Table
+ *
+ * Copyright (c) 2014 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2008-2014 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on the following paper:
+ * https://www.usenix.org/legacy/event/atc11/tech/final_files/Triplett.pdf
+ *
+ * Code partially derived from nft_hash
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/**************************************************************************
+ * Self Test
+ **************************************************************************/
+
+#include <linux/init.h>
+#include <linux/jhash.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rcupdate.h>
+#include <linux/rhashtable.h>
+#include <linux/slab.h>
+
+
+#define TEST_HT_SIZE 8
+#define TEST_ENTRIES 2048
+#define TEST_PTR ((void *) 0xdeadbeef)
+#define TEST_NEXPANDS 4
+
+struct test_obj {
+ void *ptr;
+ int value;
+ struct rhash_head node;
+};
+
+static int __init test_rht_lookup(struct rhashtable *ht)
+{
+ unsigned int i;
+
+ for (i = 0; i < TEST_ENTRIES * 2; i++) {
+ struct test_obj *obj;
+ bool expected = !(i % 2);
+ u32 key = i;
+
+ obj = rhashtable_lookup(ht, &key);
+
+ if (expected && !obj) {
+ pr_warn("Test failed: Could not find key %u\n", key);
+ return -ENOENT;
+ } else if (!expected && obj) {
+ pr_warn("Test failed: Unexpected entry found for key %u\n",
+ key);
+ return -EEXIST;
+ } else if (expected && obj) {
+ if (obj->ptr != TEST_PTR || obj->value != i) {
+ pr_warn("Test failed: Lookup value mismatch %p!=%p, %u!=%u\n",
+ obj->ptr, TEST_PTR, obj->value, i);
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void test_bucket_stats(struct rhashtable *ht, bool quiet)
+{
+ unsigned int cnt, rcu_cnt, i, total = 0;
+ struct rhash_head *pos;
+ struct test_obj *obj;
+ struct bucket_table *tbl;
+
+ tbl = rht_dereference_rcu(ht->tbl, ht);
+ for (i = 0; i < tbl->size; i++) {
+ rcu_cnt = cnt = 0;
+
+ if (!quiet)
+ pr_info(" [%#4x/%zu]", i, tbl->size);
+
+ rht_for_each_entry_rcu(obj, pos, tbl, i, node) {
+ cnt++;
+ total++;
+ if (!quiet)
+ pr_cont(" [%p],", obj);
+ }
+
+ rht_for_each_entry_rcu(obj, pos, tbl, i, node)
+ rcu_cnt++;
+
+ if (rcu_cnt != cnt)
+ pr_warn("Test failed: Chain count mismach %d != %d",
+ cnt, rcu_cnt);
+
+ if (!quiet)
+ pr_cont("\n [%#x] first element: %p, chain length: %u\n",
+ i, tbl->buckets[i], cnt);
+ }
+
+ pr_info(" Traversal complete: counted=%u, nelems=%u, entries=%d\n",
+ total, atomic_read(&ht->nelems), TEST_ENTRIES);
+
+ if (total != atomic_read(&ht->nelems) || total != TEST_ENTRIES)
+ pr_warn("Test failed: Total count mismatch ^^^");
+}
+
+static int __init test_rhashtable(struct rhashtable *ht)
+{
+ struct bucket_table *tbl;
+ struct test_obj *obj;
+ struct rhash_head *pos, *next;
+ int err;
+ unsigned int i;
+
+ /*
+ * Insertion Test:
+ * Insert TEST_ENTRIES into table with all keys even numbers
+ */
+ pr_info(" Adding %d keys\n", TEST_ENTRIES);
+ for (i = 0; i < TEST_ENTRIES; i++) {
+ struct test_obj *obj;
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ obj->ptr = TEST_PTR;
+ obj->value = i * 2;
+
+ rhashtable_insert(ht, &obj->node);
+ }
+
+ rcu_read_lock();
+ test_bucket_stats(ht, true);
+ test_rht_lookup(ht);
+ rcu_read_unlock();
+
+ for (i = 0; i < TEST_NEXPANDS; i++) {
+ pr_info(" Table expansion iteration %u...\n", i);
+ mutex_lock(&ht->mutex);
+ rhashtable_expand(ht);
+ mutex_unlock(&ht->mutex);
+
+ rcu_read_lock();
+ pr_info(" Verifying lookups...\n");
+ test_rht_lookup(ht);
+ rcu_read_unlock();
+ }
+
+ for (i = 0; i < TEST_NEXPANDS; i++) {
+ pr_info(" Table shrinkage iteration %u...\n", i);
+ mutex_lock(&ht->mutex);
+ rhashtable_shrink(ht);
+ mutex_unlock(&ht->mutex);
+
+ rcu_read_lock();
+ pr_info(" Verifying lookups...\n");
+ test_rht_lookup(ht);
+ rcu_read_unlock();
+ }
+
+ rcu_read_lock();
+ test_bucket_stats(ht, true);
+ rcu_read_unlock();
+
+ pr_info(" Deleting %d keys\n", TEST_ENTRIES);
+ for (i = 0; i < TEST_ENTRIES; i++) {
+ u32 key = i * 2;
+
+ obj = rhashtable_lookup(ht, &key);
+ BUG_ON(!obj);
+
+ rhashtable_remove(ht, &obj->node);
+ kfree(obj);
+ }
+
+ return 0;
+
+error:
+ tbl = rht_dereference_rcu(ht->tbl, ht);
+ for (i = 0; i < tbl->size; i++)
+ rht_for_each_entry_safe(obj, pos, next, tbl, i, node)
+ kfree(obj);
+
+ return err;
+}
+
+static int __init test_rht_init(void)
+{
+ struct rhashtable ht;
+ struct rhashtable_params params = {
+ .nelem_hint = TEST_HT_SIZE,
+ .head_offset = offsetof(struct test_obj, node),
+ .key_offset = offsetof(struct test_obj, value),
+ .key_len = sizeof(int),
+ .hashfn = jhash,
+ .nulls_base = (3U << RHT_BASE_SHIFT),
+ .grow_decision = rht_grow_above_75,
+ .shrink_decision = rht_shrink_below_30,
+ };
+ int err;
+
+ pr_info("Running resizable hashtable tests...\n");
+
+ err = rhashtable_init(&ht, ¶ms);
+ if (err < 0) {
+ pr_warn("Test failed: Unable to initialize hashtable: %d\n",
+ err);
+ return err;
+ }
+
+ err = test_rhashtable(&ht);
+
+ rhashtable_destroy(&ht);
+
+ return err;
+}
+
+module_init(test_rht_init);
+
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net] net: sctp: fix passing wrong parameter header to param_type2af in sctp_process_param
From: Neil Horman @ 2015-01-29 14:43 UTC (permalink / raw)
To: Daniel Borkmann
Cc: davem, vyasevich, netdev, linux-sctp, Saran Maruti Ramanara
In-Reply-To: <1422525958-5737-1-git-send-email-dborkman@redhat.com>
On Thu, Jan 29, 2015 at 11:05:58AM +0100, Daniel Borkmann wrote:
> From: Saran Maruti Ramanara <saran.neti@telus.com>
>
> When making use of RFC5061, section 4.2.4. for setting the primary IP
> address, we're passing a wrong parameter header to param_type2af(),
> resulting always in NULL being returned.
>
> At this point, param.p points to a sctp_addip_param struct, containing
> a sctp_paramhdr (type = 0xc004, length = var), and crr_id as a correlation
> id. Followed by that, as also presented in RFC5061 section 4.2.4., comes
> the actual sctp_addr_param, which also contains a sctp_paramhdr, but
> this time with the correct type SCTP_PARAM_IPV{4,6}_ADDRESS that
> param_type2af() can make use of. Since we already hold a pointer to
> addr_param from previous line, just reuse it for param_type2af().
>
> Fixes: d6de3097592b ("[SCTP]: Add the handling of "Set Primary IP Address" parameter to INIT")
> Signed-off-by: Saran Maruti Ramanara <saran.neti@telus.com>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
> net/sctp/sm_make_chunk.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> index e49e231..06320c8 100644
> --- a/net/sctp/sm_make_chunk.c
> +++ b/net/sctp/sm_make_chunk.c
> @@ -2608,7 +2608,7 @@ do_addr_param:
>
> addr_param = param.v + sizeof(sctp_addip_param_t);
>
> - af = sctp_get_af_specific(param_type2af(param.p->type));
> + af = sctp_get_af_specific(param_type2af(addr_param->p.type));
> if (af == NULL)
> break;
>
> --
> 1.7.11.7
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* linux-next - crashes in rhashtable_shrink
From: Valdis Kletnieks @ 2015-01-29 14:57 UTC (permalink / raw)
To: Thomas Graf; +Cc: linux-kernel, netdev
[-- Attachment #1: Type: text/plain, Size: 2041 bytes --]
For the past few kernels, I've seen occasional crashes in rhashtable_shrink.
Looks like the last thing to touch that code was the patch series:
Subject [PATCH 0/9 net-next v2] rhashtable: Per bucket locks & deferred table resizing
Date Fri, 2 Jan 2015 23:00:13 +0100
Most common appears to be during boot, while ip6tables-restore is
running (though I admit I am not sure if ip6tables-restore was actually
running, or if it ended up hung because somebody else had died while holding
a lock.). But I have also seen it after 10-12 hours of uptime
[ 53.762550] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 53.763607] IP: [<ffffffffab2a2898>] bucket_tail+0x57/0xaf
[ 53.771622] Workqueue: events rht_deferred_worker
[ 53.772715] task: ffff880224d20890 ti: ffff880224d24000 task.ti: ffff880224d24000
[ 53.793546] Call Trace:
[ 53.795374] [<ffffffffab2a38fd>] rhashtable_shrink+0x13e/0x1a0
[ 53.797197] [<ffffffffab2a3a02>] rht_deferred_worker+0xa3/0xb4
[ 53.798857] [<ffffffffab058ef6>] process_one_work+0x2d8/0x54d
[ 53.800070] [<ffffffffab0594d8>] worker_thread+0x343/0x46b
[ 53.801290] [<ffffffffab059195>] ? process_scheduled_works+0x2a/0x2a
[ 53.802513] [<ffffffffab05e19d>] kthread+0xea/0xf2
[ 53.803733] [<ffffffffab6c50ba>] ? _raw_spin_unlock_irq+0x29/0x74
[ 53.804957] [<ffffffffab05e0b3>] ? __kthread_parkme+0xa8/0xa8
[ 53.806176] [<ffffffffab6c5a6c>] ret_from_fork+0x7c/0xb0
[ 53.807400] [<ffffffffab05e0b3>] ? __kthread_parkme+0xa8/0xa8
[ 53.808609] Code: 4c 89 e7 e8 a1 ff ff ff 85 c0 75 1f 48 c7 c2 a9 89 b0 ab be 76 00 00 00 48 c7 c7 0d 61 b2 ab c6 05 a9 3d a3 00 01 e8 62 d6 dd ff <f6> 03 01 75 48 e8 d6 d7 de ff 85 c0 74 37 80 3d 90 3d a3 00 00
[ 53.810092] RIP [<ffffffffab2a2898>] bucket_tail+0x57/0xaf
[ 53.811414] RSP <ffff880224d27cc8>
[ 53.812721] CR2: 0000000000000000
[ 53.814033] ---[ end trace 82b77fc1a90284ff ]---
Unfortunately, I can't easily bisect to verify or narrow down further, as I'm only
seeing it 2-3 times a week....
[-- Attachment #2: Type: application/pgp-signature, Size: 848 bytes --]
^ permalink raw reply
* Re: linux-next - crashes in rhashtable_shrink
From: Thomas Graf @ 2015-01-29 15:00 UTC (permalink / raw)
To: Valdis Kletnieks; +Cc: linux-kernel, netdev
In-Reply-To: <5398.1422543462@turing-police.cc.vt.edu>
On 01/29/15 at 09:57am, Valdis Kletnieks wrote:
> For the past few kernels, I've seen occasional crashes in rhashtable_shrink.
> Looks like the last thing to touch that code was the patch series:
>
> Subject [PATCH 0/9 net-next v2] rhashtable: Per bucket locks & deferred table resizing
> Date Fri, 2 Jan 2015 23:00:13 +0100
Thanks for the report! Based on a similar report I've already tracked
this down to race condition. I'm in the final stages of submitting a
series of fixes for it.
^ permalink raw reply
* Re: [PATCH net-next] net: mark some potential candidates __read_mostly
From: Hannes Frederic Sowa @ 2015-01-29 15:40 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, netdev
In-Reply-To: <1422530103-23869-1-git-send-email-dborkman@redhat.com>
On Do, 2015-01-29 at 12:15 +0100, Daniel Borkmann wrote:
> They are all either written once or extremly rarely (e.g. from init
> code), so we can move them to the .data..read_mostly section.
>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
> drivers/net/ipvlan/ipvlan_core.c | 2 +-
> net/bridge/br_netlink.c | 2 +-
> net/ipv4/devinet.c | 2 +-
> net/ipv6/addrconf.c | 2 +-
> net/mpls/mpls_gso.c | 4 ++--
> 5 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
> index 2e19528..2a17500 100644
> --- a/drivers/net/ipvlan/ipvlan_core.c
> +++ b/drivers/net/ipvlan/ipvlan_core.c
> @@ -9,7 +9,7 @@
>
> #include "ipvlan.h"
>
> -static u32 ipvlan_jhash_secret;
> +static u32 ipvlan_jhash_secret __read_mostly;
>
> void ipvlan_init_secret(void)
> {
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index 3875ea5..e08b260 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -701,7 +701,7 @@ static size_t br_get_link_af_size(const struct net_device *dev)
> return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info));
> }
>
> -static struct rtnl_af_ops br_af_ops = {
> +static struct rtnl_af_ops br_af_ops __read_mostly = {
> .family = AF_BRIDGE,
> .get_link_af_size = br_get_link_af_size,
> };
Why not const?
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 59ebe16..f0b4a31 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -2322,7 +2322,7 @@ static __net_initdata struct pernet_operations devinet_ops = {
> .exit = devinet_exit_net,
> };
>
> -static struct rtnl_af_ops inet_af_ops = {
> +static struct rtnl_af_ops inet_af_ops __read_mostly = {
> .family = AF_INET,
> .fill_link_af = inet_fill_link_af,
> .get_link_af_size = inet_get_link_af_size,
Const?
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 7dcc065e..8623118 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -5405,7 +5405,7 @@ static struct pernet_operations addrconf_ops = {
> .exit = addrconf_exit_net,
> };
>
> -static struct rtnl_af_ops inet6_ops = {
> +static struct rtnl_af_ops inet6_ops __read_mostly = {
> .family = AF_INET6,
> .fill_link_af = inet6_fill_link_af,
> .get_link_af_size = inet6_get_link_af_size,
Const?
> diff --git a/net/mpls/mpls_gso.c b/net/mpls/mpls_gso.c
> index 349295d..809df53 100644
> --- a/net/mpls/mpls_gso.c
> +++ b/net/mpls/mpls_gso.c
> @@ -60,14 +60,14 @@ out:
> return segs;
> }
>
> -static struct packet_offload mpls_mc_offload = {
> +static struct packet_offload mpls_mc_offload __read_mostly = {
> .type = cpu_to_be16(ETH_P_MPLS_MC),
> .callbacks = {
> .gso_segment = mpls_gso_segment,
> },
> };
>
> -static struct packet_offload mpls_uc_offload = {
> +static struct packet_offload mpls_uc_offload __read_mostly = {
> .type = cpu_to_be16(ETH_P_MPLS_UC),
> .callbacks = {
> .gso_segment = mpls_gso_segment,
^ permalink raw reply
* Re: [PATCH net-next] net: mark some potential candidates __read_mostly
From: Daniel Borkmann @ 2015-01-29 16:11 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: davem, netdev
In-Reply-To: <1422546024.2861.18.camel@redhat.com>
On 01/29/2015 04:40 PM, Hannes Frederic Sowa wrote:
...
> Why not const?
Because all these candidates have a list member and are being
registered at respective places during __init/__exit. Similar
structs in other places already have __read_mostly, but these
ones can still be converted to it.
Cheers,
Daniel
^ permalink raw reply
* [PATCH] [TEMPORARY] net: netfilter: IPV6 XT sockets need CONFIG_NF_DEFRAG_IPV6
From: Arnd Bergmann @ 2015-01-29 16:18 UTC (permalink / raw)
To: netdev; +Cc: davem, KOVACS Krisztian, linux-arm-kernel
If IP6_NF_IPTABLES=m, NF_DEFRAG_IPV6 gets selected as a module as well
from NETFILTER_XT_MATCH_SOCKET, so the latter cannot be built-in, or
we get:
net/built-in.o: In function `socket_mt_init':
:(.init.text+0x32a0): undefined reference to `nf_defrag_ipv6_enable'
net/built-in.o: In function `tproxy_tg_init':
xt_TPROXY.c:582: undefined reference to `nf_defrag_ipv6_enable'
This adds one more dependency like the others to avoid the problem.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index b02660fa9eb0..2bd57d62a385 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -875,6 +875,7 @@ config NETFILTER_XT_TARGET_TPROXY
depends on NETFILTER_ADVANCED
depends on (IPV6 || IPV6=n)
depends on IP_NF_MANGLE
+ depends on (IP6_NF_IPTABLES || !IP6_NF_IPTABLES)
select NF_DEFRAG_IPV4
select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
help
@@ -1367,6 +1368,7 @@ config NETFILTER_XT_MATCH_SOCKET
depends on NETFILTER_ADVANCED
depends on !NF_CONNTRACK || NF_CONNTRACK
depends on (IPV6 || IPV6=n)
+ depends on (IP6_NF_IPTABLES || !IP6_NF_IPTABLES)
select NF_DEFRAG_IPV4
select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
help
^ permalink raw reply related
* [PATCH net] sunvnet: set queue mapping when doing packet copies
From: David L Stevens @ 2015-01-29 16:46 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan
In-Reply-To: <54C90AED.7040404@oracle.com>
[resending this since it never appeared on netdev yesterday]
This patch fixes a bug where vnet_skb_shape() didn't set the already-selected
queue mapping when a packet copy was required. This results in using the
wrong queue index for stops/starts, hung tx queues and watchdog timeouts
under heavy load.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
drivers/net/ethernet/sun/sunvnet.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 2b719cc..2b10b85 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -1123,6 +1123,7 @@ static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, int ncookies)
skb_shinfo(nskb)->gso_size = skb_shinfo(skb)->gso_size;
skb_shinfo(nskb)->gso_type = skb_shinfo(skb)->gso_type;
}
+ nskb->queue_mapping = skb->queue_mapping;
dev_kfree_skb(skb);
skb = nskb;
}
^ permalink raw reply related
* Re: [PATCH] [TEMPORARY] net: netfilter: IPV6 XT sockets need CONFIG_NF_DEFRAG_IPV6
From: Arnd Bergmann @ 2015-01-29 16:50 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: netdev, davem, KOVACS Krisztian
In-Reply-To: <1513018.IdvuSAziQY@wuerfel>
On Thursday 29 January 2015 17:18:59 Arnd Bergmann wrote:
> If IP6_NF_IPTABLES=m, NF_DEFRAG_IPV6 gets selected as a module as well
> from NETFILTER_XT_MATCH_SOCKET, so the latter cannot be built-in, or
> we get:
I messed up the subject line, the [TEMPORARY] was not meant to be
in there, and I also saw that the subject was mixed up too.
I will send it again with the proper subject.
Arnd
^ permalink raw reply
* [PATCH iproute2 0/4] iproute: Support for remote checksum offload
From: Tom Herbert @ 2015-01-29 16:51 UTC (permalink / raw)
To: stephen, netdev
Also, updated man pages for remote checksum offload options,
and added a section on setting FOU/GUE encapsulation with IP tunnels.
Tom Herbert (4):
ip link: Add support for remote checksum offload to IP tunnels
vxlan: Add support for remote checksum offload
iproute: Description of new options for VXLAN in ip-link man pages
iproute: Descriptions of fou and gue options in ip-link man pages
include/linux/if_link.h | 2 ++
ip/iplink_vxlan.c | 21 ++++++++++++
ip/link_gre.c | 11 ++++++-
ip/link_iptnl.c | 11 ++++++-
man/man8/ip-link.8.in | 86 ++++++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 128 insertions(+), 3 deletions(-)
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply
* [PATCH iproute2 1/4] ip link: Add support for remote checksum offload to IP tunnels
From: Tom Herbert @ 2015-01-29 16:51 UTC (permalink / raw)
To: stephen, netdev
In-Reply-To: <1422550321-30901-1-git-send-email-therbert@google.com>
This patch adds support to remote checksum checksum offload
confinguration for IPIP, SIT, and GRE tunnels. This patch
adds a [no]encap-remcsum to ip link command which applicable
when configured tunnels that use GUE.
http://tools.ietf.org/html/draft-herbert-remotecsumoffload-00
Example:
ip link add name tun1 type gre remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap fou encap-sport auto encap-dport 7777 encap-csum \
encap-remcsum
This would create an GRE tunnel in GUE encapsulation where the source
port is automatically selected (based on hash of inner packet),
checksums in the encapsulating UDP header are enabled (needed.for
remote checksum offload), and remote checksum ffload is configured to
be used on the tunnel (affects TX side).
Signed-off-by: Tom Herbert <therbert@google.com>
---
ip/link_gre.c | 11 ++++++++++-
ip/link_iptnl.c | 11 ++++++++++-
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/ip/link_gre.c b/ip/link_gre.c
index 47b64cb..1d78387 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -31,7 +31,7 @@ static void print_usage(FILE *f)
fprintf(f, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
fprintf(f, " [ noencap ] [ encap { fou | gue | none } ]\n");
fprintf(f, " [ encap-sport PORT ] [ encap-dport PORT ]\n");
- fprintf(f, " [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
+ fprintf(f, " [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n");
fprintf(f, "\n");
fprintf(f, "Where: NAME := STRING\n");
fprintf(f, " ADDR := { IP_ADDRESS | any }\n");
@@ -287,6 +287,10 @@ get_failed:
encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6;
+ } else if (strcmp(*argv, "encap-remcsum") == 0) {
+ encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
+ } else if (strcmp(*argv, "noencap-remcsum") == 0) {
+ encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM;
} else
usage();
argc--; argv++;
@@ -445,6 +449,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fputs("encap-csum6 ", f);
else
fputs("noencap-csum6 ", f);
+
+ if (flags & TUNNEL_ENCAP_FLAG_REMCSUM)
+ fputs("encap-remcsum ", f);
+ else
+ fputs("noencap-remcsum ", f);
}
}
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index 9487117..cab174f 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -31,7 +31,7 @@ static void print_usage(FILE *f, int sit)
fprintf(f, " [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
fprintf(f, " [ noencap ] [ encap { fou | gue | none } ]\n");
fprintf(f, " [ encap-sport PORT ] [ encap-dport PORT ]\n");
- fprintf(f, " [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
+ fprintf(f, " [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n");
if (sit) {
fprintf(f, " [ mode { ip6ip | ipip | any } ]\n");
fprintf(f, " [ isatap ]\n");
@@ -256,6 +256,10 @@ get_failed:
encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
+ } else if (strcmp(*argv, "encap-remcsum") == 0) {
+ encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
+ } else if (strcmp(*argv, "noencap-remcsum") == 0) {
+ encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM;
} else if (strcmp(*argv, "6rd-prefix") == 0) {
inet_prefix prefix;
NEXT_ARG();
@@ -438,6 +442,11 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
fputs("encap-csum6 ", f);
else
fputs("noencap-csum6 ", f);
+
+ if (flags & TUNNEL_ENCAP_FLAG_REMCSUM)
+ fputs("encap-remcsum ", f);
+ else
+ fputs("noencap-remcsum ", f);
}
}
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH iproute2 2/4] vxlan: Add support for remote checksum offload
From: Tom Herbert @ 2015-01-29 16:51 UTC (permalink / raw)
To: stephen, netdev
In-Reply-To: <1422550321-30901-1-git-send-email-therbert@google.com>
This patch adds support to remote checksum checksum offload
to VXLAN. This patch adds remcsumtx and remcsumrx to ip vxlan
configuration to enable remote checksum offload for transmit
and receive on the VXLAN tunnel.
https://tools.ietf.org/html/draft-herbert-vxlan-rco-00
Example:
ip link add name vxlan0 type vxlan id 42 group 239.1.1.1 dev eth0 \
udpcsum remcsumtx remcsumrx
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/if_link.h | 2 ++
ip/iplink_vxlan.c | 21 +++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 167ec34..11df025 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -368,6 +368,8 @@ enum {
IFLA_VXLAN_UDP_CSUM,
IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+ IFLA_VXLAN_REMCSUM_TX,
+ IFLA_VXLAN_REMCSUM_RX,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index 9cc3ec3..8fb11df 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -30,6 +30,7 @@ static void print_explain(FILE *f)
fprintf(f, " [ [no]l2miss ] [ [no]l3miss ]\n");
fprintf(f, " [ ageing SECONDS ] [ maxaddress NUMBER ]\n");
fprintf(f, " [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n");
+ fprintf(f, " [ [no]remcsumtx ] [ [no]remcsumrx ]\n");
fprintf(f, "\n");
fprintf(f, "Where: VNI := 0-16777215\n");
fprintf(f, " ADDR := { IP_ADDRESS | any }\n");
@@ -68,6 +69,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 udpcsum = 0;
__u8 udp6zerocsumtx = 0;
__u8 udp6zerocsumrx = 0;
+ __u8 remcsumtx = 0;
+ __u8 remcsumrx = 0;
int dst_port_set = 0;
struct ifla_vxlan_port_range range = { 0, 0 };
@@ -197,6 +200,14 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
udp6zerocsumrx = 1;
} else if (!matches(*argv, "noudp6zerocsumrx")) {
udp6zerocsumrx = 0;
+ } else if (!matches(*argv, "remcsumtx")) {
+ remcsumtx = 1;
+ } else if (!matches(*argv, "noremcsumtx")) {
+ remcsumtx = 0;
+ } else if (!matches(*argv, "remcsumrx")) {
+ remcsumrx = 1;
+ } else if (!matches(*argv, "noremcsumrx")) {
+ remcsumrx = 0;
} else if (matches(*argv, "help") == 0) {
explain();
return -1;
@@ -255,6 +266,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum);
addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
+ addattr8(n, 1024, IFLA_VXLAN_REMCSUM_TX, remcsumtx);
+ addattr8(n, 1024, IFLA_VXLAN_REMCSUM_RX, remcsumrx);
if (noage)
addattr32(n, 1024, IFLA_VXLAN_AGEING, 0);
@@ -398,6 +411,14 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX] &&
rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
fputs("udp6zerocsumrx ", f);
+
+ if (tb[IFLA_VXLAN_REMCSUM_TX] &&
+ rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_TX]))
+ fputs("remcsumtx ", f);
+
+ if (tb[IFLA_VXLAN_REMCSUM_RX] &&
+ rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_RX]))
+ fputs("remcsumrx ", f);
}
static void vxlan_print_help(struct link_util *lu, int argc, char **argv,
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH iproute2 3/4] iproute: Description of new options for VXLAN in ip-link man pages
From: Tom Herbert @ 2015-01-29 16:52 UTC (permalink / raw)
To: stephen, netdev
In-Reply-To: <1422550321-30901-1-git-send-email-therbert@google.com>
Add description for UDP checksums and remote checksum offload.
Signed-off-by: Tom Herbert <therbert@google.com>
---
man/man8/ip-link.8.in | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 1209b55..a0be895 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -276,6 +276,12 @@ the following additional arguments are supported:
.BI ageing " SECONDS "
.R " ] [ "
.BI maxaddress " NUMBER "
+.R " ] [ "
+.I "[no]udpcsum "
+.R " ] [ "
+.I "[no]remcsumtx "
+.R " ] [ "
+.I "[no]remcsumrx "
.R " ]"
.in +8
@@ -348,6 +354,18 @@ are entered into the VXLAN device forwarding database.
.BI maxaddress " NUMBER"
- specifies the maximum number of FDB entries.
+.sp
+.I [no]udpcsum
+- specifies if UDP checksum is enabled in the outer header.
+
+.sp
+.I [no]remcsumtx
+- specifies if remote checksum option is tranmitted.
+
+.sp
+.I [no]remcsumrx
+- specifies if remote checksum option is allowed to be received.
+
.in -8
.TP
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH iproute2 4/4] iproute: Descriptions of fou and gue options in ip-link man pages
From: Tom Herbert @ 2015-01-29 16:52 UTC (permalink / raw)
To: stephen, netdev
In-Reply-To: <1422550321-30901-1-git-send-email-therbert@google.com>
Add section for additional arguments to GRE, IPIP, and SIT types
that are related to Foo-over-UDP and Generic UDP Encapsulation.
Also, added an example GUE configuration in the examples section.
Signed-off-by: Tom Herbert <therbert@google.com>
---
man/man8/ip-link.8.in | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index a0be895..2634590 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -369,6 +369,63 @@ are entered into the VXLAN device forwarding database.
.in -8
.TP
+GRE, IPIP, SIT Type Support
+For a link of types
+.I GRE/IPIP/SIT
+the following additional arguments are supported:
+
+.BI "ip link add " DEVICE
+.BR type " { gre | ipip | sit } "
+.BI " remote " ADDR " local " ADDR
+.R " [ "
+.BR encap " { fou | gue | none } "
+.R " ] [ "
+.BI "encap-sport { " PORT " | auto } "
+.R " ] [ "
+.BI "encap-dport " PORT
+.R " ] [ "
+.I " [no]encap-csum "
+.R " ] [ "
+.I " [no]encap-remcsum "
+.R " ]"
+
+.in +8
+.sp
+.BI remote " ADDR "
+- specifies the remote address of the tunnel.
+
+.sp
+.BI local " ADDR "
+- specifies the fixed local address for tunneled packets.
+It must be an address on another interface on this host.
+
+.sp
+.BR encap " { fou | gue | none } "
+- specifies type of secondary UDP encapsulation. "fou" indicates
+Foo-Over-UDP, "gue" indicates Generic UDP Encapsulation.
+
+.sp
+.BI "encap-sport { " PORT " | auto } "
+- specifies the source port in UDP encapsulation.
+.IR PORT
+indicates the port by number, "auto"
+indicates that the port number should be chosen automatically
+(the kernel picks a flow based on the flow hash of the
+encapsulated packet).
+
+.sp
+.I [no]encap-csum
+- specifies if UDP checksums are enabled in the secondary
+encapsulation.
+
+.sp
+.I [no]encap-remcsum
+- specifies if Remote Checksum Offload is enabled. This is only
+applicable for Generic UDP Encapsulation.
+
+.in -8
+
+.TP
IP6GRE/IP6GRETAP Type Support
For a link of type
.I IP6GRE/IP6GRETAP
@@ -404,7 +461,7 @@ the following additional arguments are supported:
.sp
.BI local " ADDR "
- specifies the fixed local IPv6 address for tunneled packets.
-It must be and address on another interface on this host.
+It must be an address on another interface on this host.
.sp
.BI [i|o]seq
@@ -781,6 +838,15 @@ ip link help gre
.RS 4
Display help for the gre link type.
.RE
+.PP
+ip link add name tun1 type ipip remote 192.168.1.1
+local 192.168.1.2 ttl 225 encap gue encap-sport auto
+encap-dport 5555 encap-csum encap-remcsum
+.RS 4
+Creates an IPIP that is encapsulated with Generic UDP Encapsulation,
+and the outer UDP checksum and remote checksum offload are enabled.
+
+.RE
.SH SEE ALSO
.br
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [PATCH iproute2 3/4] iproute: Description of new options for VXLAN in ip-link man pages
From: Nikolay Aleksandrov @ 2015-01-29 17:20 UTC (permalink / raw)
To: Tom Herbert, stephen, netdev
In-Reply-To: <1422550321-30901-4-git-send-email-therbert@google.com>
On 01/29/2015 05:52 PM, Tom Herbert wrote:
> Add description for UDP checksums and remote checksum offload.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> man/man8/ip-link.8.in | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
> index 1209b55..a0be895 100644
> --- a/man/man8/ip-link.8.in
> +++ b/man/man8/ip-link.8.in
> @@ -276,6 +276,12 @@ the following additional arguments are supported:
> .BI ageing " SECONDS "
> .R " ] [ "
> .BI maxaddress " NUMBER "
> +.R " ] [ "
> +.I "[no]udpcsum "
> +.R " ] [ "
> +.I "[no]remcsumtx "
> +.R " ] [ "
> +.I "[no]remcsumrx "
> .R " ]"
>
> .in +8
> @@ -348,6 +354,18 @@ are entered into the VXLAN device forwarding database.
> .BI maxaddress " NUMBER"
> - specifies the maximum number of FDB entries.
>
> +.sp
> +.I [no]udpcsum
> +- specifies if UDP checksum is enabled in the outer header.
> +
> +.sp
> +.I [no]remcsumtx
> +- specifies if remote checksum option is tranmitted.
^^^^^^^^^^
transmitted
> +
> +.sp
> +.I [no]remcsumrx
> +- specifies if remote checksum option is allowed to be received.
> +
> .in -8
>
> .TP
>
^ permalink raw reply
* Re: [PATCH net-next v8 0/4] net: Add Keystone NetCP ethernet driver support
From: Murali Karicheri @ 2015-01-29 17:21 UTC (permalink / raw)
To: Arnd Bergmann, Balbi, Felipe, mugunthanvnm-l0cyMroinI0
Cc: David Miller, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <54C9654C.8030407-l0cyMroinI0@public.gmane.org>
On 01/28/2015 05:40 PM, Murali Karicheri wrote:
> + Felipe, Mugunthan for commenting on TI_CPSW, ALE.
>
--- Cut ------
>
>>
>> The second problem is where I got stuck myself: cpsw_ale.c (also cpts.c)
>> is getting linked into both modules, which is not allowed: It is
>> impossible for the kernel to compile these if one driver is a module
>> and the other one is not, and any use of KBUILD_MODNAME fails because
>> it is unclear what the modname is if the file is compiled once to
>> be linked into two drivers.
Arnd,
I think the solution is to make the cpsw_ale as a module and configured
through a Kconfig option. I am working on a fix for this now.
Similar fix is required for cpts.o. Currently we are not using this
module for Netcp, but soon this will be re-used. I have send a patch
that is already applied to net-next removing cpts.o for Netcp.
Murali
>
> I am still looking into this. Both Keystone and TI CPSW driver would
> need to use cpsw_ale.o and cpts.o (currently not used, but will need
> this later). Not found a solution yet.
>
> Murali
>>
>> Arnd
>
>
--
Murali Karicheri
Linux Kernel, Texas Instruments
--
To unsubscribe from this list: send the line "unsubscribe devicetree" 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
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