Netdev List
 help / color / mirror / Atom feed
* general protection fault in tipc_nametbl_unsubscribe
From: syzbot @ 2018-04-02  6:01 UTC (permalink / raw)
  To: davem, jon.maloy, linux-kernel, netdev, syzkaller-bugs,
	tipc-discussion, ying.xue

Hello,

syzbot hit the following crash on upstream commit
10b84daddbec72c6b440216a69de9a9605127f7a (Sat Mar 31 17:59:00 2018 +0000)
Merge branch 'perf-urgent-for-linus' of  
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
syzbot dashboard link:  
https://syzkaller.appspot.com/bug?extid=4859fe19555ea87c42f3

So far this crash happened 3 times on upstream.
C reproducer: https://syzkaller.appspot.com/x/repro.c?id=4775372465897472
syzkaller reproducer:  
https://syzkaller.appspot.com/x/repro.syz?id=4868734988582912
Raw console output:  
https://syzkaller.appspot.com/x/log.txt?id=5073802094444544
Kernel config:  
https://syzkaller.appspot.com/x/.config?id=-2760467897697295172
compiler: gcc (GCC) 7.1.1 20170620

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+4859fe19555ea87c42f3@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for  
details.
If you forward the report, please keep this part and the footer.

R13: ffffffffffffffff R14: 0000000000000000 R15: 0000000000000000
Name sequence creation failed, no memory
Failed to create subscription for {24576,0,4294967295}
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
    (ftrace buffer empty)
Modules linked in:
CPU: 1 PID: 4447 Comm: syzkaller851181 Not tainted 4.16.0-rc7+ #374
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
RIP: 0010:__list_del_entry_valid+0x7e/0x150 lib/list_debug.c:51
RSP: 0018:ffff8801ae1aef48 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff8801cf54c760 RDI: ffff8801cf54c768
RBP: ffff8801ae1aef60 R08: 1ffff10035c35cff R09: ffffffff89956150
R10: ffff8801ae1aee28 R11: 000000000000168a R12: ffffffff87745ea0
R13: ffff8801ae1af100 R14: ffff8801cf54c760 R15: ffff8801cf4c8cc0
FS:  0000000000000000(0000) GS:ffff8801db100000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055dce15c3090 CR3: 000000000846a002 CR4: 00000000001606e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
  __list_del_entry include/linux/list.h:117 [inline]
  list_del_init include/linux/list.h:159 [inline]
  tipc_nametbl_unsubscribe+0x318/0x990 net/tipc/name_table.c:848
  tipc_subscrb_subscrp_delete+0x1e9/0x460 net/tipc/subscr.c:212
  tipc_subscrb_delete net/tipc/subscr.c:242 [inline]
  tipc_subscrb_release_cb+0x17/0x30 net/tipc/subscr.c:321
  tipc_topsrv_kern_unsubscr+0x2c3/0x430 net/tipc/server.c:535
  tipc_group_delete+0x2c0/0x3d0 net/tipc/group.c:231
  tipc_sk_leave+0x10b/0x200 net/tipc/socket.c:2795
  tipc_release+0x154/0xff0 net/tipc/socket.c:577
  sock_release+0x8d/0x1e0 net/socket.c:595
  sock_close+0x16/0x20 net/socket.c:1149
  __fput+0x327/0x7e0 fs/file_table.c:209
  ____fput+0x15/0x20 fs/file_table.c:243
  task_work_run+0x199/0x270 kernel/task_work.c:113
  exit_task_work include/linux/task_work.h:22 [inline]
  do_exit+0x9bb/0x1ad0 kernel/exit.c:865
  do_group_exit+0x149/0x400 kernel/exit.c:968
  SYSC_exit_group kernel/exit.c:979 [inline]
  SyS_exit_group+0x1d/0x20 kernel/exit.c:977
  do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
  entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x43f228
RSP: 002b:00007ffde31217e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000000000043f228
RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
RBP: 00000000004bf308 R08: 00000000000000e7 R09: ffffffffffffffd0
R10: 00000000204ee000 R11: 0000000000000246 R12: 0000000000000001
R13: 00000000006d1180 R14: 0000000000000000 R15: 0000000000000000
Code: 00 00 00 00 ad de 49 39 c4 74 66 48 b8 00 02 00 00 00 00 ad de 48 89  
da 48 39 c3 74 65 48 c1 ea 03 48 b8 00 00 00 00 00 fc ff df <80> 3c 02 00  
75 7b 48 8b 13 48 39 f2 75 57 49 8d 7c 24 08 48 b8
RIP: __list_del_entry_valid+0x7e/0x150 lib/list_debug.c:51 RSP:  
ffff8801ae1aef48
---[ end trace ba18c1598e2d5535 ]---


---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.

syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is  
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
If you want to test a patch for this bug, please reply with:
#syz test: git://repo/address.git branch
and provide the patch inline or as an attachment.
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug  
report.
Note: all commands must start from beginning of the line in the email body.

^ permalink raw reply

* KASAN: stack-out-of-bounds Read in xfrm_state_find (5)
From: syzbot @ 2018-04-02  6:01 UTC (permalink / raw)
  To: davem, herbert, linux-kernel, netdev, steffen.klassert,
	syzkaller-bugs

Hello,

syzbot hit the following crash on upstream commit
10b84daddbec72c6b440216a69de9a9605127f7a (Sat Mar 31 17:59:00 2018 +0000)
Merge branch 'perf-urgent-for-linus' of  
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
syzbot dashboard link:  
https://syzkaller.appspot.com/bug?extid=d90468452f685a0b28eb

So far this crash happened 4 times on net-next, upstream.
C reproducer: https://syzkaller.appspot.com/x/repro.c?id=6686969799114752
syzkaller reproducer:  
https://syzkaller.appspot.com/x/repro.syz?id=5121263362113536
Raw console output:  
https://syzkaller.appspot.com/x/log.txt?id=5897355362566144
Kernel config:  
https://syzkaller.appspot.com/x/.config?id=-2760467897697295172
compiler: gcc (GCC) 7.1.1 20170620

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+d90468452f685a0b28eb@syzkaller.appspotmail.com
It will help syzbot understand when the bug is fixed. See footer for  
details.
If you forward the report, please keep this part and the footer.

==================================================================
BUG: KASAN: stack-out-of-bounds in xfrm_state_find+0x30de/0x3210  
net/xfrm/xfrm_state.c:1051
Read of size 4 at addr ffff8801b25ef480 by task syzkaller538986/4480

CPU: 0 PID: 4480 Comm: syzkaller538986 Not tainted 4.16.0-rc7+ #9
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Call Trace:
  __dump_stack lib/dump_stack.c:17 [inline]
  dump_stack+0x194/0x24d lib/dump_stack.c:53
  print_address_description+0x73/0x250 mm/kasan/report.c:256
  kasan_report_error mm/kasan/report.c:354 [inline]
  kasan_report+0x23c/0x360 mm/kasan/report.c:412
  __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:432
  xfrm_state_find+0x30de/0x3210 net/xfrm/xfrm_state.c:1051
  xfrm_tmpl_resolve_one net/xfrm/xfrm_policy.c:1393 [inline]
  xfrm_tmpl_resolve+0x2ee/0xc40 net/xfrm/xfrm_policy.c:1437
  xfrm_resolve_and_create_bundle+0x184/0x28d0 net/xfrm/xfrm_policy.c:1833
  xfrm_lookup+0xfcb/0x25c0 net/xfrm/xfrm_policy.c:2163
  xfrm_lookup_route+0x39/0x1a0 net/xfrm/xfrm_policy.c:2283
  ip_route_output_flow+0x7c/0xa0 net/ipv4/route.c:2583
  udp_sendmsg+0x19bd/0x2f70 net/ipv4/udp.c:1012
  udpv6_sendmsg+0x757/0x3400 net/ipv6/udp.c:1156
  inet_sendmsg+0x11f/0x5e0 net/ipv4/af_inet.c:764
  sock_sendmsg_nosec net/socket.c:630 [inline]
  sock_sendmsg+0xca/0x110 net/socket.c:640
  ___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
  __sys_sendmsg+0xe5/0x210 net/socket.c:2080
  SYSC_sendmsg net/socket.c:2091 [inline]
  SyS_sendmsg+0x2d/0x50 net/socket.c:2087
  do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
  entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x440139
RSP: 002b:00007fffa14c36e8 EFLAGS: 00000217 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440139
RDX: 0000000000000000 RSI: 0000000020000580 RDI: 0000000000000003
RBP: 00000000006ca018 R08: 00000000004002c8 R09: 00000000004002c8
R10: 00000000000000e8 R11: 0000000000000217 R12: 0000000000401a60
R13: 0000000000401af0 R14: 0000000000000000 R15: 0000000000000000

