* [PATCH net-next 3/3] ip: Add support for IP_CHECKSUM cmsg
From: Tom Herbert @ 2014-12-04 0:44 UTC (permalink / raw)
To: davem, netdev
In-Reply-To: <1417653868-14922-1-git-send-email-therbert@google.com>
New cmsg type is IP_CHECKSUM under SOL_IP. Enabled by standard
setsockopt.
The value returned is the unfolded 32 bit checksum of the packet
being received starting from the first byte returned in recvmsg
through the end of the packet (truncation is disregarded).
Modified UDP to postpull checksum beyond UDP header before returning
checksum for UDP data to userspace.
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/net/inet_sock.h | 1 +
include/uapi/linux/in.h | 1 +
net/ipv4/ip_sockglue.c | 34 +++++++++++++++++++++++++++++++++-
net/ipv4/udp.c | 10 +++++++++-
4 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 4091fab..2823fc0 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -203,6 +203,7 @@ struct inet_sock {
#define IP_CMSG_RETOPTS (1 << 4)
#define IP_CMSG_PASSSEC (1 << 5)
#define IP_CMSG_ORIGDSTADDR (1 << 6)
+#define IP_CMSG_CHECKSUM (1 << 7)
static inline struct inet_sock *inet_sk(const struct sock *sk)
{
diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
index c33a65e..589ced0 100644
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -109,6 +109,7 @@ struct in_addr {
#define IP_MINTTL 21
#define IP_NODEFRAG 22
+#define IP_CHECKSUM 23
/* IP_MTU_DISCOVER values */
#define IP_PMTUDISC_DONT 0 /* Never send DF frames */
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index d4406aa..054280f 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -96,6 +96,14 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
}
+static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb)
+{
+ if (skb->ip_summed != CHECKSUM_COMPLETE)
+ return;
+
+ put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &skb->csum);
+}
+
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
{
char *secdata;
@@ -190,9 +198,16 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
return;
}
- if (flags & IP_CMSG_ORIGDSTADDR)
+ if (flags & IP_CMSG_ORIGDSTADDR) {
ip_cmsg_recv_dstaddr(msg, skb);
+ flags &= ~IP_CMSG_ORIGDSTADDR;
+ if (!flags)
+ return;
+ }
+
+ if (flags & IP_CMSG_CHECKSUM)
+ ip_cmsg_recv_checksum(msg, skb);
}
EXPORT_SYMBOL(ip_cmsg_recv);
@@ -512,6 +527,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
case IP_MULTICAST_ALL:
case IP_MULTICAST_LOOP:
case IP_RECVORIGDSTADDR:
+ case IP_CHECKSUM:
if (optlen >= sizeof(int)) {
if (get_user(val, (int __user *) optval))
return -EFAULT;
@@ -609,6 +625,19 @@ static int do_ip_setsockopt(struct sock *sk, int level,
else
inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR;
break;
+ case IP_CHECKSUM:
+ if (val) {
+ if (!(inet->cmsg_flags & IP_CMSG_CHECKSUM)) {
+ inet_inc_convert_csum(sk);
+ inet->cmsg_flags |= IP_CMSG_CHECKSUM;
+ }
+ } else {
+ if (inet->cmsg_flags & IP_CMSG_CHECKSUM) {
+ inet_dec_convert_csum(sk);
+ inet->cmsg_flags &= ~IP_CMSG_CHECKSUM;
+ }
+ }
+ break;
case IP_TOS: /* This sets both TOS and Precedence */
if (sk->sk_type == SOCK_STREAM) {
val &= ~INET_ECN_MASK;
@@ -1212,6 +1241,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
case IP_RECVORIGDSTADDR:
val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
break;
+ case IP_CHECKSUM:
+ val = (inet->cmsg_flags & IP_CMSG_CHECKSUM) != 0;
+ break;
case IP_TOS:
val = inet->tos;
break;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 221b53f..bba2e06 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1315,8 +1315,16 @@ try_again:
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
*addr_len = sizeof(*sin);
}
- if (inet->cmsg_flags)
+ if (inet->cmsg_flags) {
+ /* Pull checksum past UDP header in case we are providing
+ * checksum in cmsg.
+ */
+ if (inet->cmsg_flags & IP_CMSG_CHECKSUM)
+ skb_postpull_rcsum(skb, skb->data,
+ sizeof(struct udphdr));
+
ip_cmsg_recv(msg, skb);
+ }
err = copied;
if (flags & MSG_TRUNC)
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next 1/3] ip: Move checksum convert defines to inet
From: Tom Herbert @ 2014-12-04 0:44 UTC (permalink / raw)
To: davem, netdev
In-Reply-To: <1417653868-14922-1-git-send-email-therbert@google.com>
Move convert_csum from udp_sock to inet_sock. This allows the
possibility that we can use convert checksum for different types
of sockets and also allows convert checksum to be enabled from
inet layer (what we'll want to do when enabling IP_CHECKSUM cmsg).
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/udp.h | 16 +---------------
include/net/inet_sock.h | 17 +++++++++++++++++
net/ipv4/fou.c | 2 +-
net/ipv4/udp.c | 2 +-
net/ipv4/udp_tunnel.c | 2 +-
net/ipv6/udp.c | 2 +-
6 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/include/linux/udp.h b/include/linux/udp.h
index ee32775..247cfdc 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -49,11 +49,7 @@ struct udp_sock {
unsigned int corkflag; /* Cork is required */
__u8 encap_type; /* Is this an Encapsulation socket? */
unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
- no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
- convert_csum:1;/* On receive, convert checksum
- * unnecessary to checksum complete
- * if possible.
- */
+ no_check6_rx:1;/* Allow zero UDP6 checksums on RX? */
/*
* Following member retains the information to create a UDP header
* when the socket is uncorked.
@@ -102,16 +98,6 @@ static inline bool udp_get_no_check6_rx(struct sock *sk)
return udp_sk(sk)->no_check6_rx;
}
-static inline void udp_set_convert_csum(struct sock *sk, bool val)
-{
- udp_sk(sk)->convert_csum = val;
-}
-
-static inline bool udp_get_convert_csum(struct sock *sk)
-{
- return udp_sk(sk)->convert_csum;
-}
-
#define udp_portaddr_for_each_entry(__sk, node, list) \
hlist_nulls_for_each_entry(__sk, node, list, __sk_common.skc_portaddr_node)
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index a829b77..360b110 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -184,6 +184,7 @@ struct inet_sock {
mc_all:1,
nodefrag:1;
__u8 rcv_tos;
+ __u8 convert_csum;
int uc_index;
int mc_index;
__be32 mc_addr;
@@ -250,4 +251,20 @@ static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
return flags;
}
+static inline void inet_inc_convert_csum(struct sock *sk)
+{
+ inet_sk(sk)->convert_csum++;
+}
+
+static inline void inet_dec_convert_csum(struct sock *sk)
+{
+ if (inet_sk(sk)->convert_csum > 0)
+ inet_sk(sk)->convert_csum--;
+}
+
+static inline bool inet_get_convert_csum(struct sock *sk)
+{
+ return !!inet_sk(sk)->convert_csum;
+}
+
#endif /* _INET_SOCK_H */
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index b986298..2197c36 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -490,7 +490,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg,
sk->sk_user_data = fou;
fou->sock = sock;
- udp_set_convert_csum(sk, true);
+ inet_inc_convert_csum(sk);
sk->sk_allocation = GFP_ATOMIC;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b2d6068..221b53f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1793,7 +1793,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
if (sk != NULL) {
int ret;
- if (udp_sk(sk)->convert_csum && uh->check && !IS_UDPLITE(sk))
+ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
inet_compute_pseudo);
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c
index 1671263..9996e63 100644
--- a/net/ipv4/udp_tunnel.c
+++ b/net/ipv4/udp_tunnel.c
@@ -63,7 +63,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
inet_sk(sk)->mc_loop = 0;
/* Enable CHECKSUM_UNNECESSARY to CHECKSUM_COMPLETE conversion */
- udp_set_convert_csum(sk, true);
+ inet_inc_convert_csum(sk);
rcu_assign_sk_user_data(sk, cfg->sk_user_data);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 7cfb5d7..5d9900c 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -896,7 +896,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
goto csum_error;
}
- if (udp_sk(sk)->convert_csum && uh->check && !IS_UDPLITE(sk))
+ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk))
skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check,
ip6_compute_pseudo);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* [PATCH net-next 0/3] ip: Support checksum returned in csmg
From: Tom Herbert @ 2014-12-04 0:44 UTC (permalink / raw)
To: davem, netdev
This patch set allows the packet checksum for a datagram socket
to be returned in csum data in recvmsg. This allows userspace
to implement its own checksum over the data, for instance if an
IP tunnel was be implemented in user space, the inner checksum
could be validated.
Changes in this patch set:
- Move checksum conversion to inet_sock from udp_sock. This
generalizes checksum conversion for use with other protocols.
- Move IP cmsg constants to a header file and make processing
of the flags more efficient in ip_cmsg_recv.
- Return checksum value in cmsg. This is specifically the unfolded
32 bit checksum of the full packet starting from the first byte
returned in recvmsg.
Tested: Wrote a little server to get checksums in cmsg for UDP and
verfied correct checksum is returned.
Tom Herbert (3):
ip: Move checksum convert defines to inet
ip: IP cmsg cleanup
ip: Add support for IP_CHECKSUM cmsg
include/linux/udp.h | 16 +--------
include/net/inet_sock.h | 27 ++++++++++++++
include/uapi/linux/in.h | 1 +
net/ipv4/fou.c | 2 +-
net/ipv4/ip_sockglue.c | 96 +++++++++++++++++++++++++++++++++++--------------
net/ipv4/udp.c | 12 +++++--
net/ipv4/udp_tunnel.c | 2 +-
net/ipv6/udp.c | 2 +-
8 files changed, 111 insertions(+), 47 deletions(-)
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply
* Re: [patch net-next v4 8/9] net: move vlan pop/push functions into common code
From: Pravin Shelar @ 2014-12-04 0:33 UTC (permalink / raw)
To: Jiri Benc
Cc: Jiri Pirko, netdev, David Miller, Jamal Hadi Salim, Tom Herbert,
Eric Dumazet, Willem de Bruijn, Daniel Borkmann, mst, fw,
Paul.Durrant, Thomas Graf, Cong Wang
In-Reply-To: <20141121202933.2970b7ea@griffin>
On Fri, Nov 21, 2014 at 11:29 AM, Jiri Benc <jbenc@redhat.com> wrote:
> On Fri, 21 Nov 2014 10:41:27 -0800, Pravin Shelar wrote:
>> There is bug in the openvswitch code where vlan-pop does mac-length
>> reset rather than subtracting VLAN_HLEN from mac-len. MPLS code
>> depends on this. Now this patch moves the bug to common code. I am
>> fine with this patch and I can send fix to change code vlan-pop code
>> to adjust mac_len later on.
>> But I am worried about the comment made by Jiri Benc on earlier
>> version of this patch where is mentioned that subtracting VLAN_HLEN
>> can break common case for vlan-pop. In that case we can not change
>> this common function. Jiri Benc, Can you point me to the code, so the
>> we can work on solution to fix this issue.
>
> In such case, a skb that enters the __pop_vlan_tci function looks like
> this:
>
> +--------+--------+-------------+-----+---------+-------
> | dstmac | srcmac | ETH_P_8021Q | tci | ETH_P_x | data
> +--------+--------+-------------+-----+---------+-------
> ^ ^
> mac_header network_header
>
> skb->protocol = ETH_P_8021Q
> skb->mac_len = 14
>
> After the function finishes, it's supposed to look like this:
>
> +--------+--------+---------+-------
> | dstmac | srcmac | ETH_P_x | data
> +--------+--------+---------+-------
> ^ ^
> mac_header network_header
>
> skb->protocol = ETH_P_x
> skb->mac_len = 14
>
> Blindly decrementing mac_len wouldn't work here, you'd end up with
> mac_len = 10. You'd either need to ensure this case doesn't happen (it
> does with openvswitch currently) or detect this case.
>
OVS correctly sets mac header length in case of vlan header. Can you
give me OVS test case to reproduce this issue?
^ permalink raw reply
* Re: [PATCH iproute2] ss: Use rtnl_dump_filter in handle_netlink_request
From: Vadim Kochan @ 2014-12-04 0:00 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
In-Reply-To: <20141203232819.GA12656@angus-think.lan>
Ofcourse I think it is possible to add checking if protocol ==
NETLINK_INET_DIAG protocol
and dont print the error message in lib/netlink.c if errno == ENOENT,
but I am not sure if you will like such approach ...
On Thu, Dec 4, 2014 at 1:28 AM, <vadim4j@gmail.com> wrote:
> On Wed, Dec 03, 2014 at 03:07:48PM -0800, Stephen Hemminger wrote:
>> On Thu, 4 Dec 2014 00:15:54 +0200
>> Vadim Kochan <vadim4j@gmail.com> wrote:
>>
>> > I established some simple OpenVPN connection (at least by the logs and
>> > ss I see that peer is connected), but
>> > I dont get any errors with ss.
>> >
>> > So can you please provide some more info how did you tested this patch
>> > ? I am surprised that this is caused only
>> > by these changes ...
>> >
>> > On Wed, Dec 3, 2014 at 7:45 PM, <vadim4j@gmail.com> wrote:
>> > > On Wed, Dec 03, 2014 at 09:51:23AM -0800, Stephen Hemminger wrote:
>> > >> On Wed, 3 Dec 2014 19:20:10 +0200
>> > >> vadim4j@gmail.com wrote:
>> > >>
>> > >> > On Wed, Dec 03, 2014 at 09:21:29AM -0800, Stephen Hemminger wrote:
>> > >> > > On Tue, 2 Dec 2014 16:53:04 +0200
>> > >> > > Vadim Kochan <vadim4j@gmail.com> wrote:
>> > >> > >
>> > >> > > > Replaced handling netlink messages by rtnl_dump_filter
>> > >> > > > from lib/libnetlink.c, also:
>> > >> > > >
>> > >> > > > - removed unused dump_fp arg;
>> > >> > > > - added MAGIC_SEQ #define for 123456 seq id
>> > >> > > >
>> > >> > > > Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
>> > >> > >
>> > >> > > This doesn't work correctly.
>> > >> > >
>> > >> > > Simple test
>> > >> > > $ misc/ss >/dev/null
>> > >> > > RTNETLINK answers: No such file or directory
>> > >> > > RTNETLINK answers: No such file or directory
>> > >> > > RTNETLINK answers: No such file or directory
>> > >> >
>> > >> > Just tried, I did not get such errors.
>> > >>
>> > >> I have OpenVPN running.
>> > >
>> > > Hm, it is reproduced only with this patch ?
>> > > If so I will try to setup OpenVPN ... can't imagine how it can be
>> > > related ...
>>
>> I am running on 3.17.4 kernel if that helps.
>
> OK, thank you!
>
> I see a reason why it was caused by this patch. So the difference is in
> the way how the libnetlink/rtnl_* and original ss.c handles the
> NLMSG_ERROR, ss.c netlink handler checks errno ENOENT (No such file or directory)
> and silently closes file end returns -1, but rtnl_* prints the error message.
>
> Meanwhile I dont know the real reason why ENOENT error is happaned, may
> be it is OK in context of diagnostic messages. But I grepped over the
> commits and found that this ENOENT checking was added by Eric in:
>
> commit a3fd8e58c1787af186f5c4b234ff974544f840b6
> Author: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Mon Jan 30 17:05:45 2012 +0100
>
> ss: should support CONFIG_INET_UDP_DIAG=n kernels
>
> ss -x currently fails if CONFIG_INET_UDP_DIAG=n or old kernels
>
> Also close file descriptors while we are at it.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Pavel Emelyanov <xemul@parallels.com>
^ permalink raw reply
* Re: [PATCH iproute2] ss: Use rtnl_dump_filter in handle_netlink_request
From: vadim4j @ 2014-12-03 23:28 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
In-Reply-To: <20141203150748.001d481e@urahara>
On Wed, Dec 03, 2014 at 03:07:48PM -0800, Stephen Hemminger wrote:
> On Thu, 4 Dec 2014 00:15:54 +0200
> Vadim Kochan <vadim4j@gmail.com> wrote:
>
> > I established some simple OpenVPN connection (at least by the logs and
> > ss I see that peer is connected), but
> > I dont get any errors with ss.
> >
> > So can you please provide some more info how did you tested this patch
> > ? I am surprised that this is caused only
> > by these changes ...
> >
> > On Wed, Dec 3, 2014 at 7:45 PM, <vadim4j@gmail.com> wrote:
> > > On Wed, Dec 03, 2014 at 09:51:23AM -0800, Stephen Hemminger wrote:
> > >> On Wed, 3 Dec 2014 19:20:10 +0200
> > >> vadim4j@gmail.com wrote:
> > >>
> > >> > On Wed, Dec 03, 2014 at 09:21:29AM -0800, Stephen Hemminger wrote:
> > >> > > On Tue, 2 Dec 2014 16:53:04 +0200
> > >> > > Vadim Kochan <vadim4j@gmail.com> wrote:
> > >> > >
> > >> > > > Replaced handling netlink messages by rtnl_dump_filter
> > >> > > > from lib/libnetlink.c, also:
> > >> > > >
> > >> > > > - removed unused dump_fp arg;
> > >> > > > - added MAGIC_SEQ #define for 123456 seq id
> > >> > > >
> > >> > > > Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> > >> > >
> > >> > > This doesn't work correctly.
> > >> > >
> > >> > > Simple test
> > >> > > $ misc/ss >/dev/null
> > >> > > RTNETLINK answers: No such file or directory
> > >> > > RTNETLINK answers: No such file or directory
> > >> > > RTNETLINK answers: No such file or directory
> > >> >
> > >> > Just tried, I did not get such errors.
> > >>
> > >> I have OpenVPN running.
> > >
> > > Hm, it is reproduced only with this patch ?
> > > If so I will try to setup OpenVPN ... can't imagine how it can be
> > > related ...
>
> I am running on 3.17.4 kernel if that helps.
OK, thank you!
I see a reason why it was caused by this patch. So the difference is in
the way how the libnetlink/rtnl_* and original ss.c handles the
NLMSG_ERROR, ss.c netlink handler checks errno ENOENT (No such file or directory)
and silently closes file end returns -1, but rtnl_* prints the error message.
Meanwhile I dont know the real reason why ENOENT error is happaned, may
be it is OK in context of diagnostic messages. But I grepped over the
commits and found that this ENOENT checking was added by Eric in:
commit a3fd8e58c1787af186f5c4b234ff974544f840b6
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon Jan 30 17:05:45 2012 +0100
ss: should support CONFIG_INET_UDP_DIAG=n kernels
ss -x currently fails if CONFIG_INET_UDP_DIAG=n or old kernels
Also close file descriptors while we are at it.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
^ permalink raw reply
* Re: [PATCH net] Update old iproute2 and Xen Remus links
From: Stephen Hemminger @ 2014-12-03 23:34 UTC (permalink / raw)
To: Andrew Shewmaker; +Cc: linux-doc, linux-kernel, netdev, corbet, jhs, davem
In-Reply-To: <1417644451-7305-1-git-send-email-agshew@gmail.com>
On Wed, 3 Dec 2014 14:07:31 -0800
Andrew Shewmaker <agshew@gmail.com> wrote:
> Signed-off-by: Andrew Shewmaker <agshew@gmail.com>
> ---
> Documentation/Changes | 2 +-
> net/sched/Kconfig | 7 ++++---
> 2 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/Changes b/Documentation/Changes
> index 1de131b..74bdda9 100644
> --- a/Documentation/Changes
> +++ b/Documentation/Changes
> @@ -383,7 +383,7 @@ o <http://www.iptables.org/downloads.html>
>
> Ip-route2
> ---------
> -o <ftp://ftp.tux.org/pub/net/ip-routing/iproute2-2.2.4-now-ss991023.tar.gz>
> +o <https://www.kernel.org/pub/linux/utils/net/iproute2/>
>
> OProfile
> --------
> diff --git a/net/sched/Kconfig b/net/sched/Kconfig
> index a1a8e29..d17053d 100644
> --- a/net/sched/Kconfig
> +++ b/net/sched/Kconfig
> @@ -22,8 +22,9 @@ menuconfig NET_SCHED
> This code is considered to be experimental.
>
> To administer these schedulers, you'll need the user-level utilities
> - from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
> - That package also contains some documentation; for more, check out
> + from the package iproute2+tc at
> + <https://www.kernel.org/pub/linux/utils/net/iproute2/>. That package
> + also contains some documentation; for more, check out
> <http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2>.
>
> This Quality of Service (QoS) support will enable you to use
> @@ -336,7 +337,7 @@ config NET_SCH_PLUG
> of virtual machines by allowing the generated network output to be rolled
> back if needed.
>
> - For more information, please refer to http://wiki.xensource.com/xenwiki/Remus
> + For more information, please refer to <http://wiki.xenproject.org/wiki/Remus>
>
> Say Y here if you are using this kernel for Xen dom0 and
> want to protect Xen guests with Remus.
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
^ permalink raw reply
* Re: [patch net-next 3/6] net_sched: cls_bpf: remove faulty use of list_for_each_entry_rcu
From: Daniel Borkmann @ 2014-12-03 23:15 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: Jiri Pirko, netdev, davem
In-Reply-To: <547F7D6D.3000709@mojatatu.com>
On 12/03/2014 10:15 PM, Jamal Hadi Salim wrote:
...
> I am not an rcu officionado. So if the control path is doing a non-rcu
> get + rcu-del/change (update) then as long as the fastpath is (read)
> rcu locking we are fine and nothing will actually happen until the
> fastpath releases and rcu grace period ends, correct?
So if the control path does a list_del_rcu() and call_rcu() under
lock and iterates over list_for_each_entry{,safe}() [which we do
in cls_bpf_delete()], while the fast path [cls_bpf_classify()] uses
a rcu_read_{un,}lock() with *_rcu list iterator, that's fine then,
as it's still guaranteed to be deleted after the grace period. So
Jiri's change looks good to me.
Acked-by: Daniel Borkmann <dborkman@redhat.com>
^ permalink raw reply
* Re: [PATCH iproute2] ss: Use rtnl_dump_filter in handle_netlink_request
From: Stephen Hemminger @ 2014-12-03 23:07 UTC (permalink / raw)
To: Vadim Kochan; +Cc: netdev@vger.kernel.org
In-Reply-To: <CAMw6YJ+W0KCvGrfij990+BU2EsW6E4SEWJRsrRgk=vnq-okjzQ@mail.gmail.com>
On Thu, 4 Dec 2014 00:15:54 +0200
Vadim Kochan <vadim4j@gmail.com> wrote:
> I established some simple OpenVPN connection (at least by the logs and
> ss I see that peer is connected), but
> I dont get any errors with ss.
>
> So can you please provide some more info how did you tested this patch
> ? I am surprised that this is caused only
> by these changes ...
>
> On Wed, Dec 3, 2014 at 7:45 PM, <vadim4j@gmail.com> wrote:
> > On Wed, Dec 03, 2014 at 09:51:23AM -0800, Stephen Hemminger wrote:
> >> On Wed, 3 Dec 2014 19:20:10 +0200
> >> vadim4j@gmail.com wrote:
> >>
> >> > On Wed, Dec 03, 2014 at 09:21:29AM -0800, Stephen Hemminger wrote:
> >> > > On Tue, 2 Dec 2014 16:53:04 +0200
> >> > > Vadim Kochan <vadim4j@gmail.com> wrote:
> >> > >
> >> > > > Replaced handling netlink messages by rtnl_dump_filter
> >> > > > from lib/libnetlink.c, also:
> >> > > >
> >> > > > - removed unused dump_fp arg;
> >> > > > - added MAGIC_SEQ #define for 123456 seq id
> >> > > >
> >> > > > Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> >> > >
> >> > > This doesn't work correctly.
> >> > >
> >> > > Simple test
> >> > > $ misc/ss >/dev/null
> >> > > RTNETLINK answers: No such file or directory
> >> > > RTNETLINK answers: No such file or directory
> >> > > RTNETLINK answers: No such file or directory
> >> >
> >> > Just tried, I did not get such errors.
> >>
> >> I have OpenVPN running.
> >
> > Hm, it is reproduced only with this patch ?
> > If so I will try to setup OpenVPN ... can't imagine how it can be
> > related ...
I am running on 3.17.4 kernel if that helps.
^ permalink raw reply
* Re: [PATCH net] gso: do GSO for local skb with size bigger than MTU
From: Thomas Graf @ 2014-12-03 23:05 UTC (permalink / raw)
To: Jesse Gross
Cc: Michael S. Tsirkin, Du, Fan, Jason Wang, netdev@vger.kernel.org,
davem@davemloft.net, fw@strlen.de, dev@openvswitch.org,
Pravin Shelar
In-Reply-To: <CAEP_g=90nC2HhmBNKh-hKJ5MJ85Z-_ER14roDxMsZAKog+dFhw@mail.gmail.com>
On 12/03/14 at 02:51pm, Jesse Gross wrote:
> My proposal would be something like this:
> * For L2, reduce the VM MTU to the lowest common denominator on the segment.
> * For L3, use path MTU discovery or fragment inner packet (i.e.
> normal routing behavior).
> * As a last resort (such as if using an old version of virtio in the
> guest), fragment the tunnel packet.
That's what I had in mind as well although using a differentiator bit
which indicates to the output path whether the packet is to be
considered switched or routed and thus send ICMPs. The bit would be set
per flow, thus allowing arbitary granularity of behaviour.
I haven't fully thought this through yet though.
^ permalink raw reply
* Re: [PATCH net] gso: do GSO for local skb with size bigger than MTU
From: Jesse Gross @ 2014-12-03 22:51 UTC (permalink / raw)
To: Thomas Graf
Cc: Michael S. Tsirkin, Du, Fan, Jason Wang, netdev@vger.kernel.org,
davem@davemloft.net, fw@strlen.de, dev@openvswitch.org,
Pravin Shelar
In-Reply-To: <20141203220244.GA8822@casper.infradead.org>
On Wed, Dec 3, 2014 at 2:02 PM, Thomas Graf <tgraf@suug.ch> wrote:
> On 12/03/14 at 11:38am, Jesse Gross wrote:
>> On Wed, Dec 3, 2014 at 10:38 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> > Both approaches seem strange. You are sending 1 packet an hour to
>> > some destination behind 100 tunnels. Why would you want to
>> > cut down your MTU for all packets? On the other hand,
>> > doubling the amount of packets because your MTU is off
>> > by a couple of bytes will hurt performance significantly.
>> >
>> > Still, if you want to cut down the MTU within guest,
>> > that's only an ifconfig away.
>> > Most people would not want to bother, I think it's a good
>> > idea to make PMTU work properly for them.
>>
>> I care about correctness first, which means that an Ethernet link
>> being exposed to the guest should behave like Ethernet. So, yes, IPX
>> should work if somebody chooses to do that.
>>
>> Your comments are about performance optimization. That's fine but
>> without a correct base to start from it seems like putting the cart
>> before the horse and is hard to reason about.
>
> I agree with Jesse in particular about correctnes but Michael has a
> point (which I thing nobod objects to) which is that it may not always
> make sense to force the MTU onto the guest. It clearly makes sense for
> the edge server connected to an overlay but it may not be ideal if
> WAN traffic is VXLAN encapped and local DC traffic is put onto a VLAN.
The question is whether you would do this in a single L2 segment. It's
possible, of course, but probably not a great idea and I'm not sure
that it's really worth optimizing for. We do have one existing example
of this type of MTU reduction - the bridge device when you attach
multiple devices with varying MTUs (including a VXLAN device). In that
case, the bridge device is effectively acting as a connection point,
similar to virtio in a VM.
My proposal would be something like this:
* For L2, reduce the VM MTU to the lowest common denominator on the segment.
* For L3, use path MTU discovery or fragment inner packet (i.e.
normal routing behavior).
* As a last resort (such as if using an old version of virtio in the
guest), fragment the tunnel packet.
^ permalink raw reply
* Re: [PATCH net] gso: do GSO for local skb with size bigger than MTU
From: Michael S. Tsirkin @ 2014-12-03 22:50 UTC (permalink / raw)
To: Thomas Graf
Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Jason Wang,
Du, Fan, fw-HFFVJYpyMKqzQB+pC5nmwQ@public.gmane.org,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org
In-Reply-To: <20141203220244.GA8822-FZi0V3Vbi30CUdFEqe4BF2D2FQJk+8+b@public.gmane.org>
On Wed, Dec 03, 2014 at 10:02:44PM +0000, Thomas Graf wrote:
> On 12/03/14 at 11:38am, Jesse Gross wrote:
> > On Wed, Dec 3, 2014 at 10:38 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > > Both approaches seem strange. You are sending 1 packet an hour to
> > > some destination behind 100 tunnels. Why would you want to
> > > cut down your MTU for all packets? On the other hand,
> > > doubling the amount of packets because your MTU is off
> > > by a couple of bytes will hurt performance significantly.
> > >
> > > Still, if you want to cut down the MTU within guest,
> > > that's only an ifconfig away.
> > > Most people would not want to bother, I think it's a good
> > > idea to make PMTU work properly for them.
> >
> > I care about correctness first, which means that an Ethernet link
> > being exposed to the guest should behave like Ethernet. So, yes, IPX
> > should work if somebody chooses to do that.
> >
> > Your comments are about performance optimization. That's fine but
> > without a correct base to start from it seems like putting the cart
> > before the horse and is hard to reason about.
>
> I agree with Jesse in particular about correctnes but Michael has a
> point (which I thing nobod objects to) which is that it may not always
> make sense to force the MTU onto the guest. It clearly makes sense for
> the edge server connected to an overlay but it may not be ideal if
> WAN traffic is VXLAN encapped and local DC traffic is put onto a VLAN.
And it's not like tweaking local MTU for one interface will
magically fix everything.
> That said, I think it is fair to assume that the host knows what role
> it plays and can be configured accordingly, i.e. a Netlink API which
> exposes the encap overhead so libvirt can max() over it force it onto
> the guest or something along those lines.
I'd say let's try to at least fix IP traffic properly.
--
MST
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* Re: [PATCH net-next v4] rtnetlink: delay RTM_DELLINK notification until after ndo_uninit()
From: Thomas Graf @ 2014-12-03 22:25 UTC (permalink / raw)
To: Mahesh Bandewar
Cc: netdev, David Miller, Eric Dumazet, Roopa Prabhu, Toshiaki Makita
In-Reply-To: <1417643184-23440-1-git-send-email-maheshb@google.com>
On 12/03/14 at 01:46pm, Mahesh Bandewar wrote:
> The commit 56bfa7ee7c ("unregister_netdevice : move RTM_DELLINK to
> until after ndo_uninit") tried to do this ealier but while doing so
> it created a problem. Unfortunately the delayed rtmsg_ifinfo() also
> delayed call to fill_info(). So this translated into asking driver
> to remove private state and then query it's private state. This
> could have catastropic consequences.
>
[...]
>
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
> Reported-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> Cc: Eric Dumazet <edumazet@google.com>
> Cc: Roopa Prabhu <roopa@cumulusnetworks.com>
> Cc: David S. Miller <davem@davemloft.net>
LGTM, thanks!
Acked-by: Thomas Graf <tgraf@suug.ch>
^ permalink raw reply
* Re: [PATCH iproute2] ss: Use rtnl_dump_filter in handle_netlink_request
From: Vadim Kochan @ 2014-12-03 22:15 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
In-Reply-To: <20141203174506.GA12511@angus-think.wlc.globallogic.com>
I established some simple OpenVPN connection (at least by the logs and
ss I see that peer is connected), but
I dont get any errors with ss.
So can you please provide some more info how did you tested this patch
? I am surprised that this is caused only
by these changes ...
On Wed, Dec 3, 2014 at 7:45 PM, <vadim4j@gmail.com> wrote:
> On Wed, Dec 03, 2014 at 09:51:23AM -0800, Stephen Hemminger wrote:
>> On Wed, 3 Dec 2014 19:20:10 +0200
>> vadim4j@gmail.com wrote:
>>
>> > On Wed, Dec 03, 2014 at 09:21:29AM -0800, Stephen Hemminger wrote:
>> > > On Tue, 2 Dec 2014 16:53:04 +0200
>> > > Vadim Kochan <vadim4j@gmail.com> wrote:
>> > >
>> > > > Replaced handling netlink messages by rtnl_dump_filter
>> > > > from lib/libnetlink.c, also:
>> > > >
>> > > > - removed unused dump_fp arg;
>> > > > - added MAGIC_SEQ #define for 123456 seq id
>> > > >
>> > > > Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
>> > >
>> > > This doesn't work correctly.
>> > >
>> > > Simple test
>> > > $ misc/ss >/dev/null
>> > > RTNETLINK answers: No such file or directory
>> > > RTNETLINK answers: No such file or directory
>> > > RTNETLINK answers: No such file or directory
>> >
>> > Just tried, I did not get such errors.
>>
>> I have OpenVPN running.
>
> Hm, it is reproduced only with this patch ?
> If so I will try to setup OpenVPN ... can't imagine how it can be
> related ...
^ permalink raw reply
* Re: [PATCH net-next v4] rtnetlink: delay RTM_DELLINK notification until after ndo_uninit()
From: Eric Dumazet @ 2014-12-03 22:07 UTC (permalink / raw)
To: Mahesh Bandewar
Cc: netdev, David Miller, Eric Dumazet, Roopa Prabhu, Toshiaki Makita
In-Reply-To: <1417643184-23440-1-git-send-email-maheshb@google.com>
On Wed, 2014-12-03 at 13:46 -0800, Mahesh Bandewar wrote:
> The commit 56bfa7ee7c ("unregister_netdevice : move RTM_DELLINK to
> until after ndo_uninit") tried to do this ealier but while doing so
> it created a problem. Unfortunately the delayed rtmsg_ifinfo() also
> delayed call to fill_info(). So this translated into asking driver
> to remove private state and then query it's private state. This
> could have catastropic consequences.
>
> This change breaks the rtmsg_ifinfo() into two parts - one takes the
> precise snapshot of the device by called fill_info() before calling
> the ndo_uninit() and the second part sends the notification using
> collected snapshot.
>
> It was brought to notice when last link is deleted from an ipvlan device
> when it has free-ed the port and the subsequent .fill_info() call is
> trying to get the info from the port.
> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
> Reported-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> Cc: Eric Dumazet <edumazet@google.com>
> Cc: Roopa Prabhu <roopa@cumulusnetworks.com>
> Cc: David S. Miller <davem@davemloft.net>
> ---
Acked-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* [PATCH net] Update old iproute2 and Xen Remus links
From: Andrew Shewmaker @ 2014-12-03 22:07 UTC (permalink / raw)
To: linux-doc; +Cc: linux-kernel, netdev, corbet, jhs, davem, Andrew Shewmaker
Signed-off-by: Andrew Shewmaker <agshew@gmail.com>
---
Documentation/Changes | 2 +-
net/sched/Kconfig | 7 ++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Documentation/Changes b/Documentation/Changes
index 1de131b..74bdda9 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -383,7 +383,7 @@ o <http://www.iptables.org/downloads.html>
Ip-route2
---------
-o <ftp://ftp.tux.org/pub/net/ip-routing/iproute2-2.2.4-now-ss991023.tar.gz>
+o <https://www.kernel.org/pub/linux/utils/net/iproute2/>
OProfile
--------
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index a1a8e29..d17053d 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -22,8 +22,9 @@ menuconfig NET_SCHED
This code is considered to be experimental.
To administer these schedulers, you'll need the user-level utilities
- from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
- That package also contains some documentation; for more, check out
+ from the package iproute2+tc at
+ <https://www.kernel.org/pub/linux/utils/net/iproute2/>. That package
+ also contains some documentation; for more, check out
<http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2>.
This Quality of Service (QoS) support will enable you to use
@@ -336,7 +337,7 @@ config NET_SCH_PLUG
of virtual machines by allowing the generated network output to be rolled
back if needed.
- For more information, please refer to http://wiki.xensource.com/xenwiki/Remus
+ For more information, please refer to <http://wiki.xenproject.org/wiki/Remus>
Say Y here if you are using this kernel for Xen dom0 and
want to protect Xen guests with Remus.
--
2.1.0
^ permalink raw reply related
* Re: [PATCH net] gso: do GSO for local skb with size bigger than MTU
From: Thomas Graf @ 2014-12-03 22:02 UTC (permalink / raw)
To: Jesse Gross
Cc: Michael S. Tsirkin, Du, Fan, Jason Wang, netdev@vger.kernel.org,
davem@davemloft.net, fw@strlen.de, dev@openvswitch.org,
Pravin Shelar
In-Reply-To: <CAEP_g=_Y2YQg0wDRJLXsNH6p3fOc5G0KSJb12x_b4OE238ophg@mail.gmail.com>
On 12/03/14 at 11:38am, Jesse Gross wrote:
> On Wed, Dec 3, 2014 at 10:38 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > Both approaches seem strange. You are sending 1 packet an hour to
> > some destination behind 100 tunnels. Why would you want to
> > cut down your MTU for all packets? On the other hand,
> > doubling the amount of packets because your MTU is off
> > by a couple of bytes will hurt performance significantly.
> >
> > Still, if you want to cut down the MTU within guest,
> > that's only an ifconfig away.
> > Most people would not want to bother, I think it's a good
> > idea to make PMTU work properly for them.
>
> I care about correctness first, which means that an Ethernet link
> being exposed to the guest should behave like Ethernet. So, yes, IPX
> should work if somebody chooses to do that.
>
> Your comments are about performance optimization. That's fine but
> without a correct base to start from it seems like putting the cart
> before the horse and is hard to reason about.
I agree with Jesse in particular about correctnes but Michael has a
point (which I thing nobod objects to) which is that it may not always
make sense to force the MTU onto the guest. It clearly makes sense for
the edge server connected to an overlay but it may not be ideal if
WAN traffic is VXLAN encapped and local DC traffic is put onto a VLAN.
That said, I think it is fair to assume that the host knows what role
it plays and can be configured accordingly, i.e. a Netlink API which
exposes the encap overhead so libvirt can max() over it force it onto
the guest or something along those lines.
^ permalink raw reply
* Re: [PATCH] Documentation: bindings: net: DPAA corenet binding document
From: Scott Wood @ 2014-12-03 22:01 UTC (permalink / raw)
To: Bucur Madalin-Cristian-B32716
Cc: devicetree@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
netdev@vger.kernel.org, Medve Emilian-EMMEDVE1,
Liberman Igal-B31950, galak@codeaurora.org, Shaohui Xie
In-Reply-To: <1417561420.15957.221.camel@freescale.com>
On Tue, 2014-12-02 at 17:03 -0600, Scott Wood wrote:
> On Tue, 2014-12-02 at 06:12 -0600, Bucur Madalin-Cristian-B32716 wrote:
> > > -----Original Message-----
> > > From: Wood Scott-B07421
> > > Sent: Tuesday, December 02, 2014 6:40 AM
> > >
> > > No need for the <SoC> part. As we previously discussed, the only
> > > purpose of this node is backwards compatibility with the U-Boot MAC
> > > address fixup -- if U-Boot doesn't look for the <SoC> version, then
> > > don't complicate things.
> > >
> > > Though, I can't find where U-Boot references this node. Are you sure
> > > it's not using the ethernet%d aliases like everything else, in which
> > > case why do we need this node at all?
> > >
> > > -Scott
> > >
> >
> > The initial (Freescale SDK) binding document contained those compatibles,
> > not sure what the initial intent was for the <SoC> variants.
> >
> > The "fsl,dpaa" node is of interest to the DPAA Ethernet because it is
> > the parent of the "fsl,dpa-ethernet" nodes.
>
> I'm not interested in what the SDK binding says, or what the SDK kernel
> does. I'm interested in whether there's a U-Boot compatibility issue,
> as was previously alleged. If there isn't, then there's no need for
> fsl,dpaa *or* fsl,dpa-ethernet.
OK, I found the U-Boot fixup in question. It's not for MAC addresses,
but for marking disabled ports as disabled. It marks the dpa-ethernet
node as disabled, based on it having an fsl,fman-mac property that
points to the MAC node.
U-Boot also disables the MAC node itself, so it doesn't matter if it
doesn't find fsl,fman-mac -- except for the special case of fm1-dtsec1,
which is always kept enabled because it's used for MDIO for all ports.
Based on http://patchwork.ozlabs.org/patch/410770/ there's a separate
node for mdio, so why can't we mark the MAC disabled? Assuming that
there's no real problem in marking the fm1-dtsec1 MAC node disabled, we
can consider this to be a bug in U-Boot which can be worked around by
having the fm1-dtsec1 mac node have an fsl,fman-mac property that points
to itself. This property would only go on the fm1-dtsec1 mac node and
would only be in device trees for SoCs that are supported by U-Boots old
enough to not have had the bug be fixed.
-Scott
^ permalink raw reply
* [PATCH net-next v4] rtnetlink: delay RTM_DELLINK notification until after ndo_uninit()
From: Mahesh Bandewar @ 2014-12-03 21:46 UTC (permalink / raw)
To: netdev
Cc: David Miller, Eric Dumazet, Roopa Prabhu, Toshiaki Makita,
Mahesh Bandewar
The commit 56bfa7ee7c ("unregister_netdevice : move RTM_DELLINK to
until after ndo_uninit") tried to do this ealier but while doing so
it created a problem. Unfortunately the delayed rtmsg_ifinfo() also
delayed call to fill_info(). So this translated into asking driver
to remove private state and then query it's private state. This
could have catastropic consequences.
This change breaks the rtmsg_ifinfo() into two parts - one takes the
precise snapshot of the device by called fill_info() before calling
the ndo_uninit() and the second part sends the notification using
collected snapshot.
It was brought to notice when last link is deleted from an ipvlan device
when it has free-ed the port and the subsequent .fill_info() call is
trying to get the info from the port.
kernel: [ 255.139429] ------------[ cut here ]------------
kernel: [ 255.139439] WARNING: CPU: 12 PID: 11173 at net/core/rtnetlink.c:2238 rtmsg_ifinfo+0x100/0x110()
kernel: [ 255.139493] Modules linked in: ipvlan bonding w1_therm ds2482 wire cdc_acm ehci_pci ehci_hcd i2c_dev i2c_i801 i2c_core msr cpuid bnx2x ptp pps_core mdio libcrc32c
kernel: [ 255.139513] CPU: 12 PID: 11173 Comm: ip Not tainted 3.18.0-smp-DEV #167
kernel: [ 255.139514] Hardware name: Intel RML,PCH/Ibis_QC_18, BIOS 1.0.10 05/15/2012
kernel: [ 255.139515] 0000000000000009 ffff880851b6b828 ffffffff815d87f4 00000000000000e0
kernel: [ 255.139516] 0000000000000000 ffff880851b6b868 ffffffff8109c29c 0000000000000000
kernel: [ 255.139518] 00000000ffffffa6 00000000000000d0 ffffffff81aaf580 0000000000000011
kernel: [ 255.139520] Call Trace:
kernel: [ 255.139527] [<ffffffff815d87f4>] dump_stack+0x46/0x58
kernel: [ 255.139531] [<ffffffff8109c29c>] warn_slowpath_common+0x8c/0xc0
kernel: [ 255.139540] [<ffffffff8109c2ea>] warn_slowpath_null+0x1a/0x20
kernel: [ 255.139544] [<ffffffff8150d570>] rtmsg_ifinfo+0x100/0x110
kernel: [ 255.139547] [<ffffffff814f78b5>] rollback_registered_many+0x1d5/0x2d0
kernel: [ 255.139549] [<ffffffff814f79cf>] unregister_netdevice_many+0x1f/0xb0
kernel: [ 255.139551] [<ffffffff8150acab>] rtnl_dellink+0xbb/0x110
kernel: [ 255.139553] [<ffffffff8150da90>] rtnetlink_rcv_msg+0xa0/0x240
kernel: [ 255.139557] [<ffffffff81329283>] ? rhashtable_lookup_compare+0x43/0x80
kernel: [ 255.139558] [<ffffffff8150d9f0>] ? __rtnl_unlock+0x20/0x20
kernel: [ 255.139562] [<ffffffff8152cb11>] netlink_rcv_skb+0xb1/0xc0
kernel: [ 255.139563] [<ffffffff8150a495>] rtnetlink_rcv+0x25/0x40
kernel: [ 255.139565] [<ffffffff8152c398>] netlink_unicast+0x178/0x230
kernel: [ 255.139567] [<ffffffff8152c75f>] netlink_sendmsg+0x30f/0x420
kernel: [ 255.139571] [<ffffffff814e0b0c>] sock_sendmsg+0x9c/0xd0
kernel: [ 255.139575] [<ffffffff811d1d7f>] ? rw_copy_check_uvector+0x6f/0x130
kernel: [ 255.139577] [<ffffffff814e11c9>] ? copy_msghdr_from_user+0x139/0x1b0
kernel: [ 255.139578] [<ffffffff814e1774>] ___sys_sendmsg+0x304/0x310
kernel: [ 255.139581] [<ffffffff81198723>] ? handle_mm_fault+0xca3/0xde0
kernel: [ 255.139585] [<ffffffff811ebc4c>] ? destroy_inode+0x3c/0x70
kernel: [ 255.139589] [<ffffffff8108e6ec>] ? __do_page_fault+0x20c/0x500
kernel: [ 255.139597] [<ffffffff811e8336>] ? dput+0xb6/0x190
kernel: [ 255.139606] [<ffffffff811f05f6>] ? mntput+0x26/0x40
kernel: [ 255.139611] [<ffffffff811d2b94>] ? __fput+0x174/0x1e0
kernel: [ 255.139613] [<ffffffff814e2129>] __sys_sendmsg+0x49/0x90
kernel: [ 255.139615] [<ffffffff814e2182>] SyS_sendmsg+0x12/0x20
kernel: [ 255.139617] [<ffffffff815df092>] system_call_fastpath+0x12/0x17
kernel: [ 255.139619] ---[ end trace 5e6703e87d984f6b ]---
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Reported-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Roopa Prabhu <roopa@cumulusnetworks.com>
Cc: David S. Miller <davem@davemloft.net>
---
v1:
Initial version
v2:
Keep the rtmsg_ifinfo() return type as it is but break the function into
two minimizing the changes all over places
v3:
Corrected an error in the code.
v4:
Removed EXPORT_SYMBOL() for both the new functions.
include/linux/rtnetlink.h | 5 +++++
net/core/dev.c | 12 +++++++++---
net/core/rtnetlink.c | 25 +++++++++++++++++++++----
3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 3b0419072f88..5db76a32fcab 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -17,6 +17,11 @@ extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
u32 id, long expires, u32 error);
void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change, gfp_t flags);
+struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
+ unsigned change, gfp_t flags);
+void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev,
+ gfp_t flags);
+
/* RTNL is used as a global lock for all changes to network configuration */
extern void rtnl_lock(void);
diff --git a/net/core/dev.c b/net/core/dev.c
index 0814a560e5f3..dd3bf582e6f0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5925,6 +5925,8 @@ static void rollback_registered_many(struct list_head *head)
synchronize_net();
list_for_each_entry(dev, head, unreg_list) {
+ struct sk_buff *skb = NULL;
+
/* Shutdown queueing discipline. */
dev_shutdown(dev);
@@ -5934,6 +5936,11 @@ static void rollback_registered_many(struct list_head *head)
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
+ if (!dev->rtnl_link_ops ||
+ dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
+ skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U,
+ GFP_KERNEL);
+
/*
* Flush the unicast and multicast chains
*/
@@ -5943,9 +5950,8 @@ static void rollback_registered_many(struct list_head *head)
if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev);
- if (!dev->rtnl_link_ops ||
- dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
- rtmsg_ifinfo(RTM_DELLINK, dev, ~0U, GFP_KERNEL);
+ if (skb)
+ rtmsg_ifinfo_send(skb, dev, GFP_KERNEL);
/* Notifier chain MUST detach us all upper devices. */
WARN_ON(netdev_has_any_upper_dev(dev));
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 61cb7e7cc3c7..a9be2c161702 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2245,8 +2245,8 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
-void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
- gfp_t flags)
+struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
+ unsigned int change, gfp_t flags)
{
struct net *net = dev_net(dev);
struct sk_buff *skb;
@@ -2264,11 +2264,28 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags);
- return;
+ return skb;
errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+ return NULL;
+}
+
+void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags)
+{
+ struct net *net = dev_net(dev);
+
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags);
+}
+
+void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
+ gfp_t flags)
+{
+ struct sk_buff *skb;
+
+ skb = rtmsg_ifinfo_build_skb(type, dev, change, flags);
+ if (skb)
+ rtmsg_ifinfo_send(skb, dev, flags);
}
EXPORT_SYMBOL(rtmsg_ifinfo);
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related
* Re: [PATCHv11 net-next 1/2] openvswitch: Refactor ovs_nla_fill_match().
From: Joe Stringer @ 2014-12-03 21:42 UTC (permalink / raw)
To: Pravin Shelar; +Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org, netdev, LKML
In-Reply-To: <CALnjE+pNbwtGPsHfTJ0FXxdSpXT=AKgtfHPqT5matCx+PGcXbA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 3 December 2014 at 11:37, Pravin Shelar <pshelar@nicira.com> wrote:
> On Tue, Dec 2, 2014 at 6:56 PM, Joe Stringer <joestringer@nicira.com> wrote:
>> diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
>> index 332b5a0..b2a3796 100644
>> --- a/net/openvswitch/datapath.c
>> +++ b/net/openvswitch/datapath.c
>> @@ -462,10 +462,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
>> 0, upcall_info->cmd);
>> upcall->dp_ifindex = dp_ifindex;
>>
>> - nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
>> - err = ovs_nla_put_flow(key, key, user_skb);
>> + err = ovs_nla_put_flow(key, key, OVS_PACKET_ATTR_KEY, false, user_skb);
>
> We need different name here, since it does not operate on flow. maybe
> __ovs_nla_put_key(). we can move the function definition to
> flow_netlink.h
OK sure. I'll fix this up for the next version.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* Re: [PATCH net-next] net: bcmgenet: add support for Rx priority queues
From: Petri Gynther @ 2014-12-03 21:31 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev, David Miller
In-Reply-To: <547E3192.4080400@gmail.com>
Hi Florian,
On Tue, Dec 2, 2014 at 1:39 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 02/12/14 13:00, Petri Gynther wrote:
>> bcmgenet hardware supports 16 Rx priority queues + 1 Rx default queue.
>> Currently, the driver only supports the Rx default queue.
>> Add support for the Rx priority queues.
>
> You are doing many things in one patch here, I see at least 3 separate
> commits:
>
> - move TX completion to NAPI
> - introduce a RX ring change that just applies to RX ring 16
> - introduce support for RX rings 0 through 15
>
> Eventually a 4th one which caches the reads and writes to the INTRL2_0
> registers and uses int0_mask, which BTW, I had problems with on GENETv4,
> hence the reason why it is not currently adopted.
>
I'll break this patch into smaller pieces.
> Have you tried the following NAPI/queue partitioning:
>
> - one NAPI context per TX queue, except ring 16
> - one NAPI context per RX queue, except ring 16
> - one shared NAPI context for RX & TX queue 16 (today's scheme)
>
Since my initial goal was to get one Rx priority queue working
together with the Rx default queue, I just added one new NAPI context
for the priority queue Rx/Tx processing.
> The changes are looking good, but since there are many things that
> change, it is harder to review, which is why I would prefer separate
> individual patches.
>
> Thanks!
>
>>
>> Signed-off-by: Petri Gynther <pgynther@google.com>
>> ---
>> drivers/net/ethernet/broadcom/genet/bcmgenet.c | 432 +++++++++++++++----------
>> drivers/net/ethernet/broadcom/genet/bcmgenet.h | 27 +-
>> 2 files changed, 289 insertions(+), 170 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> index f2fadb0..aced105 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> @@ -53,8 +53,10 @@
>> /* Default highest priority queue for multi queue support */
>> #define GENET_Q0_PRIORITY 0
>>
>> -#define GENET_DEFAULT_BD_CNT \
>> - (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->bds_cnt)
>> +#define GENET_Q16_RX_BD_CNT \
>> + (TOTAL_DESC - priv->hw_params->rx_queues * priv->hw_params->rx_bds_cnt)
>> +#define GENET_Q16_TX_BD_CNT \
>> + (TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_cnt)
>>
>> #define RX_BUF_LENGTH 2048
>> #define SKB_ALIGNMENT 32
>> @@ -1313,7 +1315,8 @@ out:
>> }
>>
>>
>> -static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb)
>> +static int bcmgenet_rx_refill(struct bcmgenet_priv *priv,
>> + struct bcmgenet_rx_ring *ring, struct enet_cb *cb)
>> {
>> struct device *kdev = &priv->pdev->dev;
>> struct sk_buff *skb;
>> @@ -1341,14 +1344,16 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb)
>> dma_unmap_addr_set(cb, dma_addr, mapping);
>> /* assign packet, prepare descriptor, and advance pointer */
>>
>> - dmadesc_set_addr(priv, priv->rx_bd_assign_ptr, mapping);
>> + dmadesc_set_addr(priv, ring->bd_assign_ptr, mapping);
>>
>> /* turn on the newly assigned BD for DMA to use */
>> - priv->rx_bd_assign_index++;
>> - priv->rx_bd_assign_index &= (priv->num_rx_bds - 1);
>> + if (likely(ring->bd_assign_idx < ring->end_ptr))
>> + ring->bd_assign_idx++;
>> + else
>> + ring->bd_assign_idx = ring->cb_ptr;
>>
>> - priv->rx_bd_assign_ptr = priv->rx_bds +
>> - (priv->rx_bd_assign_index * DMA_DESC_SIZE);
>> + ring->bd_assign_ptr = priv->rx_bds +
>> + (ring->bd_assign_idx * DMA_DESC_SIZE);
>>
>> return 0;
>> }
>> @@ -1357,8 +1362,10 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb)
>> * this could be called from bottom half, or from NAPI polling method.
>> */
>> static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
>> - unsigned int budget)
>> + unsigned int index,
>> + struct napi_struct *napi, int budget)
>> {
>> + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index];
>> struct net_device *dev = priv->dev;
>> struct enet_cb *cb;
>> struct sk_buff *skb;
>> @@ -1369,21 +1376,21 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
>> unsigned int p_index;
>> unsigned int chksum_ok = 0;
>>
>> - p_index = bcmgenet_rdma_ring_readl(priv, DESC_INDEX, RDMA_PROD_INDEX);
>> + p_index = bcmgenet_rdma_ring_readl(priv, index, RDMA_PROD_INDEX);
>> p_index &= DMA_P_INDEX_MASK;
>>
>> - if (p_index < priv->rx_c_index)
>> - rxpkttoprocess = (DMA_C_INDEX_MASK + 1) -
>> - priv->rx_c_index + p_index;
>> + if (likely(p_index >= ring->c_index))
>> + rxpkttoprocess = p_index - ring->c_index;
>> else
>> - rxpkttoprocess = p_index - priv->rx_c_index;
>> + rxpkttoprocess = (DMA_C_INDEX_MASK + 1) -
>> + ring->c_index + p_index;
>>
>> netif_dbg(priv, rx_status, dev,
>> "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess);
>>
>> while ((rxpktprocessed < rxpkttoprocess) &&
>> (rxpktprocessed < budget)) {
>> - cb = &priv->rx_cbs[priv->rx_read_ptr];
>> + cb = &priv->rx_cbs[ring->read_ptr];
>> skb = cb->skb;
>>
>> /* We do not have a backing SKB, so we do not have a
>> @@ -1408,7 +1415,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
>> dma_length_status =
>> dmadesc_get_length_status(priv,
>> priv->rx_bds +
>> - (priv->rx_read_ptr *
>> + (ring->read_ptr *
>> DMA_DESC_SIZE));
>> } else {
>> struct status_64 *status;
>> @@ -1425,8 +1432,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
>>
>> netif_dbg(priv, rx_status, dev,
>> "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n",
>> - __func__, p_index, priv->rx_c_index,
>> - priv->rx_read_ptr, dma_length_status);
>> + __func__, p_index, ring->c_index,
>> + ring->read_ptr, dma_length_status);
>>
>> if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
>> netif_err(priv, rx_status, dev,
>> @@ -1491,28 +1498,34 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
>> dev->stats.multicast++;
>>
>> /* Notify kernel */
>> - napi_gro_receive(&priv->napi, skb);
>> + napi_gro_receive(napi, skb);
>> cb->skb = NULL;
>> netif_dbg(priv, rx_status, dev, "pushed up to kernel\n");
>>
>> /* refill RX path on the current control block */
>> refill:
>> - err = bcmgenet_rx_refill(priv, cb);
>> + err = bcmgenet_rx_refill(priv, ring, cb);
>> if (err) {
>> priv->mib.alloc_rx_buff_failed++;
>> netif_err(priv, rx_err, dev, "Rx refill failed\n");
>> }
>>
>> rxpktprocessed++;
>> - priv->rx_read_ptr++;
>> - priv->rx_read_ptr &= (priv->num_rx_bds - 1);
>> + if (likely(ring->read_ptr < ring->end_ptr))
>> + ring->read_ptr++;
>> + else
>> + ring->read_ptr = ring->cb_ptr;
>> +
>> + ring->c_index = (ring->c_index + 1) & DMA_C_INDEX_MASK;
>> + bcmgenet_rdma_ring_writel(priv, index, ring->c_index, RDMA_CONS_INDEX);
>> }
>>
>> return rxpktprocessed;
>> }
>>
>> /* Assign skb to RX DMA descriptor. */
>> -static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
>> +static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
>> + struct bcmgenet_rx_ring *ring)
>> {
>> struct enet_cb *cb;
>> int ret = 0;
>> @@ -1521,12 +1534,12 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
>> netif_dbg(priv, hw, priv->dev, "%s:\n", __func__);
>>
>> /* loop here for each buffer needing assign */
>> - for (i = 0; i < priv->num_rx_bds; i++) {
>> - cb = &priv->rx_cbs[priv->rx_bd_assign_index];
>> + for (i = 0; i < ring->size; i++) {
>> + cb = &priv->rx_cbs[ring->bd_assign_idx];
>> if (cb->skb)
>> - continue;
>> + bcmgenet_free_cb(cb);
>>
>> - ret = bcmgenet_rx_refill(priv, cb);
>> + ret = bcmgenet_rx_refill(priv, ring, cb);
>> if (ret)
>> break;
>> }
>> @@ -1607,9 +1620,11 @@ static int reset_umac(struct bcmgenet_priv *priv)
>> static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
>> {
>> /* Mask all interrupts.*/
>> + priv->int0_mask = 0xFFFFFFFF;
>> bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
>> bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
>> bcmgenet_intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
>> + priv->int1_mask = 0xFFFFFFFF;
>> bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
>> bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
>> bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
>> @@ -1619,7 +1634,8 @@ static int init_umac(struct bcmgenet_priv *priv)
>> {
>> struct device *kdev = &priv->pdev->dev;
>> int ret;
>> - u32 reg, cpu_mask_clear;
>> + u32 reg;
>> + u32 i;
>>
>> dev_dbg(&priv->pdev->dev, "bcmgenet: init_umac\n");
>>
>> @@ -1646,15 +1662,15 @@ static int init_umac(struct bcmgenet_priv *priv)
>>
>> bcmgenet_intr_disable(priv);
>>
>> - cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE;
>> -
>> - dev_dbg(kdev, "%s:Enabling RXDMA_BDONE interrupt\n", __func__);
>> + /* Enable Rx and Tx interrupts for the default queue 16 */
>> + priv->int0_mask &= ~(UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE |
>> + UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE);
>>
>> /* Monitor cable plug/unplugged event for internal PHY */
>> if (phy_is_internal(priv->phydev)) {
>> - cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
>> + priv->int0_mask &= ~(UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
>> } else if (priv->ext_phy) {
>> - cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
>> + priv->int0_mask &= ~(UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
>> } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
>> reg = bcmgenet_bp_mc_get(priv);
>> reg |= BIT(priv->hw_params->bp_in_en_shift);
>> @@ -1669,9 +1685,18 @@ static int init_umac(struct bcmgenet_priv *priv)
>>
>> /* Enable MDIO interrupts on GENET v3+ */
>> if (priv->hw_params->flags & GENET_HAS_MDIO_INTR)
>> - cpu_mask_clear |= UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR;
>> + priv->int0_mask &= ~(UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR);
>>
>> - bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR);
>> + /* Enable Tx priority queue interrupts */
>> + for (i = 0; i < priv->hw_params->tx_queues; i++)
>> + priv->int1_mask &= ~(1 << i);
>> +
>> + /* Enable Rx priority queue interrupts */
>> + for (i = 0; i < priv->hw_params->rx_queues; i++)
>> + priv->int1_mask &= ~(1 << (UMAC_IRQ1_RX_INTR_SHIFT + i));
>> +
>> + bcmgenet_intrl2_0_writel(priv, ~priv->int0_mask, INTRL2_CPU_MASK_CLEAR);
>> + bcmgenet_intrl2_1_writel(priv, ~priv->int1_mask, INTRL2_CPU_MASK_CLEAR);
>>
>> /* Enable rx/tx engine.*/
>> dev_dbg(kdev, "done init umac\n");
>> @@ -1684,12 +1709,11 @@ static int init_umac(struct bcmgenet_priv *priv)
>> */
>> static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
>> unsigned int index, unsigned int size,
>> - unsigned int write_ptr, unsigned int end_ptr)
>> + unsigned int start_ptr, unsigned int end_ptr)
>> {
>> struct bcmgenet_tx_ring *ring = &priv->tx_rings[index];
>> u32 words_per_bd = WORDS_PER_BD(priv);
>> u32 flow_period_val = 0;
>> - unsigned int first_bd;
>>
>> spin_lock_init(&ring->lock);
>> ring->index = index;
>> @@ -1702,12 +1726,12 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
>> ring->int_enable = bcmgenet_tx_ring_int_enable;
>> ring->int_disable = bcmgenet_tx_ring_int_disable;
>> }
>> - ring->cbs = priv->tx_cbs + write_ptr;
>> + ring->cbs = priv->tx_cbs + start_ptr;
>> ring->size = size;
>> ring->c_index = 0;
>> ring->free_bds = size;
>> - ring->write_ptr = write_ptr;
>> - ring->cb_ptr = write_ptr;
>> + ring->write_ptr = start_ptr;
>> + ring->cb_ptr = start_ptr;
>> ring->end_ptr = end_ptr - 1;
>> ring->prod_index = 0;
>>
>> @@ -1718,22 +1742,16 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
>> bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);
>> bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX);
>> bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
>> - /* Disable rate control for now */
>> bcmgenet_tdma_ring_writel(priv, index, flow_period_val,
>> TDMA_FLOW_PERIOD);
>> - /* Unclassified traffic goes to ring 16 */
>> bcmgenet_tdma_ring_writel(priv, index,
>> ((size << DMA_RING_SIZE_SHIFT) |
>> RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
>> -
>> - first_bd = write_ptr;
>> -
>> - /* Set start and end address, read and write pointers */
>> - bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
>> + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> DMA_START_ADDR);
>> - bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
>> + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> TDMA_READ_PTR);
>> - bcmgenet_tdma_ring_writel(priv, index, first_bd,
>> + bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> TDMA_WRITE_PTR);
>> bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1,
>> DMA_END_ADDR);
>> @@ -1741,42 +1759,44 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
>>
>> /* Initialize a RDMA ring */
>> static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
>> - unsigned int index, unsigned int size)
>> + unsigned int index, unsigned int size,
>> + unsigned int start_ptr, unsigned int end_ptr)
>> {
>> + struct bcmgenet_rx_ring *ring = &priv->rx_rings[index];
>> u32 words_per_bd = WORDS_PER_BD(priv);
>> int ret;
>>
>> - priv->num_rx_bds = TOTAL_DESC;
>> - priv->rx_bds = priv->base + priv->hw_params->rdma_offset;
>> - priv->rx_bd_assign_ptr = priv->rx_bds;
>> - priv->rx_bd_assign_index = 0;
>> - priv->rx_c_index = 0;
>> - priv->rx_read_ptr = 0;
>> - priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb),
>> - GFP_KERNEL);
>> - if (!priv->rx_cbs)
>> - return -ENOMEM;
>> + ring->index = index;
>> + ring->cbs = priv->rx_cbs + start_ptr;
>> + ring->size = size;
>> + ring->c_index = 0;
>> + ring->read_ptr = start_ptr;
>> + ring->cb_ptr = start_ptr;
>> + ring->end_ptr = end_ptr - 1;
>>
>> - ret = bcmgenet_alloc_rx_buffers(priv);
>> + ret = bcmgenet_alloc_rx_buffers(priv, ring);
>> if (ret) {
>> - kfree(priv->rx_cbs);
>> return ret;
>> }
>>
>> - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_WRITE_PTR);
>> bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX);
>> bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX);
>> + bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
>> bcmgenet_rdma_ring_writel(priv, index,
>> ((size << DMA_RING_SIZE_SHIFT) |
>> RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
>> - bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR);
>> - bcmgenet_rdma_ring_writel(priv, index,
>> - words_per_bd * size - 1, DMA_END_ADDR);
>> bcmgenet_rdma_ring_writel(priv, index,
>> (DMA_FC_THRESH_LO <<
>> DMA_XOFF_THRESHOLD_SHIFT) |
>> DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH);
>> - bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR);
>> + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> + DMA_START_ADDR);
>> + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> + RDMA_READ_PTR);
>> + bcmgenet_rdma_ring_writel(priv, index, start_ptr * words_per_bd,
>> + RDMA_WRITE_PTR);
>> + bcmgenet_rdma_ring_writel(priv, index, end_ptr * words_per_bd - 1,
>> + DMA_END_ADDR);
>>
>> return ret;
>> }
>> @@ -1784,75 +1804,113 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
>> /* init multi xmit queues, only available for GENET2+
>> * the queue is partitioned as follows:
>> *
>> - * queue 0 - 3 is priority based, each one has 32 descriptors,
>> + * queues 0-3 are priority based, each one has 32 descriptors,
>> * with queue 0 being the highest priority queue.
>> *
>> - * queue 16 is the default tx queue with GENET_DEFAULT_BD_CNT
>> + * queue 16 is the default tx queue with GENET_Q16_TX_BD_CNT
>> * descriptors: 256 - (number of tx queues * bds per queues) = 128
>> * descriptors.
>> *
>> * The transmit control block pool is then partitioned as following:
>> - * - tx_cbs[0...127] are for queue 16
>> - * - tx_ring_cbs[0] points to tx_cbs[128..159]
>> - * - tx_ring_cbs[1] points to tx_cbs[160..191]
>> - * - tx_ring_cbs[2] points to tx_cbs[192..223]
>> - * - tx_ring_cbs[3] points to tx_cbs[224..255]
>> + * - tx_ring_cbs[0] points to tx_cbs[0..31]
>> + * - tx_ring_cbs[1] points to tx_cbs[32..63]
>> + * - tx_ring_cbs[2] points to tx_cbs[64..95]
>> + * - tx_ring_cbs[3] points to tx_cbs[96..127]
>> + * - tx ring 16 uses tx_cbs[128..255]
>> */
>> -static void bcmgenet_init_multiq(struct net_device *dev)
>> +static void bcmgenet_init_tx_queues(struct net_device *dev)
>> {
>> struct bcmgenet_priv *priv = netdev_priv(dev);
>> unsigned int i, dma_enable;
>> - u32 reg, dma_ctrl, ring_cfg = 0;
>> + u32 dma_ctrl, ring_cfg;
>> u32 dma_priority[3] = {0, 0, 0};
>>
>> - if (!netif_is_multiqueue(dev)) {
>> - netdev_warn(dev, "called with non multi queue aware HW\n");
>> - return;
>> - }
>> -
>> dma_ctrl = bcmgenet_tdma_readl(priv, DMA_CTRL);
>> dma_enable = dma_ctrl & DMA_EN;
>> dma_ctrl &= ~DMA_EN;
>> bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL);
>>
>> + dma_ctrl = 0;
>> + ring_cfg = 0;
>> +
>> /* Enable strict priority arbiter mode */
>> bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL);
>>
>> + /* Initialize Tx priority queues */
>> for (i = 0; i < priv->hw_params->tx_queues; i++) {
>> - /* first 64 tx_cbs are reserved for default tx queue
>> - * (ring 16)
>> - */
>> - bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt,
>> - i * priv->hw_params->bds_cnt,
>> - (i + 1) * priv->hw_params->bds_cnt);
>> + bcmgenet_init_tx_ring(priv, i, priv->hw_params->tx_bds_cnt,
>> + i * priv->hw_params->tx_bds_cnt,
>> + (i + 1) * priv->hw_params->tx_bds_cnt);
>>
>> /* Configure ring as descriptor ring and setup priority */
>> - ring_cfg |= 1 << i;
>> - dma_ctrl |= 1 << (i + DMA_RING_BUF_EN_SHIFT);
>> + ring_cfg |= (1 << i);
>> + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
>>
>> dma_priority[DMA_PRIO_REG_INDEX(i)] |=
>> ((GENET_Q0_PRIORITY + i) << DMA_PRIO_REG_SHIFT(i));
>> }
>>
>> - /* Set ring 16 priority and program the hardware registers */
>> + /* Initialize Tx default queue 16 */
>> + bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_Q16_TX_BD_CNT,
>> + priv->hw_params->tx_queues *
>> + priv->hw_params->tx_bds_cnt, TOTAL_DESC);
>> + ring_cfg |= (1 << DESC_INDEX);
>> + dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
>> dma_priority[DMA_PRIO_REG_INDEX(DESC_INDEX)] |=
>> ((GENET_Q0_PRIORITY + priv->hw_params->tx_queues) <<
>> DMA_PRIO_REG_SHIFT(DESC_INDEX));
>> +
>> + /* Set Tx ring priorities */
>> bcmgenet_tdma_writel(priv, dma_priority[0], DMA_PRIORITY_0);
>> bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1);
>> bcmgenet_tdma_writel(priv, dma_priority[2], DMA_PRIORITY_2);
>>
>> /* Enable rings */
>> - reg = bcmgenet_tdma_readl(priv, DMA_RING_CFG);
>> - reg |= ring_cfg;
>> - bcmgenet_tdma_writel(priv, reg, DMA_RING_CFG);
>> + bcmgenet_tdma_writel(priv, ring_cfg, DMA_RING_CFG);
>>
>> /* Configure ring as descriptor ring and re-enable DMA if enabled */
>> - reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
>> - reg |= dma_ctrl;
>> if (dma_enable)
>> - reg |= DMA_EN;
>> - bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
>> + dma_ctrl |= DMA_EN;
>> + bcmgenet_tdma_writel(priv, dma_ctrl, DMA_CTRL);
>> +}
>> +
>> +static void bcmgenet_init_rx_queues(struct net_device *dev)
>> +{
>> + struct bcmgenet_priv *priv = netdev_priv(dev);
>> + unsigned int i, dma_enable;
>> + u32 dma_ctrl, ring_cfg;
>> +
>> + dma_ctrl = bcmgenet_rdma_readl(priv, DMA_CTRL);
>> + dma_enable = dma_ctrl & DMA_EN;
>> + dma_ctrl &= ~DMA_EN;
>> + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL);
>> +
>> + dma_ctrl = 0;
>> + ring_cfg = 0;
>> +
>> + /* Initialize Rx priority queues */
>> + for (i = 0; i < priv->hw_params->rx_queues; i++) {
>> + bcmgenet_init_rx_ring(priv, i, priv->hw_params->rx_bds_cnt,
>> + i * priv->hw_params->rx_bds_cnt,
>> + (i + 1) * priv->hw_params->rx_bds_cnt);
>> + ring_cfg |= (1 << i);
>> + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
>> + }
>> +
>> + /* Initialize Rx default queue 16 */
>> + bcmgenet_init_rx_ring(priv, DESC_INDEX, GENET_Q16_RX_BD_CNT,
>> + priv->hw_params->rx_queues *
>> + priv->hw_params->rx_bds_cnt, TOTAL_DESC);
>> + ring_cfg |= (1 << DESC_INDEX);
>> + dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
>> +
>> + /* Enable rings */
>> + bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG);
>> +
>> + /* Configure ring as descriptor ring and re-enable DMA if enabled */
>> + if (dma_enable)
>> + dma_ctrl |= DMA_EN;
>> + bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL);
>> }
>>
>> static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
>> @@ -1928,24 +1986,28 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
>> /* init_edma: Initialize DMA control register */
>> static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
>> {
>> - int ret;
>> + netif_dbg(priv, hw, priv->dev, "bcmgenet: init_dma\n");
>>
>> - netif_dbg(priv, hw, priv->dev, "bcmgenet: init_edma\n");
>> + /* init rDma */
>> + bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE);
>>
>> - /* by default, enable ring 16 (descriptor based) */
>> - ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, TOTAL_DESC);
>> - if (ret) {
>> - netdev_err(priv->dev, "failed to initialize RX ring\n");
>> - return ret;
>> + /* init common Rx ring structures */
>> + priv->rx_bds = priv->base + priv->hw_params->rdma_offset;
>> + priv->num_rx_bds = TOTAL_DESC;
>> + priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb),
>> + GFP_KERNEL);
>> + if (!priv->rx_cbs) {
>> + bcmgenet_fini_dma(priv);
>> + return -ENOMEM;
>> }
>>
>> - /* init rDma */
>> - bcmgenet_rdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE);
>> + /* init Rx queues */
>> + bcmgenet_init_rx_queues(priv->dev);
>>
>> - /* Init tDma */
>> + /* init tDma */
>> bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE);
>>
>> - /* Initialize common TX ring structures */
>> + /* init common Tx ring structures */
>> priv->tx_bds = priv->base + priv->hw_params->tdma_offset;
>> priv->num_tx_bds = TOTAL_DESC;
>> priv->tx_cbs = kcalloc(priv->num_tx_bds, sizeof(struct enet_cb),
>> @@ -1955,38 +2017,75 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
>> return -ENOMEM;
>> }
>>
>> - /* initialize multi xmit queue */
>> - bcmgenet_init_multiq(priv->dev);
>> -
>> - /* initialize special ring 16 */
>> - bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT,
>> - priv->hw_params->tx_queues *
>> - priv->hw_params->bds_cnt,
>> - TOTAL_DESC);
>> + /* init Tx queues */
>> + bcmgenet_init_tx_queues(priv->dev);
>>
>> return 0;
>> }
>>
>> -/* NAPI polling method*/
>> +/* NAPI polling method for Rx and Tx default queues */
>> static int bcmgenet_poll(struct napi_struct *napi, int budget)
>> {
>> - struct bcmgenet_priv *priv = container_of(napi,
>> - struct bcmgenet_priv, napi);
>> - unsigned int work_done;
>> + struct bcmgenet_priv *priv =
>> + container_of(napi, struct bcmgenet_priv, napi);
>> + int work_done = 0;
>>
>> - /* tx reclaim */
>> + /* Tx default queue processing */
>> bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]);
>>
>> - work_done = bcmgenet_desc_rx(priv, budget);
>> + /* Rx default queue processing */
>> + work_done += bcmgenet_desc_rx(priv, DESC_INDEX, napi, budget);
>> +
>> + if (work_done < budget) {
>> + napi_complete(napi);
>> + bcmgenet_intrl2_0_writel(priv,
>> + UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE |
>> + UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
>> + INTRL2_CPU_MASK_CLEAR);
>> + }
>> +
>> + return work_done;
>> +}
>> +
>> +/* NAPI polling method for Rx and Tx priority queues */
>> +static int bcmgenet_poll_priority(struct napi_struct *napi, int budget)
>> +{
>> + struct bcmgenet_priv *priv =
>> + container_of(napi, struct bcmgenet_priv, napi_priority);
>> + int work_done = 0;
>> + unsigned int index;
>> + unsigned int active_rings;
>> +
>> + priv->irq1_stat |= (bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
>> + ~priv->int1_mask);
>> +
>> + /* Tx priority queue processing */
>> + index = 0;
>> + active_rings = priv->irq1_stat & UMAC_IRQ1_TX_INTR_MASK;
>> + while (active_rings) {
>> + if (active_rings & 0x1)
>> + bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[index]);
>> + active_rings >>= 1;
>> + index++;
>> + }
>> +
>> + /* Rx priority queue processing */
>> + index = 0;
>> + active_rings = (priv->irq1_stat >> UMAC_IRQ1_RX_INTR_SHIFT) &
>> + UMAC_IRQ1_RX_INTR_MASK;
>> + while (active_rings && work_done < budget) {
>> + if (active_rings & 0x1)
>> + work_done += bcmgenet_desc_rx(priv, index, napi,
>> + budget - work_done);
>> + active_rings >>= 1;
>> + index++;
>> + }
>> +
>> + priv->irq1_stat = 0;
>>
>> - /* Advancing our consumer index*/
>> - priv->rx_c_index += work_done;
>> - priv->rx_c_index &= DMA_C_INDEX_MASK;
>> - bcmgenet_rdma_ring_writel(priv, DESC_INDEX,
>> - priv->rx_c_index, RDMA_CONS_INDEX);
>> if (work_done < budget) {
>> napi_complete(napi);
>> - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE,
>> + bcmgenet_intrl2_1_writel(priv, ~priv->int1_mask,
>> INTRL2_CPU_MASK_CLEAR);
>> }
>>
>> @@ -2017,36 +2116,34 @@ static void bcmgenet_irq_task(struct work_struct *work)
>> }
>> }
>>
>> -/* bcmgenet_isr1: interrupt handler for ring buffer. */
>> +/* bcmgenet_isr1: handle Rx and Tx priority queues */
>> static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
>> {
>> struct bcmgenet_priv *priv = dev_id;
>> - unsigned int index;
>>
>> /* Save irq status for bottom-half processing. */
>> priv->irq1_stat =
>> bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
>> ~priv->int1_mask;
>> +
>> /* clear interrupts */
>> bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR);
>>
>> netif_dbg(priv, intr, priv->dev,
>> "%s: IRQ=0x%x\n", __func__, priv->irq1_stat);
>> - /* Check the MBDONE interrupts.
>> - * packet is done, reclaim descriptors
>> - */
>> - if (priv->irq1_stat & 0x0000ffff) {
>> - index = 0;
>> - for (index = 0; index < 16; index++) {
>> - if (priv->irq1_stat & (1 << index))
>> - bcmgenet_tx_reclaim(priv->dev,
>> - &priv->tx_rings[index]);
>> +
>> + if (priv->irq1_stat) {
>> + if (likely(napi_schedule_prep(&priv->napi_priority))) {
>> + bcmgenet_intrl2_1_writel(priv, ~priv->int1_mask,
>> + INTRL2_CPU_MASK_SET);
>> + __napi_schedule(&priv->napi_priority);
>> }
>> }
>> +
>> return IRQ_HANDLED;
>> }
>>
>> -/* bcmgenet_isr0: Handle various interrupts. */
>> +/* bcmgenet_isr0: handle Rx and Tx default queues + other stuff */
>> static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
>> {
>> struct bcmgenet_priv *priv = dev_id;
>> @@ -2054,29 +2151,25 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
>> /* Save irq status for bottom-half processing. */
>> priv->irq0_stat =
>> bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) &
>> - ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
>> + ~priv->int0_mask;
>> +
>> /* clear interrupts */
>> bcmgenet_intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
>>
>> netif_dbg(priv, intr, priv->dev,
>> "IRQ=0x%x\n", priv->irq0_stat);
>>
>> - if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) {
>> - /* We use NAPI(software interrupt throttling, if
>> - * Rx Descriptor throttling is not used.
>> - * Disable interrupt, will be enabled in the poll method.
>> - */
>> + if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE |
>> + UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) {
>> if (likely(napi_schedule_prep(&priv->napi))) {
>> - bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE,
>> - INTRL2_CPU_MASK_SET);
>> + bcmgenet_intrl2_0_writel(priv,
>> + UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE |
>> + UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
>> + INTRL2_CPU_MASK_SET);
>> __napi_schedule(&priv->napi);
>> }
>> }
>> - if (priv->irq0_stat &
>> - (UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE)) {
>> - /* Tx reclaim */
>> - bcmgenet_tx_reclaim(priv->dev, &priv->tx_rings[DESC_INDEX]);
>> - }
>> +
>> if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R |
>> UMAC_IRQ_PHY_DET_F |
>> UMAC_IRQ_LINK_UP |
>> @@ -2170,6 +2263,7 @@ static void bcmgenet_netif_start(struct net_device *dev)
>>
>> /* Start the network engine */
>> napi_enable(&priv->napi);
>> + napi_enable(&priv->napi_priority);
>>
>> umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
>>
>> @@ -2269,6 +2363,7 @@ static void bcmgenet_netif_stop(struct net_device *dev)
>>
>> netif_tx_stop_all_queues(dev);
>> napi_disable(&priv->napi);
>> + napi_disable(&priv->napi_priority);
>> phy_stop(priv->phydev);
>>
>> bcmgenet_intr_disable(priv);
>> @@ -2436,8 +2531,9 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
>> static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
>> [GENET_V1] = {
>> .tx_queues = 0,
>> + .tx_bds_cnt = 0,
>> .rx_queues = 0,
>> - .bds_cnt = 0,
>> + .rx_bds_cnt = 0,
>> .bp_in_en_shift = 16,
>> .bp_in_mask = 0xffff,
>> .hfb_filter_cnt = 16,
>> @@ -2449,8 +2545,9 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
>> },
>> [GENET_V2] = {
>> .tx_queues = 4,
>> - .rx_queues = 4,
>> - .bds_cnt = 32,
>> + .tx_bds_cnt = 32,
>> + .rx_queues = 0,
>> + .rx_bds_cnt = 0,
>> .bp_in_en_shift = 16,
>> .bp_in_mask = 0xffff,
>> .hfb_filter_cnt = 16,
>> @@ -2465,8 +2562,9 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
>> },
>> [GENET_V3] = {
>> .tx_queues = 4,
>> - .rx_queues = 4,
>> - .bds_cnt = 32,
>> + .tx_bds_cnt = 32,
>> + .rx_queues = 0,
>> + .rx_bds_cnt = 0,
>> .bp_in_en_shift = 17,
>> .bp_in_mask = 0x1ffff,
>> .hfb_filter_cnt = 48,
>> @@ -2481,8 +2579,9 @@ static struct bcmgenet_hw_params bcmgenet_hw_params[] = {
>> },
>> [GENET_V4] = {
>> .tx_queues = 4,
>> - .rx_queues = 4,
>> - .bds_cnt = 32,
>> + .tx_bds_cnt = 32,
>> + .rx_queues = 0,
>> + .rx_bds_cnt = 0,
>> .bp_in_en_shift = 17,
>> .bp_in_mask = 0x1ffff,
>> .hfb_filter_cnt = 48,
>> @@ -2560,14 +2659,15 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
>> #endif
>>
>> pr_debug("Configuration for version: %d\n"
>> - "TXq: %1d, RXq: %1d, BDs: %1d\n"
>> + "TXq: %1d, TXBDs: %1d, RXq: %1d, RXBDs: %1d\n"
>> "BP << en: %2d, BP msk: 0x%05x\n"
>> "HFB count: %2d, QTAQ msk: 0x%05x\n"
>> "TBUF: 0x%04x, HFB: 0x%04x, HFBreg: 0x%04x\n"
>> "RDMA: 0x%05x, TDMA: 0x%05x\n"
>> "Words/BD: %d\n",
>> priv->version,
>> - params->tx_queues, params->rx_queues, params->bds_cnt,
>> + params->tx_queues, params->tx_bds_cnt,
>> + params->rx_queues, params->rx_bds_cnt,
>> params->bp_in_en_shift, params->bp_in_mask,
>> params->hfb_filter_cnt, params->qtag_mask,
>> params->tbuf_offset, params->hfb_offset,
>> @@ -2594,8 +2694,9 @@ static int bcmgenet_probe(struct platform_device *pdev)
>> struct resource *r;
>> int err = -EIO;
>>
>> - /* Up to GENET_MAX_MQ_CNT + 1 TX queues and a single RX queue */
>> - dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, 1);
>> + /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */
>> + dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1,
>> + GENET_MAX_MQ_CNT + 1);
>> if (!dev) {
>> dev_err(&pdev->dev, "can't allocate net device\n");
>> return -ENOMEM;
>> @@ -2635,7 +2736,8 @@ static int bcmgenet_probe(struct platform_device *pdev)
>> dev->watchdog_timeo = 2 * HZ;
>> dev->ethtool_ops = &bcmgenet_ethtool_ops;
>> dev->netdev_ops = &bcmgenet_netdev_ops;
>> - netif_napi_add(dev, &priv->napi, bcmgenet_poll, 64);
>> + netif_napi_add(dev, &priv->napi, bcmgenet_poll, 16);
>> + netif_napi_add(dev, &priv->napi_priority, bcmgenet_poll_priority, 64);
>>
>> priv->msg_enable = netif_msg_init(-1, GENET_MSG_DEFAULT);
>>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> index b36ddec..80d9715 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> @@ -310,6 +310,11 @@ struct bcmgenet_mib_counters {
>> #define UMAC_IRQ_MDIO_DONE (1 << 23)
>> #define UMAC_IRQ_MDIO_ERROR (1 << 24)
>>
>> +/* INTRL2 instance 1 definitions */
>> +#define UMAC_IRQ1_TX_INTR_MASK 0xFFFF
>> +#define UMAC_IRQ1_RX_INTR_MASK 0xFFFF
>> +#define UMAC_IRQ1_RX_INTR_SHIFT 16
>> +
>> /* Register block offsets */
>> #define GENET_SYS_OFF 0x0000
>> #define GENET_GR_BRIDGE_OFF 0x0040
>> @@ -503,8 +508,9 @@ enum bcmgenet_version {
>> */
>> struct bcmgenet_hw_params {
>> u8 tx_queues;
>> + u8 tx_bds_cnt;
>> u8 rx_queues;
>> - u8 bds_cnt;
>> + u8 rx_bds_cnt;
>> u8 bp_in_en_shift;
>> u32 bp_in_mask;
>> u8 hfb_filter_cnt;
>> @@ -536,6 +542,18 @@ struct bcmgenet_tx_ring {
>> struct bcmgenet_tx_ring *);
>> };
>>
>> +struct bcmgenet_rx_ring {
>> + unsigned int index; /* Rx ring index */
>> + struct enet_cb *cbs; /* Rx ring buffer control block */
>> + unsigned int size; /* Rx ring size */
>> + unsigned int c_index; /* Rx last consumer index */
>> + unsigned int read_ptr; /* Rx ring read pointer */
>> + unsigned int cb_ptr; /* Rx ring initial CB ptr */
>> + unsigned int end_ptr; /* Rx ring end CB ptr */
>> + void __iomem *bd_assign_ptr; /* Rx ring refill ptr */
>> + unsigned int bd_assign_idx; /* Rx ring refill index */
>> +};
>> +
>> /* device context */
>> struct bcmgenet_priv {
>> void __iomem *base;
>> @@ -546,6 +564,7 @@ struct bcmgenet_priv {
>>
>> /* NAPI for descriptor based rx */
>> struct napi_struct napi ____cacheline_aligned;
>> + struct napi_struct napi_priority ____cacheline_aligned;
>>
>> /* transmit variables */
>> void __iomem *tx_bds;
>> @@ -556,13 +575,11 @@ struct bcmgenet_priv {
>>
>> /* receive variables */
>> void __iomem *rx_bds;
>> - void __iomem *rx_bd_assign_ptr;
>> - int rx_bd_assign_index;
>> struct enet_cb *rx_cbs;
>> unsigned int num_rx_bds;
>> unsigned int rx_buf_len;
>> - unsigned int rx_read_ptr;
>> - unsigned int rx_c_index;
>> +
>> + struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1];
>>
>> /* other misc variables */
>> struct bcmgenet_hw_params *hw_params;
>>
>
^ permalink raw reply
* Re: How do I update Ericsson F5521gw firmware from Linux? / Ericsson F5521gw Random Disconnect Issue
From: Dan Williams @ 2014-12-03 21:29 UTC (permalink / raw)
To: Richard Yao; +Cc: netdev
In-Reply-To: <20141203105841.GF32286@woodpecker.gentoo.org>
On Wed, 2014-12-03 at 10:58 +0000, Richard Yao wrote:
> I purchased an Ericsson F5521gw (Lenovo part 60Y3279) so that my Lenovo T520
> could connect to China Unicom for internet access during a stay in China.
> Unfortunately, it tends to fail every 4 to 8 hours with the following printed
> to the system log:
Probably a better discussion for the ModemManager list (since that's
what you're using) but here goes...
As far as I know, there is no way to do this from Linux unless you
install Windows into a VM and use USB passthrough to allow the VM direct
access to the Ericsson device's USB interfaces.
I'm not sure what version of NetworkManager you're running, but NM
0.9.10+ have WWAN autoconnect support which will reconnect periodically
on failure. That coupled with setting your openvpn VPN connection as a
"secondary connection" to the WWAN should ensure that the VPN is always
up when the WWAN is up. That would be a good workaround if you cannot
find a way to update the firmware.
nmcli con mod "China Unicom" connection.autoconnect yes
nmcli con
<find your VPN connection's name or UUID>
nmcli con mod "China Unicom" +connection.secondaries <VPN name or UUID>
(this does require that your VPN passwords be stored
in /etc/NetworkManager/system-connections/, but rest assured they are
only accessible by root)
Dan
> Dec 3 04:28:27 t520 kernel: [85827.909187] cdc_ncm 2-1.4:1.6 wwan0: network connection: disconnected
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> (ttyACM1): modem state changed, 'connected' --> 'registered' (reason: user-requested)
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> (ttyACM1): device state change: activated -> failed (reason 'modem-no-carrier') [100 120 25]
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> NetworkManager state is now CONNECTED_LOCAL
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> NetworkManager state is now CONNECTED_GLOBAL
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> Policy set 'tun0' (tun0) as default for IPv4 routing and DNS.
> Dec 3 04:28:27 t520 dbus[3912]: [system] Activating service name='org.freedesktop.nm_dispatcher' (using servicehelper)
> Dec 3 04:28:27 t520 nm-openvpn[4200]: MANAGEMENT: Client disconnected
> Dec 3 04:28:27 t520 nm-openvpn[4200]: SIGTERM received, sending exit notification to peer
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> (tun0): link disconnected (deferring action for 4 seconds)
> Dec 3 04:28:27 t520 NetworkManager[4134]: <error> [1417598907.695056] [platform/nm-linux-platform.c:1714] add_object(): Netlink error adding 0.0.0.0/0 via 10.8.0.5 dev tun0 metric 1024 mss 0 src user: Unspecific failure
> Dec 3 04:28:27 t520 NetworkManager[4134]: <error> [1417598907.695124] [platform/nm-linux-platform.c:1714] add_object(): Netlink error adding 10.8.0.5/32 via 0.0.0.0 dev tun0 metric 1024 mss 0 src user: Unspecific failure
> Dec 3 04:28:27 t520 NetworkManager[4134]: <error> [1417598907.695165] [platform/nm-linux-platform.c:1714] add_object(): Netlink error adding 0.0.0.0/0 via 10.8.0.5 dev tun0 metric 1024 mss 0 src user: Unspecific failure
> tail: /var/log/messages: file truncated
> Dec 3 04:28:27 t520 NetworkManager[4134]: <error> [1417598907.695165] [platform/nm-linux-platform.c:1714] add_object(): Netlink error adding 0.0.0.0/0 via 10.8.0.5 dev tun0 metric 1024 mss 0 src user: Unspecific failure
> Dec 3 04:28:27 t520 NetworkManager[4134]: <error> [1417598907.695187] [nm-policy.c:693] update_ip4_routing(): Failed to set default route.
> Dec 3 04:28:27 t520 NetworkManager[4134]: <warn> Activation (ttyACM1) failed for connection 'China Unicom'
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> (ttyACM1): device state change: failed -> disconnected (reason 'none') [120 30 0]
> Dec 3 04:28:27 t520 NetworkManager[4134]: <info> (ttyACM1): deactivating device (reason 'none') [0]
> Dec 3 04:28:27 t520 dbus[3912]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
> Dec 3 04:28:27 t520 nm-dispatcher: Dispatching action 'vpn-down' for tun0
> Dec 3 04:28:27 t520 nm-dispatcher: Dispatching action 'down' for wwan0
>
> Here is the modem's description of itself:
>
> mmcli -m 0 --command='AT*EEVINFO=99'
> response: '*EEVINFO:
> Model.................... F5521gw
> IMEI Data................ <REDACTED>
> SVN...................... 05
> Serial Number............ <REDACTED>
> Product Number........... KRD 131 18/221
> Revision................. R1C
> FW Product............... CXP 901 7640/1
> FW Version............... R2A07
> FW Build Date/Time....... 2010-12-03/12:17
> Cust. Product............ CXC 173 0424/22
> Cust. Version............ R1B02
> Customization Descr...... Lenovo
> Format................... 1
> Base Product Number...... 1/KRD 131 18/1
> Base Product Revision.... R1N
> SIMLock Deployment....... 0.0
> SIMLock Description...... Unlocked
> SIMLock Product.......... CXC 173 0839/01
> SIMLock Revision......... R1F
> Model Description........ F5521gw Mobile Broadband Module
> Vendor Name.............. Lenovo
> Config. Set Product...... CXP 901 7629/1
> Config. Set Revision..... R3A02
> Network Customization.... Default;46001
> Customization State...... 0
> Configuration Product.... CXP 901 7640/1
> Configuration Revision... R2A07
> Protocol FW Product...... CXC 173 0063/1
> Protocol FW Version...... R2A07
> Application FW Product... CXC 173 0064/1
> Application FW Version... R2A07
> Network List Product..... CXC 173 1116/1
> Network List Revision.... R1A
> Individualization........ 189.191
> Domain................... 3.3
> Upgrade State............ 1
> Volume info.............. 66 MB total / 43.9% free'
>
> Posts on the Lenovo forums suggest that this can be resolved by updating the
> firmware:
>
> http://forums.lenovo.com/t5/X-Series-Tablet-ThinkPad-Laptops/Ericsson-F5521gw-WWAN-disconnects-intermittently-and-cannot/td-p/565597
>
> Unfortunately, the official firmware updater only runs on Windows and I am
> unable to find a way to update the firmware from Linux. I also cannot find any
> hardware documentation. Does anyone have any suggestions?
> --
> 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 net-next 3/6] net_sched: cls_bpf: remove faulty use of list_for_each_entry_rcu
From: Jamal Hadi Salim @ 2014-12-03 21:15 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, davem
In-Reply-To: <20141203152051.GK1860@nanopsycho.orion>
On 12/03/14 10:20, Jiri Pirko wrote:
> Wed, Dec 03, 2014 at 03:37:46PM CET, jhs@mojatatu.com wrote:
>
> Yep, but this is updater, protected by rtnl. _rcu list travelsal variant
> should be used by reader only (classify callback in cls case).
>
> get op is only called from tc_ctl_tfilter which is always called with
> rtnl held.
>
I am not an rcu officionado. So if the control path is doing a non-rcu
get + rcu-del/change (update) then as long as the fastpath is (read)
rcu locking we are fine and nothing will actually happen until the
fastpath releases and rcu grace period ends, correct?
In which case please accept my:
ACKed-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
^ permalink raw reply
* Re: [PATCHv11 net-next 2/2] openvswitch: Add support for unique flow IDs.
From: Joe Stringer @ 2014-12-03 21:02 UTC (permalink / raw)
To: Pravin Shelar; +Cc: Linux Kernel, dev@openvswitch.org, Linux Netdev List
In-Reply-To: <CALnjE+qfdFu4Vv3RaUmOtXuvrY+_iCFLNDXhFu2+zDHBJx0L0A@mail.gmail.com>
On 3 December 2014 at 11:45, Pravin Shelar <pshelar@nicira.com> wrote:
> On Wed, Dec 3, 2014 at 10:47 AM, Joe Stringer <joestringer@nicira.com> wrote:
>> I forgot to mention that this is the first post based against net-next.
>>
>> On 2 December 2014 at 18:56, Joe Stringer <joestringer@nicira.com> wrote:
>>> <....snip...>
>>> diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
>>> index a8b30f3..7f31dbf 100644
>>> --- a/net/openvswitch/flow.h
>>> +++ b/net/openvswitch/flow.h
>>> @@ -197,6 +197,13 @@ struct sw_flow_match {
>>> struct sw_flow_mask *mask;
>>> };
>>>
>>> +#define MAX_UFID_LENGTH 256
>>> +
>>> +struct sw_flow_id {
>>> + u32 ufid_len;
>>> + u32 ufid[MAX_UFID_LENGTH / 4];
>>> +};
>>> +
>>> struct sw_flow_actions {
>>> struct rcu_head rcu;
>>> u32 actions_len;
>>
>> Pravin, I changed the 'struct sw_flow_id' to the above after feedback
>> from the previous round, but it doesn't seem quite right. Is this what
>> you meant? Given that current ovs-vswitchd userspace only generates
>> 128bit UFIDs, it seems wasteful to be allocating so much for this. Did
>> you have in mind for this to be united with the unmasked_key?
>
> I am fine with 128bits of ufid, we can extend it later if we need it.
> But what do you mean by united unmasked key? Can you define the struct
> here?
What I mean, is that we could define sw_flow_id as:
+struct sw_flow_id {
+ u32 ufid_len;
+ u32 ufid[];
+};
...and just allocate sizeof(struct sw_flow_id) + nla_len(ufid_nlattr),
rather than always allocating a 260B structure.
^ permalink raw reply
* Re: [PATCH v2 2/6] ethernet/intel: Use eth_skb_pad and skb_put_padto helpers
From: Jeff Kirsher @ 2014-12-03 19:25 UTC (permalink / raw)
To: Alexander Duyck; +Cc: netdev, davem
In-Reply-To: <20141203161739.9223.52060.stgit@ahduyck-vm-fedora20>
[-- Attachment #1: Type: text/plain, Size: 1276 bytes --]
On Wed, 2014-12-03 at 08:17 -0800, Alexander Duyck wrote:
> Update the Intel Ethernet drivers to use eth_skb_pad() and
> skb_put_padto
> instead of doing their own implementations of the function.
>
> Also this cleans up two other spots where skb_pad was called but the
> length
> and tail pointers were being manipulated directly instead of just
> having
> the padding length added via __skb_put.
>
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
> ---
> drivers/net/ethernet/intel/e1000/e1000_main.c | 8 ++------
> drivers/net/ethernet/intel/e1000e/netdev.c | 8 ++------
> drivers/net/ethernet/intel/fm10k/fm10k_main.c | 11 +++--------
> drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 ++------
> drivers/net/ethernet/intel/igb/igb_main.c | 19
> +++++--------------
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 19
> +++++--------------
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 11 +++--------
> 7 files changed, 22 insertions(+), 62 deletions(-)
Since this is a part of a series, no need to break it up, by having me
only pull in this one patch.
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ 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