The buggy address belongs to the page:
page:ffffea0006c97bc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
flags: 0x2fffc0000000000()
raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff
raw: 0000000000000000 ffffea0006c90101 0000000000000000 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
  ffff8801b25ef380: f2 00 f2 f2 f2 f2 f2 f2 f2 f8 f2 f2 f2 f2 f2 f2
  ffff8801b25ef400: f2 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00
> ffff8801b25ef480: f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 f2 f2
                    ^
  ffff8801b25ef500: f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  ffff8801b25ef580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
==================================================================


---
This bug is generated by a dumb bot. It may contain errors.
See https://goo.gl/tpsmEJ for details.
Direct all questions to syzkaller@googlegroups.com.

syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is  
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
If you want to test a patch for this bug, please reply with:
#syz test: git://repo/address.git branch
and provide the patch inline or as an attachment.
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug  
report.
Note: all commands must start from beginning of the line in the email body.

^ permalink raw reply

* Re: linux-next: Signed-off-by missing for commits in the net-next tree
From: Johan Hedberg @ 2018-04-02  5:38 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: David Miller, Networking, Linux-Next Mailing List,
	Linux Kernel Mailing List, Marcel Holtmann
In-Reply-To: <20180402123019.2e04f084@canb.auug.org.au>

Hi,

On Mon, Apr 02, 2018, Stephen Rothwell wrote:
>   45a42bc9cc65 ("Bluetooth: hci_bcm: Remove DMI quirk for the MINIX Z83-4")
>   f9b95db0165a ("Bluetooth: btrsi: remove unused including <linux/version.h>")
>   96e58d368fa6 ("Bluetooth: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for BTUSB_QCA_ROME")
>   9ea471320e13 ("Bluetooth: Mark expected switch fall-throughs")
> 
> are missing a Signed-off-by from their committer.

I think this is because I fixed up a missing author name in "Bluetooth:
hci_bcm: Remove DMI quirk for the MINIX Z83-4" and did a push --force,
whereas these patches were originally committed by Marcel. Should I be
adding my signed-off-by to all affected patches when doing such rebases?

Johan

^ permalink raw reply

* [PATCH net-next] ipv6: frags: fix /proc/sys/net/ipv6/ip6frag_low_thresh
From: Eric Dumazet @ 2018-04-02  4:57 UTC (permalink / raw)
  To: David S . Miller
  Cc: netdev, Eric Dumazet, Maciej Żenczykowski, Eric Dumazet

I forgot to change ip6frag_low_thresh proc_handler
from proc_dointvec_minmax to proc_doulongvec_minmax

Fixes: 3e67f106f619 ("inet: frags: break the 2GB limit for frags storage")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Maciej Żenczykowski <maze@google.com>
---
 net/ipv6/reassembly.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 7b52efc63f6adad2c242ae1171e5b7b27b40f0bf..70e4a578b2fb6b2941daeebe4f476214953db047 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -564,7 +564,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
 		.data		= &init_net.ipv6.frags.low_thresh,
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
+		.proc_handler	= proc_doulongvec_minmax,
 		.extra1		= &zero,
 		.extra2		= &init_net.ipv6.frags.high_thresh
 	},
-- 
2.17.0.rc1.321.gba9d0f2565-goog

^ permalink raw reply related

* Re: [PATCH] net: improve ipv4 performances
From: Eric Dumazet @ 2018-04-02  4:49 UTC (permalink / raw)
  To: Anton Gary Ceph, netdev, linux-kernel
In-Reply-To: <20180401183121.13022-1-agaceph@gmail.com>



On 04/01/2018 11:31 AM, Anton Gary Ceph wrote:
> As the Linux networking stack is growing, more and more protocols are
> added, increasing the complexity of stack itself.
> Modern processors, contrary to common belief, are very bad in branch
> prediction, so it's our task to give hints to the compiler when possible.
> 
> After a few profiling and analysis, turned out that the ethertype field
> of the packets has the following distribution:
> 
>     92.1% ETH_P_IP
>      3.2% ETH_P_ARP
>      2.7% ETH_P_8021Q
>      1.4% ETH_P_PPP_SES
>      0.6% don't know/no opinion
> 
> From a projection on statistics collected by Google about IPv6 adoption[1],
> IPv6 should peak at 25% usage at the beginning of 2030. Hence, we should
> give proper hints to the compiler about the low IPv6 usage.
> 
> Here is an iperf3 run before and after the patch:
> 
> Before:
> [ ID]  Interval           Transfer    Bandwidth       Retr
> [  4]  0.00-100.00 sec    100 GBytes  8.60 Gbits/sec  0       sender
> [  4]  0.00-100.00 sec    100 GBytes  8.60 Gbits/sec          receiver
> 
> After
> [ ID]  Interval           Transfer    Bandwidth       Retr
> [  4]  0.00-100.00 sec    109 GBytes  9.35 Gbits/sec  0       sender
> [  4]  0.00-100.00 sec    109 GBytes  9.35 Gbits/sec          receiver
>

These iperf3 numbers are simply telling something is wrong in your measures or your hardware.

By the time linux kernels with this patch reach hosts, they will likely use IPv6 anyway.

Please do not tell the compiler that IPv6 should be slowed down in favor of IPv4.

Instead, work on removing IPv4 stack from linux kernel (making it a module)

^ permalink raw reply

* Re: [PATCH] net: ip tos cgroup
From: David Miller @ 2018-04-02  4:02 UTC (permalink / raw)
  To: lirongqing; +Cc: netdev
In-Reply-To: <1522641108-8972-1-git-send-email-lirongqing@baidu.com>

From: Li RongQing <lirongqing@baidu.com>
Date: Mon,  2 Apr 2018 11:51:48 +0800

> ip tos segment can be changed by setsockopt(IP_TOS), or by iptables;
> this patch creates a new method to change socket tos segment of
> processes based on cgroup
> 
> The usage:
> 
>     1. mount tos_cgroup, and setting tos value
>     mount -t cgroup -o ip_tos ip_tos /cgroups/tos
>     echo tos-value >/cgroups/tos/ip_tos.tos
>     2. then move processes to cgroup, or create processes in cgroup
> 
> Signed-off-by: jimyan <jimyan@baidu.com>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>

The merge window has openned and therefore the net-next tree is
closed, please only submit new features when the net-next tree
is open.

Thank you.

^ permalink raw reply

* [PATCH] net: ip tos cgroup
From: Li RongQing @ 2018-04-02  3:51 UTC (permalink / raw)
  To: netdev

ip tos segment can be changed by setsockopt(IP_TOS), or by iptables;
this patch creates a new method to change socket tos segment of
processes based on cgroup

The usage:

    1. mount tos_cgroup, and setting tos value
    mount -t cgroup -o ip_tos ip_tos /cgroups/tos
    echo tos-value >/cgroups/tos/ip_tos.tos
    2. then move processes to cgroup, or create processes in cgroup

Signed-off-by: jimyan <jimyan@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
 include/linux/cgroup_subsys.h |   4 ++
 include/net/tos_cgroup.h      |  46 ++++++++++++++
 net/ipv4/Kconfig              |   9 +++
 net/ipv4/Makefile             |   1 +
 net/ipv4/af_inet.c            |   2 +
 net/ipv4/tos_cgroup.c         | 145 ++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/af_inet6.c           |   2 +
 7 files changed, 209 insertions(+)
 create mode 100644 include/net/tos_cgroup.h
 create mode 100644 net/ipv4/tos_cgroup.c

diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index acb77dcff3b4..1b86eda1c23e 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -61,6 +61,10 @@ SUBSYS(pids)
 SUBSYS(rdma)
 #endif
 
+#if IS_ENABLED(CONFIG_IP_TOS_CGROUP)
+SUBSYS(ip_tos)
+#endif
+
 /*
  * The following subsystems are not supported on the default hierarchy.
  */
diff --git a/include/net/tos_cgroup.h b/include/net/tos_cgroup.h
new file mode 100644
index 000000000000..45c33733c4e9
--- /dev/null
+++ b/include/net/tos_cgroup.h
@@ -0,0 +1,46 @@
+/*
+ * tos_cgroup.h			IP TOS Control Group
+ *
+ * Authors:	Li RongQing <lirongqing@baidu.com>
+ *          Jim Yan <jimyan@baidu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#ifndef _IP_TOS_CGROUP_H
+#define _IP_TOS_CGROUP_H
+
+#include <linux/cgroup.h>
+#include <linux/hardirq.h>
+
+struct tos_cgroup_state {
+	struct cgroup_subsys_state css;
+	u32 tos;
+};
+
+#if IS_ENABLED(CONFIG_IP_TOS_CGROUP)
+static inline u32 task_ip_tos(struct task_struct *p)
+{
+	u32 tos;
+
+	if (in_interrupt())
+		return 0;
+
+	rcu_read_lock();
+	tos = container_of(task_css(p, ip_tos_cgrp_id),
+			struct tos_cgroup_state, css)->tos;
+	rcu_read_unlock();
+
+	return tos;
+}
+#else /* !CONFIG_IP_TOS_CGROUP */
+static inline u32 task_ip_tos(struct task_struct *p)
+{
+	return 0;
+}
+#endif /* CONFIG_IP_TOS_CGROUP */
+#endif  /* _IP_TOS_CGROUP_H */
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index f48fe6fc7e8c..6f8ce1b2ceb0 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -748,3 +748,12 @@ config TCP_MD5SIG
 	  on the Internet.
 
 	  If unsure, say N.
+
+config IP_TOS_CGROUP
+	bool "ip tos cgroup"
+	depends on CGROUPS
+	---help---
+	  Say Y here if you want to set ip packet tos based on the
+	  control cgroup of their process.
+
+	  This can set ip packet tos
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 47a0a6649a9d..a2734c50db2e 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
 obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
 obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
 obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
+obj-$(CONFIG_IP_TOS_CGROUP) += tos_cgroup.o
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
 		      xfrm4_output.o xfrm4_protocol.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e4329e161943..90842bedb500 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -120,6 +120,7 @@
 #include <linux/mroute.h>
 #endif
 #include <net/l3mdev.h>
+#include <net/tos_cgroup.h>
 
 #include <trace/events/sock.h>
 
@@ -356,6 +357,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
 	inet->mc_index	= 0;
 	inet->mc_list	= NULL;
 	inet->rcv_tos	= 0;
+	inet->tos       = task_ip_tos(current);
 
 	sk_refcnt_debug_inc(sk);
 
diff --git a/net/ipv4/tos_cgroup.c b/net/ipv4/tos_cgroup.c
new file mode 100644
index 000000000000..17d2d7c02871
--- /dev/null
+++ b/net/ipv4/tos_cgroup.c
@@ -0,0 +1,145 @@
+/*
+ * net/ipv4/tos_cgroup.c	IP TOS Control Group
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Authors:	Li RongQing <lirongqing@baidu.com>
+ *          jimyan <jimyan@baidu.com>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/cgroup.h>
+#include <net/sock.h>
+#include <net/inet_sock.h>
+#include <net/tos_cgroup.h>
+#include <linux/fdtable.h>
+#include <net/route.h>
+#include <net/inet_ecn.h>
+#include <linux/sched/task.h>
+
+static inline
+struct tos_cgroup_state *css_tos_cgroup(struct cgroup_subsys_state *css)
+{
+	return css ? container_of(css, struct tos_cgroup_state, css) : NULL;
+}
+
+static inline struct tos_cgroup_state *task_tos_cgroup(struct task_struct *task)
+{
+	return css_tos_cgroup(task_css(task, ip_tos_cgrp_id));
+}
+
+static struct cgroup_subsys_state
+*cgrp_css_alloc(struct cgroup_subsys_state *parent_css)
+{
+	struct tos_cgroup_state *cs;
+
+	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
+	if (!cs)
+		return ERR_PTR(-ENOMEM);
+
+	return &cs->css;
+}
+
+static void cgrp_css_free(struct cgroup_subsys_state *css)
+{
+	kfree(css_tos_cgroup(css));
+}
+
+static int update_tos(const void *v, struct file *file, unsigned int n)
+{
+	int err;
+	struct socket *sock = sock_from_file(file, &err);
+	unsigned char val = (unsigned char)*(u64 *)v;
+
+	if (sock && (sock->sk->sk_family == PF_INET
+#if IS_ENABLED(CONFIG_IPV6)
+				|| sock->sk->sk_family == PF_INET6)) {
+#else
+		)){
+#endif
+		struct inet_sock *inet = inet_sk(sock->sk);
+
+		lock_sock(sock->sk);
+		if (sock->sk->sk_type == SOCK_STREAM) {
+			val &= ~INET_ECN_MASK;
+			val |= inet->tos & INET_ECN_MASK;
+		}
+		if (inet->tos != val) {
+			inet->tos = val;
+			sock->sk->sk_priority = rt_tos2priority(val);
+			sk_dst_reset(sock->sk);
+		}
+		release_sock(sock->sk);
+	}
+	return 0;
+}
+
+static void cgrp_attach(struct cgroup_taskset *tset)
+{
+	struct task_struct *p;
+	struct cgroup_subsys_state *css;
+	u64 v;
+
+	cgroup_taskset_for_each(p, css, tset) {
+		task_lock(p);
+		v = task_tos_cgroup(p)->tos;
+		iterate_fd(p->files, 0, update_tos, (void *)&v);
+		task_unlock(p);
+	}
+}
+
+static u64 read_tos(struct cgroup_subsys_state *css, struct cftype *cft)
+{
+	return css_tos_cgroup(css)->tos;
+}
+
+static int
+write_tos(struct cgroup_subsys_state *css, struct cftype *cft, u64 value)
+{
+	struct css_task_iter it;
+	struct task_struct *task = NULL;
+
+	if (value < 0 || value > 255) {
+		pr_info("Invalid TOS value\n");
+		return 0;
+	}
+
+	css_tos_cgroup(css)->tos = (u32)value;
+
+	css_task_iter_start(css, 0, &it);
+	while ((task = css_task_iter_next(&it))) {
+		if (task) {
+			task_lock(task);
+			iterate_fd(task->files, 0, update_tos, (void *)&value);
+			task_unlock(task);
+		}
+	}
+	css_task_iter_end(&it);
+
+	return 0;
+}
+
+static struct cftype ss_files[] = {
+	{
+		.name = "tos",
+		.read_u64 = read_tos,
+		.write_u64 = write_tos,
+	},
+	{ }	/* terminate */
+};
+
+struct cgroup_subsys ip_tos_cgrp_subsys = {
+	.css_alloc	= cgrp_css_alloc,
+	.css_free	= cgrp_css_free,
+	.attach		= cgrp_attach,
+	.legacy_cftypes	= ss_files,
+};
+
+MODULE_LICENSE("GPL v2");
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 416917719a6f..b12655004745 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -44,6 +44,7 @@
 #include <linux/icmpv6.h>
 #include <linux/netfilter_ipv6.h>
 
+#include <net/tos_cgroup.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/udp.h>
@@ -223,6 +224,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
 	inet->mc_index	= 0;
 	inet->mc_list	= NULL;
 	inet->rcv_tos	= 0;
+	inet->tos       = task_ip_tos(current);
 
 	if (net->ipv4.sysctl_ip_no_pmtu_disc)
 		inet->pmtudisc = IP_PMTUDISC_DONT;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v3 2/2] net: mvneta: improve suspend/resume
From: Jisheng Zhang @ 2018-04-02  3:24 UTC (permalink / raw)
  To: David Miller, Thomas Petazzoni, Russell King - ARM Linux
  Cc: linux-arm-kernel, netdev, linux-kernel
In-Reply-To: <20180402112229.508e1feb@xhacker.debian>

Current suspend/resume implementation reuses the mvneta_open() and
mvneta_close(), but it could be optimized to take only necessary
actions during suspend/resume.

One obvious problem of current implementation is: after hundreds of
system suspend/resume cycles, the resume of mvneta could fail due to
fragmented dma coherent memory. After this patch, the non-necessary
memory alloc/free is optimized out.

Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
 drivers/net/ethernet/marvell/mvneta.c | 69 +++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f96815853108..8999a9a52ca2 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4586,16 +4586,45 @@ static int mvneta_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int mvneta_suspend(struct device *device)
 {
+	int queue;
 	struct net_device *dev = dev_get_drvdata(device);
 	struct mvneta_port *pp = netdev_priv(dev);
 
+	if (!netif_running(dev))
+		goto clean_exit;
+
+	if (!pp->neta_armada3700) {
+		spin_lock(&pp->lock);
+		pp->is_stopped = true;
+		spin_unlock(&pp->lock);
+
+		cpuhp_state_remove_instance_nocalls(online_hpstate,
+						    &pp->node_online);
+		cpuhp_state_remove_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+						    &pp->node_dead);
+	}
+
 	rtnl_lock();
-	if (netif_running(dev))
-		mvneta_stop(dev);
+	mvneta_stop_dev(pp);
 	rtnl_unlock();
+
+	for (queue = 0; queue < rxq_number; queue++) {
+		struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+
+		mvneta_rxq_drop_pkts(pp, rxq);
+	}
+
+	for (queue = 0; queue < txq_number; queue++) {
+		struct mvneta_tx_queue *txq = &pp->txqs[queue];
+
+		mvneta_txq_hw_deinit(pp, txq);
+	}
+
+clean_exit:
 	netif_device_detach(dev);
 	clk_disable_unprepare(pp->clk_bus);
 	clk_disable_unprepare(pp->clk);
+
 	return 0;
 }
 
@@ -4604,7 +4633,7 @@ static int mvneta_resume(struct device *device)
 	struct platform_device *pdev = to_platform_device(device);
 	struct net_device *dev = dev_get_drvdata(device);
 	struct mvneta_port *pp = netdev_priv(dev);
-	int err;
+	int err, queue;
 
 	clk_prepare_enable(pp->clk);
 	if (!IS_ERR(pp->clk_bus))
@@ -4626,12 +4655,38 @@ static int mvneta_resume(struct device *device)
 	}
 
 	netif_device_attach(dev);
-	rtnl_lock();
-	if (netif_running(dev)) {
-		mvneta_open(dev);
-		mvneta_set_rx_mode(dev);
+
+	if (!netif_running(dev))
+		return 0;
+
+	for (queue = 0; queue < rxq_number; queue++) {
+		struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
+
+		rxq->next_desc_to_proc = 0;
+		mvneta_rxq_hw_init(pp, rxq);
+	}
+
+	for (queue = 0; queue < txq_number; queue++) {
+		struct mvneta_tx_queue *txq = &pp->txqs[queue];
+
+		txq->next_desc_to_proc = 0;
+		mvneta_txq_hw_init(pp, txq);
 	}
+
+	if (!pp->neta_armada3700) {
+		spin_lock(&pp->lock);
+		pp->is_stopped = false;
+		spin_unlock(&pp->lock);
+		cpuhp_state_add_instance_nocalls(online_hpstate,
+						 &pp->node_online);
+		cpuhp_state_add_instance_nocalls(CPUHP_NET_MVNETA_DEAD,
+						 &pp->node_dead);
+	}
+
+	rtnl_lock();
+	mvneta_start_dev(pp);
 	rtnl_unlock();
+	mvneta_set_rx_mode(dev);
 
 	return 0;
 }
-- 
2.16.3

^ permalink raw reply related

* [PATCH v3 1/2] net: mvneta: split rxq/txq init and txq deinit into SW and HW parts
From: Jisheng Zhang @ 2018-04-02  3:23 UTC (permalink / raw)
  To: David Miller, Thomas Petazzoni, Russell King - ARM Linux
  Cc: linux-arm-kernel, netdev, linux-kernel
In-Reply-To: <20180402112229.508e1feb@xhacker.debian>

This is to prepare the suspend/resume improvement in next patch. The
SW parts can be optimized out during resume.

As for rxq handling during suspend, we'd like to drop packets by
calling mvneta_rxq_drop_pkts() which is both SW and HW operation,
so we don't split rxq deinit.

Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
 drivers/net/ethernet/marvell/mvneta.c | 85 +++++++++++++++++++++++++++--------
 1 file changed, 66 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 30aab9bf77cc..f96815853108 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2796,10 +2796,8 @@ static void mvneta_rx_reset(struct mvneta_port *pp)
 
 /* Rx/Tx queue initialization/cleanup methods */
 
-/* Create a specified RX queue */
-static int mvneta_rxq_init(struct mvneta_port *pp,
-			   struct mvneta_rx_queue *rxq)
-
+static int mvneta_rxq_sw_init(struct mvneta_port *pp,
+			      struct mvneta_rx_queue *rxq)
 {
 	rxq->size = pp->rx_ring_size;
 
@@ -2812,6 +2810,12 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
 
 	rxq->last_desc = rxq->size - 1;
 
+	return 0;
+}
+
+static void mvneta_rxq_hw_init(struct mvneta_port *pp,
+			       struct mvneta_rx_queue *rxq)
+{
 	/* Set Rx descriptors queue starting address */
 	mvreg_write(pp, MVNETA_RXQ_BASE_ADDR_REG(rxq->id), rxq->descs_phys);
 	mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size);
@@ -2835,6 +2839,20 @@ static int mvneta_rxq_init(struct mvneta_port *pp,
 		mvneta_rxq_short_pool_set(pp, rxq);
 		mvneta_rxq_non_occup_desc_add(pp, rxq, rxq->size);
 	}
+}
+
+/* Create a specified RX queue */
+static int mvneta_rxq_init(struct mvneta_port *pp,
+			   struct mvneta_rx_queue *rxq)
+
+{
+	int ret;
+
+	ret = mvneta_rxq_sw_init(pp, rxq);
+	if (ret < 0)
+		return ret;
+
+	mvneta_rxq_hw_init(pp, rxq);
 
 	return 0;
 }
@@ -2857,9 +2875,8 @@ static void mvneta_rxq_deinit(struct mvneta_port *pp,
 	rxq->descs_phys        = 0;
 }
 
-/* Create and initialize a tx queue */
-static int mvneta_txq_init(struct mvneta_port *pp,
-			   struct mvneta_tx_queue *txq)
+static int mvneta_txq_sw_init(struct mvneta_port *pp,
+			      struct mvneta_tx_queue *txq)
 {
 	int cpu;
 
@@ -2872,7 +2889,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
 	txq->tx_stop_threshold = txq->size - MVNETA_MAX_SKB_DESCS;
 	txq->tx_wake_threshold = txq->tx_stop_threshold / 2;
 
-
 	/* Allocate memory for TX descriptors */
 	txq->descs = dma_alloc_coherent(pp->dev->dev.parent,
 					txq->size * MVNETA_DESC_ALIGNED_SIZE,
@@ -2882,14 +2898,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
 
 	txq->last_desc = txq->size - 1;
 
-	/* Set maximum bandwidth for enabled TXQs */
-	mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
-	mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
-
-	/* Set Tx descriptors queue starting address */
-	mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
-	mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
-
 	txq->tx_skb = kmalloc_array(txq->size, sizeof(*txq->tx_skb),
 				    GFP_KERNEL);
 	if (!txq->tx_skb) {
@@ -2910,7 +2918,6 @@ static int mvneta_txq_init(struct mvneta_port *pp,
 				  txq->descs, txq->descs_phys);
 		return -ENOMEM;
 	}
-	mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
 
 	/* Setup XPS mapping */
 	if (txq_number > 1)
@@ -2923,9 +2930,38 @@ static int mvneta_txq_init(struct mvneta_port *pp,
 	return 0;
 }
 
+static void mvneta_txq_hw_init(struct mvneta_port *pp,
+			       struct mvneta_tx_queue *txq)
+{
+	/* Set maximum bandwidth for enabled TXQs */
+	mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
+	mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
+
+	/* Set Tx descriptors queue starting address */
+	mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
+	mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
+
+	mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
+}
+
+/* Create and initialize a tx queue */
+static int mvneta_txq_init(struct mvneta_port *pp,
+			   struct mvneta_tx_queue *txq)
+{
+	int ret;
+
+	ret = mvneta_txq_sw_init(pp, txq);
+	if (ret < 0)
+		return ret;
+
+	mvneta_txq_hw_init(pp, txq);
+
+	return 0;
+}
+
 /* Free allocated resources when mvneta_txq_init() fails to allocate memory*/
-static void mvneta_txq_deinit(struct mvneta_port *pp,
-			      struct mvneta_tx_queue *txq)
+static void mvneta_txq_sw_deinit(struct mvneta_port *pp,
+				 struct mvneta_tx_queue *txq)
 {
 	struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
 
@@ -2946,7 +2982,11 @@ static void mvneta_txq_deinit(struct mvneta_port *pp,
 	txq->last_desc         = 0;
 	txq->next_desc_to_proc = 0;
 	txq->descs_phys        = 0;
+}
 
+static void mvneta_txq_hw_deinit(struct mvneta_port *pp,
+				 struct mvneta_tx_queue *txq)
+{
 	/* Set minimum bandwidth for disabled TXQs */
 	mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0);
 	mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0);
@@ -2956,6 +2996,13 @@ static void mvneta_txq_deinit(struct mvneta_port *pp,
 	mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), 0);
 }
 
+static void mvneta_txq_deinit(struct mvneta_port *pp,
+			      struct mvneta_tx_queue *txq)
+{
+	mvneta_txq_sw_deinit(pp, txq);
+	mvneta_txq_hw_deinit(pp, txq);
+}
+
 /* Cleanup all Tx queues */
 static void mvneta_cleanup_txqs(struct mvneta_port *pp)
 {
-- 
2.16.3

^ permalink raw reply related

* [PATCH v3 0/2] net: mvneta: improve suspend/resume
From: Jisheng Zhang @ 2018-04-02  3:22 UTC (permalink / raw)
  To: David Miller, Thomas Petazzoni, Russell King - ARM Linux
  Cc: linux-arm-kernel, netdev, linux-kernel

This series tries to optimize the mvneta's suspend/resume
implementation by only taking necessary actions.

Since v2:
 - keep rtnl lock when calling mvneta_start_dev() and mvneta_stop_dev()
   Thank Russell for pointing this out

Since v1:
 - unify ret check
 - try best to keep the suspend/resume behavior
 - split txq deinit into sw/hw parts as well
 - adjust mvneta_stop_dev() location

I didn't add Thomas's Ack tag to patch1, because in v2, I add new code
to split the txq deinit into two parts.

Jisheng Zhang (2):
  net: mvneta: split rxq/txq init and txq deinit into SW and HW parts
  net: mvneta: improve suspend/resume

 drivers/net/ethernet/marvell/mvneta.c | 154 ++++++++++++++++++++++++++++------
 1 file changed, 128 insertions(+), 26 deletions(-)

-- 
2.16.3

^ permalink raw reply

* linux-next: Signed-off-by missing for commits in the net-next tree
From: Stephen Rothwell @ 2018-04-02  2:30 UTC (permalink / raw)
  To: David Miller, Networking
  Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Johan Hedberg,
	Marcel Holtmann

[-- Attachment #1: Type: text/plain, Size: 419 bytes --]

Hi all,

Commits

  45a42bc9cc65 ("Bluetooth: hci_bcm: Remove DMI quirk for the MINIX Z83-4")
  f9b95db0165a ("Bluetooth: btrsi: remove unused including <linux/version.h>")
  96e58d368fa6 ("Bluetooth: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for BTUSB_QCA_ROME")
  9ea471320e13 ("Bluetooth: Mark expected switch fall-throughs")

are missing a Signed-off-by from their committer.

-- 
Cheers,
Stephen Rothwell

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH net 0/2] net: bgmac: Couple of sparse warnings
From: David Miller @ 2018-04-02  2:21 UTC (permalink / raw)
  To: f.fainelli
  Cc: netdev, scott.branden, andrew, abhishek.shah, ray.jui,
	linux-kernel, jon.mason, nbd
In-Reply-To: <20180401172630.12883-1-f.fainelli@gmail.com>

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Sun,  1 Apr 2018 10:26:28 -0700

> This patch series fixes a couple of warnings reported by sparse, should not
> cause any functional problems since bgmac is typically used on LE platforms
> anyway.

Series applied, thanks Florian.

^ permalink raw reply

* Re: INFO: rcu detected stall in vprintk_func
From: Sergey Senozhatsky @ 2018-04-02  2:04 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Dmitry Vyukov, syzbot, LKML, Petr Mladek, Steven Rostedt,
	Sergey Senozhatsky, syzkaller-bugs, Samuel Ortiz, David Miller,
	linux-wireless, netdev
In-Reply-To: <20180402015422.GA3795@jagdpanzerIV>

On (04/02/18 10:54), Sergey Senozhatsky wrote:
> > > If you forward the report, please keep this part and the footer.
> > >
> > > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU

[..]

> diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
> index ef4026a23e80..a309a27581da 100644
> --- a/net/nfc/llcp_core.c
> +++ b/net/nfc/llcp_core.c
> @@ -1386,7 +1386,7 @@ static void nfc_llcp_recv_agf(struct nfc_llcp_local *local, struct sk_buff *skb)
>  
>  		new_skb = nfc_alloc_recv_skb(pdu_len, GFP_KERNEL);
>  		if (new_skb == NULL) {
> -			pr_err("Could not allocate PDU\n");
> +			pr_err_ratelimited("Could not allocate PDU\n");
>  			return;
>  		}

And of course I ended up patching the wrong function...
What I actually meant was:

---

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 2ceefa183cee..2f3becb709b8 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -755,7 +755,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
 		pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
 					 frag_len + LLCP_HEADER_SIZE, &err);
 		if (pdu == NULL) {
-			pr_err("Could not allocate PDU\n");
+			pr_err_ratelimited("Could not allocate PDU\n");
 			continue;
 		}
 

^ permalink raw reply related

* Re: INFO: rcu detected stall in vprintk_default
From: Sergey Senozhatsky @ 2018-04-02  1:57 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: syzbot, Samuel Ortiz, David Miller, linux-wireless, netdev, LKML,
	Petr Mladek, Steven Rostedt, Sergey Senozhatsky, syzkaller-bugs
In-Reply-To: <CACT4Y+bM0-QmQOQBjvGCJ+yKjXjOHHi9khDr=R4Xi79GF+Ej4w@mail.gmail.com>

On (04/01/18 12:52), Dmitry Vyukov wrote:
> 
> Seems to be the same as:
> 
> #syz dup: INFO: rcu detected stall in vprintk_func
> 
> +nfc maintainers

Yes, seems to be the same issue.

	-ss

^ permalink raw reply

* Re: INFO: rcu detected stall in vprintk_func
From: Sergey Senozhatsky @ 2018-04-02  1:54 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: syzbot, LKML, Petr Mladek, Steven Rostedt, Sergey Senozhatsky,
	syzkaller-bugs, Samuel Ortiz, David Miller, linux-wireless,
	netdev
In-Reply-To: <CACT4Y+YxuvQLZjWau99-7i8dmtxtjnpX6uteabF5rorYMj5v1w@mail.gmail.com>

On (04/01/18 12:51), Dmitry Vyukov wrote:
[..]
> > IMPORTANT: if you fix the bug, please add the following tag to the commit:
> > Reported-by: syzbot+3f28bd18291266ec826b@syzkaller.appspotmail.com
> > It will help syzbot understand when the bug is fixed. See footer for
> > details.
> > If you forward the report, please keep this part and the footer.
> >
> > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU
> > llcp: nfc_llcp_send_ui_frame: Could not allocate PDU

Yes, this thing

	do {
		remote_miu = sock->remote_miu > LLCP_MAX_MIU ?
				local->remote_miu : sock->remote_miu;

		frag_len = min_t(size_t, remote_miu, remaining_len);

		pr_debug("Fragment %zd bytes remaining %zd",
			 frag_len, remaining_len);

		pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
					 frag_len + LLCP_HEADER_SIZE, &err);
		if (pdu == NULL) {
			pr_err("Could not allocate PDU\n");
			continue;
			^^^^^^^^
		}

is basically

	do {
		pr_err("Could not allocate PDU\n");
	} while (1)

Can cause problems sometimes. But this loop is a bit worrisome
even without the printk() call.

>From printk() side, we only can do rate limiting here. Would be
great if nfc maintainers could take a look and tweak the loop
maybe.

---

diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index ef4026a23e80..a309a27581da 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1386,7 +1386,7 @@ static void nfc_llcp_recv_agf(struct nfc_llcp_local *local, struct sk_buff *skb)
 
 		new_skb = nfc_alloc_recv_skb(pdu_len, GFP_KERNEL);
 		if (new_skb == NULL) {
-			pr_err("Could not allocate PDU\n");
+			pr_err_ratelimited("Could not allocate PDU\n");
 			return;
 		}
 

^ permalink raw reply related

* RE: [PATCH v4 iproute2-next 0/7] cm_id, cq, mr, and pd resource tracking
From: Steve Wise @ 2018-04-02  1:13 UTC (permalink / raw)
  To: 'Leon Romanovsky', 'David Ahern'
  Cc: stephen, netdev, linux-rdma
In-Reply-To: <20180401182945.GI22232@mtr-leonro.local>

> 
> On Sun, Apr 01, 2018 at 09:22:14AM -0600, David Ahern wrote:
> > On 3/29/18 3:38 PM, Steve Wise wrote:
> > > This series enhances the iproute2 rdma tool to include dumping of
> > > connection manager id (cm_id), completion queue (cq), memory region
> (mr),
> > > and protection domain (pd) rdma resources.  It is the user-space part
of
> > > the kernel resource tracking series merged into rdma-next for 4.17 [1]
> > > and [2].
> > >
> > > Changes since v3:
> > > - replaced rdma_cma.h inclusion with UAPI rdma_user_cm.h
> > > - display only device names instead of device/port for cq, mr, and pd
> > > since they are not associated with a specific port.
> > >
> > > Changes since v2:
> > > - pull in rdma-core:include/rdma/rdma_cma.h
> > > - 80 column reformat
> > > - add reviewed-by tags
> > >
> > > Changes since v1/RFC:
> > > - removed RFC tag
> > > - initialize rd properly to avoid passing a garbage port number
> > > - revert accidental change to qp_valid_filters
> > > - removed cm_id dev/network/transport types
> > > - cm_id ip addrs now passed up as __kernel_sockaddr_storage
> > > - cm_id ip address ports printed as "address:port" strings
> > > - only parse/display memory keys and iova if available
> > > - filter on "users" for cqs and pds
> > > - fixed memory leaks
> > > - removed PD_FLAGS attribute
> > > - filter on "mrlen" for mrs
> > > - filter on "poll-ctx" for cqs
> > > - don't require addrs or qp_type for parsing cm_ids
> > > - only filter optional attrs if they are present
> > > - remove PGSIZE MR attr to match kernel
> > >
> > > [1] https://www.spinics.net/lists/linux-rdma/msg61720.html
> > > [2] https://www.spinics.net/lists/linux-rdma/msg62979.html
> > >     https://www.spinics.net/lists/linux-rdma/msg62980.html
> > >
> > > ---
> > >
> >
> > applied to iproute2-next. Thanks,
> 
> Thanks David
> 

Yes, Thanks David and Leon.

^ permalink raw reply

* Re: [PATCH net] route: check sysctl_fib_multipath_use_neigh earlier than hash
From: David Miller @ 2018-04-02  0:58 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, ja, dsa
In-Reply-To: <6265ae9495a93efac372d41001c5ebccbb916df7.1522593635.git.lucien.xin@gmail.com>

From: Xin Long <lucien.xin@gmail.com>
Date: Sun,  1 Apr 2018 22:40:35 +0800

> Prior to this patch, when one packet is hashed into path [1]
> (hash <= nh_upper_bound) and it's neigh is dead, it will try
> path [2]. However, if path [2]'s neigh is alive but it's
> hash > nh_upper_bound, it will not return this alive path.
> This packet will never be sent even if path [2] is alive.
> 
>  3.3.3.1/24:
>   nexthop via 1.1.1.254 dev eth1 weight 1 <--[1] (dead neigh)
>   nexthop via 2.2.2.254 dev eth2 weight 1 <--[2]
> 
> With sysctl_fib_multipath_use_neigh set is supposed to find an
> available path respecting to the l3/l4 hash. But if there is
> no available route with this hash, it should at least return
> an alive route even with other hash.
> 
> This patch is to fix it by processing fib_multipath_use_neigh
> earlier than the hash check, so that it will at least return
> an alive route if there is when fib_multipath_use_neigh is
> enabled. It's also compatible with before when there are alive
> routes with the l3/l4 hash.
> 
> Fixes: a6db4494d218 ("net: ipv4: Consider failed nexthops in multipath routes")
> Reported-by: Jianlin Shi <jishi@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Applied and queued up for -stable, thanks.

^ permalink raw reply

* Re: [PATCH] [PATCH] fix typo in command value in drivers/net/phy/mdio-bitbang.
From: David Miller @ 2018-04-02  0:57 UTC (permalink / raw)
  To: fransmeulenbroeks; +Cc: netdev, trivial
In-Reply-To: <1522615975-20952-1-git-send-email-fransmeulenbroeks@gmail.com>

From: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Date: Sun,  1 Apr 2018 22:52:55 +0200

> mdio-bitbang mentioned 10 for both read and write.
> However mdio read opcode is 10 and write opcode is 01
> Fixed comment.
> 
> Signed-off-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH] sky2: Increase D3 delay to sky2 stops working after suspend
From: David Miller @ 2018-04-02  0:56 UTC (permalink / raw)
  To: kai.heng.feng; +Cc: mlindner, stephen, netdev, linux-kernel, stable
In-Reply-To: <20180331154203.5562-1-kai.heng.feng@canonical.com>

From: Kai-Heng Feng <kai.heng.feng@canonical.com>
Date: Sat, 31 Mar 2018 23:42:03 +0800

> The sky2 ethernet stops working after system resume from suspend:
> [ 582.852065] sky2 0000:04:00.0: Refused to change power state, currently in D3
> 
> The current 150ms delay is not enough, change it to 200ms can solve the
> issue.
> 
> BugLink: https://bugs.launchpad.net/bugs/1758507
> Cc: Stable <stable@vger.kernel.org>
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>

Applied.

^ permalink raw reply

* Re: [PATCH net 1/1] net/mlx5e: Set EQE based as default TX interrupt moderation mode
From: David Miller @ 2018-04-02  0:56 UTC (permalink / raw)
  To: saeedm; +Cc: netdev, talgi
In-Reply-To: <20180330225008.21042-1-saeedm@mellanox.com>

From: Saeed Mahameed <saeedm@mellanox.com>
Date: Fri, 30 Mar 2018 15:50:08 -0700

> From: Tal Gilboa <talgi@mellanox.com>
> 
> The default TX moderation mode was mistakenly set to CQE based. The
> intention was to add a control ability in order to improve some specific
> use-cases. In general, we prefer to use EQE based moderation as it gives
> much better numbers for the common cases.
> 
> CQE based causes a degradation in the common case since it resets the
> moderation timer on CQE generation. This causes an issue when TSO is
> well utilized (large TSO sessions). The timer is set to 16us so traffic
> of ~64KB TSO sessions per second would mean timer reset (CQE per TSO
> session -> long time between CQEs). In this case we quickly reach the
> tcp_limit_output_bytes (256KB by default) and cause a halt in TX traffic.
> 
> By setting EQE based moderation we make sure timer would expire after
> 16us regardless of the packet rate.
> This fixes an up to 40% packet rate and up to 23% bandwidth degradtions.
> 
> Fixes: 0088cbbc4b66 ("net/mlx5e: Enable CQE based moderation on TX CQ")
> Signed-off-by: Tal Gilboa <talgi@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH net] ibmvnic: Disable irqs before exiting reset from closed state
From: David Miller @ 2018-04-02  0:56 UTC (permalink / raw)
  To: jallen; +Cc: netdev, tlfalcon, nfont
In-Reply-To: <4511c12c-0a2a-8d46-531d-2bdc1293ca00@linux.vnet.ibm.com>

From: John Allen <jallen@linux.vnet.ibm.com>
Date: Fri, 30 Mar 2018 13:44:21 -0500

> When the driver is closed, all the associated irqs are disabled. In the
> event that the driver exits a reset in the closed state, we should be
> consistent with the state we are in directly after a close. So before we
> exit the reset routine, all irqs should be disabled as well. This will
> prevent the irqs from being enabled twice in this case and reporting a
> number of noisy warning traces.
> 
> Signed-off-by: John Allen <jallen@linux.vnet.ibm.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: sched: do not emit messages while holding spinlock
From: David Miller @ 2018-04-02  0:56 UTC (permalink / raw)
  To: lirongqing; +Cc: netdev
In-Reply-To: <1522375881-29142-1-git-send-email-lirongqing@baidu.com>

From: Li RongQing <lirongqing@baidu.com>
Date: Fri, 30 Mar 2018 10:11:21 +0800

> move messages emitting out of sch_tree_lock to avoid holding
> this lock too long.
> 
> Signed-off-by: Li RongQing <lirongqing@baidu.com>

Applied.

^ permalink raw reply

* Re: [PATCH net] vlan: also check phy_driver ts_info for vlan's real device
From: David Miller @ 2018-04-02  0:56 UTC (permalink / raw)
  To: liuhangbin; +Cc: netdev, richardcochran
In-Reply-To: <1522374240-18673-1-git-send-email-liuhangbin@gmail.com>

From: Hangbin Liu <liuhangbin@gmail.com>
Date: Fri, 30 Mar 2018 09:44:00 +0800

> Just like function ethtool_get_ts_info(), we should also consider the
> phy_driver ts_info call back. For example, driver dp83640.
> 
> Fixes: 37dd9255b2f6 ("vlan: Pass ethtool get_ts_info queries to real device.")
> Acked-by: Richard Cochran <richardcochran@gmail.com>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH] net: improve ipv4 performances
From: Md. Islam @ 2018-04-02  0:51 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Anton Gary Ceph, netdev, linux-kernel
In-Reply-To: <20180401115044.17f7ccb4@xeon-e3>

Yes, I'm also seeing good performance improvement after adding
likely() and prefetch().

On Sun, Apr 1, 2018 at 2:50 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Sun,  1 Apr 2018 20:31:21 +0200
> Anton Gary Ceph <agaceph@gmail.com> wrote:
>
>> As the Linux networking stack is growing, more and more protocols are
>> added, increasing the complexity of stack itself.
>> Modern processors, contrary to common belief, are very bad in branch
>> prediction, so it's our task to give hints to the compiler when possible.
>>
>> After a few profiling and analysis, turned out that the ethertype field
>> of the packets has the following distribution:
>>
>>     92.1% ETH_P_IP
>>      3.2% ETH_P_ARP
>>      2.7% ETH_P_8021Q
>>      1.4% ETH_P_PPP_SES
>>      0.6% don't know/no opinion
>>
>> From a projection on statistics collected by Google about IPv6 adoption[1],
>> IPv6 should peak at 25% usage at the beginning of 2030. Hence, we should
>> give proper hints to the compiler about the low IPv6 usage.
>>
>> Here is an iperf3 run before and after the patch:
>>
>> Before:
>> [ ID]  Interval           Transfer    Bandwidth       Retr
>> [  4]  0.00-100.00 sec    100 GBytes  8.60 Gbits/sec  0       sender
>> [  4]  0.00-100.00 sec    100 GBytes  8.60 Gbits/sec          receiver
>>
>> After
>> [ ID]  Interval           Transfer    Bandwidth       Retr
>> [  4]  0.00-100.00 sec    109 GBytes  9.35 Gbits/sec  0       sender
>> [  4]  0.00-100.00 sec    109 GBytes  9.35 Gbits/sec          receiver
>>
>> [1] https://www.google.com/intl/en/ipv6/statistics.html
>>
>> Signed-off-by: Anton Gary Ceph <agaceph@gmail.com>
>
> I am surprised it makes that much of an impact.
>
> It would be easier to manage future bisection if the big patch
> was split into several pieces. Bridge,  bonding, netfilter, etc.
> There doesn't appear to be any direct cross dependencies.
>
>



-- 
Tamim
PhD Candidate,
Kent State University
http://web.cs.kent.edu/~mislam4/

^ permalink raw reply

* [PATCH v15 ] net/veth/XDP: Line-rate packet forwarding in kernel
From: Md. Islam @ 2018-04-02  0:47 UTC (permalink / raw)
  To: netdev, David Miller, David Ahern, stephen, agaceph,
	Pavel Emelyanov, Eric Dumazet, alexei.starovoitov, brouer

[-- Attachment #1: Type: text/plain, Size: 10604 bytes --]

This patch implements IPv4 forwarding on xdp_buff. I added a new
config option XDP_ROUTER. Kernel would forward packets through fast
path when this option is enabled. But it would require driver support.
Currently it only works with veth. Here I have modified veth such that
it outputs xdp_buff. I created a testbed in Mininet. The Mininet
script (topology.py) is attached. Here the topology is:

h1 -----r1-----h2 (r1 acts as a router)

This patch improves the throughput from 53.8Gb/s to 60Gb/s on my
machine. Median RTT also improved from around .055 ms to around .035
ms.

Then I disabled hyperthreading and cpu frequency scaling in order to
utilize CPU cache (DPDK also utilizes CPU cache to improve
forwarding). This further improves per-packet forwarding latency from
around 400ns to 200 ns. More specifically, header parsing and fib
lookup only takes around 82 ns. This shows that this could be used to
implement linerate packet forwarding in kernel.

The patch has been generated on 4.15.0+. Please let me know your
feedback and suggestions. Please feel free to let me know if this
approach make sense.

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 944ec3c..8474eef 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -328,6 +328,18 @@ config VETH
       When one end receives the packet it appears on its pair and vice
       versa.

+config XDP_ROUTER
+    bool "XDP router for veth"
+    depends on IP_ADVANCED_ROUTER
+    depends on VETH
+    default y
+    ---help---
+      This option will enable IP forwarding on incoming xdp_buff.
+      Currently it is only supported by veth. Say y or n.
+
+      Currently veth uses slow path for packet forwarding. This option
+      forwards packets as soon as it is received (as XDP generic).
+
 config VIRTIO_NET
     tristate "Virtio network driver"
     depends on VIRTIO
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index a69ad39..76112f9 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -111,6 +111,29 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb,
struct net_device *dev)
         goto drop;
     }

+#ifdef CONFIG_XDP_ROUTER
+
+    /* if IP forwarding is enabled on the receiver, create xdp_buff
+     * from skb and call xdp_router_forward()
+     */
+    if (is_forwarding_enabled(rcv)) {
+        struct xdp_buff *xdp = kmalloc(sizeof(*xdp), GFP_KERNEL);
+
+        xdp->data = skb->data;
+        xdp->data_end = skb->data + (skb->len - skb->data_len);
+        xdp->data_meta = skb;
+        prefetch_xdp(xdp);
+        if (likely(xdp_router_forward(rcv, xdp) == NET_RX_SUCCESS)) {
+            struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);
+
+            u64_stats_update_begin(&stats->syncp);
+            stats->bytes += length;
+            stats->packets++;
+            u64_stats_update_end(&stats->syncp);
+            goto success;
+        }
+    }
+#endif
     if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {
         struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);

@@ -122,6 +145,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb,
struct net_device *dev)
 drop:
         atomic64_inc(&priv->dropped);
     }
+success:
     rcu_read_unlock();
     return NETDEV_TX_OK;
 }
@@ -276,6 +300,62 @@ static void veth_set_rx_headroom(struct
net_device *dev, int new_hr)
     rcu_read_unlock();
 }

+#ifdef CONFIG_XDP_ROUTER
+int veth_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp)
+{
+    struct veth_priv *priv = netdev_priv(dev);
+    struct net_device *rcv;
+    struct ethhdr *ethh;
+    struct sk_buff *skb;
+    int length = xdp->data_end - xdp->data;
+
+    rcu_read_lock();
+    rcv = rcu_dereference(priv->peer);
+    if (unlikely(!rcv)) {
+        kfree(xdp);
+        goto drop;
+    }
+
+    /* Update MAC address and checksum */
+    ethh = eth_hdr_xdp(xdp);
+    ether_addr_copy(ethh->h_source, dev->dev_addr);
+    ether_addr_copy(ethh->h_dest, rcv->dev_addr);
+
+    /* if IP forwarding is enabled on the receiver,
+     * call xdp_router_forward()
+     */
+    if (is_forwarding_enabled(rcv)) {
+        prefetch_xdp(xdp);
+        if (likely(xdp_router_forward(rcv, xdp) == NET_RX_SUCCESS)) {
+            struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);
+
+            u64_stats_update_begin(&stats->syncp);
+            stats->bytes += length;
+            stats->packets++;
+            u64_stats_update_end(&stats->syncp);
+            goto success;
+        }
+    }
+
+    /* Local deliver */
+    skb = (struct sk_buff *)xdp->data_meta;
+    if (likely(dev_forward_skb(rcv, skb) == NET_RX_SUCCESS)) {
+        struct pcpu_vstats *stats = this_cpu_ptr(dev->vstats);
+
+        u64_stats_update_begin(&stats->syncp);
+        stats->bytes += length;
+        stats->packets++;
+        u64_stats_update_end(&stats->syncp);
+    } else {
+drop:
+        atomic64_inc(&priv->dropped);
+    }
+success:
+    rcu_read_unlock();
+    return NETDEV_TX_OK;
+}
+#endif
+
 static const struct net_device_ops veth_netdev_ops = {
     .ndo_init            = veth_dev_init,
     .ndo_open            = veth_open,
@@ -290,6 +370,9 @@ static const struct net_device_ops veth_netdev_ops = {
     .ndo_get_iflink        = veth_get_iflink,
     .ndo_features_check    = passthru_features_check,
     .ndo_set_rx_headroom    = veth_set_rx_headroom,
+#ifdef CONFIG_XDP_ROUTER
+    .ndo_xdp_xmit        = veth_xdp_xmit,
+#endif
 };

 #define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 492bc65..025a3ec 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -19,6 +19,29 @@

 #include <linux/skbuff.h>
 #include <uapi/linux/ip.h>
+#include <linux/filter.h>
+
+#ifdef CONFIG_XDP_ROUTER
+
+#define MIN_PACKET_SIZE 55
+
+static inline struct iphdr *ip_hdr_xdp(const struct xdp_buff *xdp)
+{
+    return (struct iphdr *)(xdp->data+ETH_HLEN);
+}
+
+static inline struct ethhdr *eth_hdr_xdp(const struct xdp_buff *xdp)
+{
+    return (struct ethhdr *)(xdp->data);
+}
+
+static inline bool is_xdp_forwardable(const struct xdp_buff *xdp)
+{
+    return xdp->data_end - xdp->data >= MIN_PACKET_SIZE;
+}
+
+#endif
+

 static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
 {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4c77f39..e3bf002 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3290,6 +3290,12 @@ static inline void dev_consume_skb_any(struct
sk_buff *skb)
     __dev_kfree_skb_any(skb, SKB_REASON_CONSUMED);
 }

+#ifdef CONFIG_XDP_ROUTER
+bool is_forwarding_enabled(struct net_device *dev);
+int xdp_router_forward(struct net_device *dev, struct xdp_buff *xdp);
+void prefetch_xdp(struct xdp_buff *xdp);
+#endif
+
 void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog);
 int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb);
 int netif_rx(struct sk_buff *skb);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index f805243..623b2de 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -369,6 +369,12 @@ int fib_sync_down_dev(struct net_device *dev,
unsigned long event, bool force);
 int fib_sync_down_addr(struct net_device *dev, __be32 local);
 int fib_sync_up(struct net_device *dev, unsigned int nh_flags);

+#ifdef CONFIG_XDP_ROUTER
+int ip_route_lookup(__be32 daddr, __be32 saddr,
+                   u8 tos, struct net_device *dev,
+                   struct fib_result *res);
+#endif
+
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
                const struct sk_buff *skb);
diff --git a/net/core/dev.c b/net/core/dev.c
index dda9d7b..9d92352 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4090,6 +4090,65 @@ int do_xdp_generic(struct bpf_prog *xdp_prog,
struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(do_xdp_generic);

+#ifdef CONFIG_XDP_ROUTER
+
+bool is_forwarding_enabled(struct net_device *dev)
+{
+    struct in_device *in_dev;
+
+    /* verify forwarding is enabled on this interface */
+    in_dev = __in_dev_get_rcu(dev);
+    if (unlikely(!in_dev || !IN_DEV_FORWARD(in_dev)))
+        return false;
+
+    return true;
+}
+EXPORT_SYMBOL_GPL(is_forwarding_enabled);
+
+int xdp_router_forward(struct net_device *dev, struct xdp_buff *xdp)
+{
+        int err;
+        struct fib_result res;
+        struct iphdr *iph;
+        struct net_device *rcv;
+
+        if (unlikely(xdp->data_end - xdp->data < MIN_PACKET_SIZE))
+            return NET_RX_DROP;
+
+        iph = (struct iphdr *)(xdp->data + ETH_HLEN);
+
+        /*currently only supports IPv4
+         */
+        if (unlikely(iph->version != 4))
+            return NET_RX_DROP;
+
+        err = ip_route_lookup(iph->daddr, iph->saddr,
+                      iph->tos, dev, &res);
+        if (unlikely(err))
+            return NET_RX_DROP;
+
+        rcv = FIB_RES_DEV(res);
+        if (likely(rcv)) {
+            if (likely(rcv->netdev_ops->ndo_xdp_xmit(rcv, xdp) ==
+                       NETDEV_TX_OK))
+                return NET_RX_SUCCESS;
+        }
+
+        return NET_RX_DROP;
+}
+EXPORT_SYMBOL_GPL(xdp_router_forward);
+
+inline void prefetch_xdp(struct xdp_buff *xdp)
+{
+        prefetch(xdp);
+        /* prefetch version, tos, saddr and daddr of IP header */
+        prefetch(xdp->data + ETH_HLEN);
+        prefetch(xdp->data + ETH_HLEN + 12);
+}
+EXPORT_SYMBOL_GPL(prefetch_xdp);
+
+#endif
+
 static int netif_rx_internal(struct sk_buff *skb)
 {
     int ret;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 49cc1c1..2333205 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1866,6 +1866,35 @@ static int ip_mkroute_input(struct sk_buff *skb,
     return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
 }

+#ifdef CONFIG_XDP_ROUTER
+
+int ip_route_lookup(__be32 daddr, __be32 saddr,
+            u8 tos, struct net_device *dev,
+            struct fib_result *res)
+{
+    struct flowi4    fl4;
+    int        err;
+    struct net    *net = dev_net(dev);
+
+    fl4.flowi4_oif = 0;
+    fl4.flowi4_iif = dev->ifindex;
+    fl4.flowi4_mark = 0;
+    fl4.flowi4_tos = tos & IPTOS_RT_MASK;
+    fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
+    fl4.flowi4_flags = 0;
+    fl4.daddr = daddr;
+    fl4.saddr = saddr;
+
+    err = fib_lookup(net, &fl4, res, 0);
+
+    if (unlikely(err != 0 || res->type != RTN_UNICAST))
+        return -EINVAL;
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ip_route_lookup);
+#endif
+
 /*
  *    NOTE. We drop all the packets that has local source
  *    addresses, because every properly looped back packet

Many thanks
Tamim

[-- Attachment #2: topology.py --]
[-- Type: text/x-python, Size: 3289 bytes --]

#!/usr/bin/python

"""

##############################################################################
# Topology with one router and two hosts with static routes
#
#       172.16.101.0/24         172.16.102.0/24   
#  h1 ------------------- r1 ------------------ h2
#    .1                .2   .3               .1   
#
##############################################################################

Here r1 acts as a Linux router. There are two veth-pairs in our topology as following.

h1-eth0-------r1-eth2       r1-eth3-----h2eth0    

Packets received on r1-eth2 is being transmitted to r1-eth3 using XDP fast path. Packets are generated on h1 towards h2 using iperf.

"""


from mininet.topo import Topo
from mininet.net import Mininet
from mininet.link import TCLink
from mininet.node import Node, CPULimitedHost
from mininet.log import setLogLevel, info
from mininet.util import custom, waitListening
from mininet.cli import CLI
import sys
import time

class LinuxRouter( Node ):
    "A Node with IP forwarding enabled."

    def config( self, **params ):
        super( LinuxRouter, self).config( **params )
        # Enable forwarding on the router
        self.cmd( 'sysctl net.ipv4.ip_forward=1' )

    def terminate( self ):
        self.cmd( 'sysctl net.ipv4.ip_forward=0' )
        super( LinuxRouter, self ).terminate()

class NetworkTopo( Topo ):
    def build( self, **_opts ):	
        h1 = self.addHost( 'h1', ip='172.16.101.1/24', defaultRoute='via 172.16.101.2' )
        h2 = self.addHost( 'h2', ip='172.16.102.1/24', defaultRoute='via 172.16.102.3' )
	r1 = self.addNode( 'r1', cls=LinuxRouter, ip='172.16.101.2/24' )

        self.addLink( h1, r1, intfName2='r1-eth2', params2={ 'ip' : '172.16.101.2/24' })
        self.addLink( h2, r1, intfName2='r1-eth3', params2={ 'ip' : '172.16.102.3/24' })

def main(cli=0):
    "Test linux router"
    topo = NetworkTopo()

    net = Mininet( topo=topo, controller = None )
    net.start()

#   testing using port 45678, TCP window size 20MB and 10 connection. 
    res = net['h2'].cmd('iperf -s -p 45678 -w 20MB &')
#Anyhing that blocks shouldn't be used in cmd(). Use popen() instead. It will create a new process. Now monitor the output of the process
    proc = net['h1'].popen('iperf -c 172.16.102.1 -p 45678 -t 30  -w 20MB -P 10')


#    print res #Don't uncomment this. Strange things happen :-(

#Parse the res to find out the PID of iperf server. The program can crash if res isn't formatted properly. Try again
    pid = res.split(" ")
    iperf_s_pid = pid[1]
    iperf_c_pid = int(pid[1]) + 1

    print pid[1], int(pid[1]) + 1

#Pin iperf server and client to core 0 and 1 respectively. Note that throughput you get depends on other applications running on a CPU. So if you get bad throughput, try restatring. Even though you close some applications, the process can sit in the backgroud
    net['h2'].cmd('sudo taskset -pc 0 {0}'.format(iperf_s_pid))
    net['h1'].cmd('sudo taskset -pc 1 {0}'.format(iperf_c_pid)) 

    for line in iter(proc.stdout.readline, b''):
	print line

    net['h2'].cmd('sudo kill -9 {0}'.format(iperf_s_pid))
    net['h1'].cmd('sudo kill -9 {0}'.format(iperf_c_pid))

    CLI( net )
    net.stop()

if __name__ == '__main__':
    args = sys.argv
    setLogLevel( 'info' )
    main()

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox