* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Eric Dumazet @ 2015-02-03 14:27 UTC (permalink / raw)
To: Michal Kazior
Cc: linux-wireless, Network Development,
eyalpe-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb
In-Reply-To: <CA+BoTQkMikA8wxm1ce2DkKhPB0HiKeAqT7f+sQ=91W40z=X0Rg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, 2015-02-03 at 12:50 +0100, Michal Kazior wrote:
> On 3 February 2015 at 02:18, Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > On Mon, 2015-02-02 at 10:52 -0800, Eric Dumazet wrote:
> >
> >> It seems to break ACK clocking badly (linux stack has a somewhat buggy
> >> tcp_tso_should_defer(), which relies on ACK being received smoothly, as
> >> no timer is setup to split the TSO packet.)
> >
> > Following patch might help the TSO split defer logic.
> >
> > It would avoid setting the TSO defer 'pseudo timer' twice, if/when TCP
> > Small Queue logic prevented the xmit at the expiration of first 'timer'.
> >
> > This patch clears the tso_deferred variable only if we could really
> > send something.
> >
> > Please try it, thanks !
> [..patch..]
>
> I've done a second round of tests. I've added the A-MSDU count
> parameter I've mentioned in my other email into the mix.
>
> net - net/master (includes stretch ack patches)
> net-tso - net/master + your TSO defer patch
> net-gro - net/master + my ath10k GRO patch
> net-gro-tso - net/master + duh
>
> Here's the best of amsdu count 1 and 3:
>
> ; for (i in */output.txt) { echo $i; for (j in (1 3)) { cat $i | awk
> 'x && /Mbits/ {y=$0}; x && y && !/Mbits/ {print y; x=0; y=""}; /set
> amsdu cnt to '$j'/{x=1}' | awk '{ if (x < $(NF-1)) {x=$(NF-1)} }
> END{print "A-MSDU limit='$j', " x " Mbits/sec"}' } }
> net-gro-tso/output.txt
> A-MSDU limit=1, 436 Mbits/sec
> A-MSDU limit=3, 284 Mbits/sec
> net-gro/output.txt
> A-MSDU limit=1, 444 Mbits/sec
> A-MSDU limit=3, 283 Mbits/sec
> net-tso/output.txt
> A-MSDU limit=1, 376 Mbits/sec
> A-MSDU limit=3, 251 Mbits/sec
> net/output.txt
> A-MSDU limit=1, 387 Mbits/sec
> A-MSDU limit=3, 260 Mbits/sec
>
> IOW:
> - stretch acks / TSO defer don't seem to help much (when compared to
> throughput results from yesterday)
> - GRO helps
> - disabling A-MSDU on sender helps
> - net/master+GRO still doesn't reach the performance from before the
> regression (~600mbps w/ GRO)
>
> You can grab logs and dumps here: http://www.filedropper.com/test2tar
>
Thanks for these traces.
There is absolutely a problem at the sender, as we can see a big 2ms
delay between reception of ACK and send of following packets.
TCP stack should generate them immediately.
Are you using some kind of netem qdisc ?
These 2ms delays, in a flow with a 5ms RTT are terrible.
06:54:57.408391 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 4294899240, win 11268, options [nop,nop,TS val 1053302 ecr 1052250], length 0
06:54:57.408418 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 4294910824, win 11268, options [nop,nop,TS val 1053303 ecr 1052251], length 0
06:54:57.408431 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 4294936888, win 11268, options [nop,nop,TS val 1053303 ecr 1052251], length 0
06:54:57.408453 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 4294962952, win 11268, options [nop,nop,TS val 1053303 ecr 1052251], length 0
06:54:57.408474 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 0, win 11268, options [nop,nop,TS val 1053303 ecr 1052251], length 0
<this 2ms delay is not generated by TCP stack.>
06:54:57.410243 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 82536:83984, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410271 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 83984:85432, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410289 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 85432:86880, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410310 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 86880:88328, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410326 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 88328:89776, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410339 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 89776:91224, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410353 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 91224:92672, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
06:54:57.410370 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 92672:94120, ack 1, win 457, options [nop,nop,TS val 1052256 ecr 1053303], length 1448
...
06:54:57.411178 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 28960, win 11268, options [nop,nop,TS val 1053306 ecr 1052253], length 0
06:54:57.411190 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 52128, win 11268, options [nop,nop,TS val 1053306 ecr 1052254], length 0
06:54:57.411220 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 78192, win 11268, options [nop,nop,TS val 1053306 ecr 1052254], length 0
06:54:57.411243 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 82536, win 11268, options [nop,nop,TS val 1053306 ecr 1052254], length 0
< same 2ms unexplained gap here >
06:54:57.412912 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 165072:166520, ack 1, win 457, options [nop,nop,TS val 1052259 ecr 1053306], length 1448
06:54:57.412935 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 166520:167968, ack 1, win 457, options [nop,nop,TS val 1052259 ecr 1053306], length 1448
06:54:57.412948 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 167968:169416, ack 1, win 457, options [nop,nop,TS val 1052259 ecr 1053306], length 1448
...
06:54:57.413650 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 244712:246160, ack 1, win 457, options [nop,nop,TS val 1052260 ecr 1053306], length 1448
06:54:57.413662 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 246160:247608, ack 1, win 457, options [nop,nop,TS val 1052260 ecr 1053306], length 1448
06:54:57.413712 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 112944, win 11268, options [nop,nop,TS val 1053308 ecr 1052256], length 0
06:54:57.413730 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 130320, win 11268, options [nop,nop,TS val 1053308 ecr 1052257], length 0
06:54:57.413754 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 160728, win 11268, options [nop,nop,TS val 1053309 ecr 1052257], length 0
06:54:57.413779 IP 192.168.1.2.5001 > 192.168.1.3.51645: Flags [.], ack 165072, win 11268, options [nop,nop,TS val 1053309 ecr 1052257], length 0
< same 2ms delay >
06:54:57.415682 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 247608:249056, ack 1, win 457, options [nop,nop,TS val 1052262 ecr 1053309], length 1448
06:54:57.415709 IP 192.168.1.3.51645 > 192.168.1.2.5001: Flags [.], seq 249056:250504, ack 1, win 457, options [nop,nop,TS val 1052262 ecr 1053309], length 1448
Are packets TX completed after a timer or something ?
Some very heavy stuff might run from tasklet (or other softirq triggered) event.
BTW, traces tend to show that you 'receive' multiple ACK in the same burst,
its not clear if they are delayed at one side or the other.
GRO should delay only GRO candidates. ACK packets are not GRO candidates.
Have you tried to disable GSO on sender ?
(Or maybe wifi drivers should start to use skb->xmit_more as a signal to end aggregation)
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 08/17] {macvtap,tun}_get_user(): switch to iov_iter
From: Al Viro @ 2015-02-03 14:27 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: David Miller, netdev, linux-kernel
In-Reply-To: <20150203101044.GA5081@redhat.com>
On Tue, Feb 03, 2015 at 12:10:44PM +0200, Michael S. Tsirkin wrote:
> Hmm does copy_from_iter actually modify the iovec?
> If so, won't this break aio on tun/macvtap, by
> reversing the effect of
> commit 6f26c9a7555e5bcca3560919db9b852015077dae
> tun: fix tun_chr_aio_write so that aio works
> ?
>
>
> Maybe we should change iovec_iter to avoid modifying the
> underlying iovec?
iov_iter never changes the underlying iovec (or kvec, or bvec).
iter->iov_offset changes as you go and once you have consumed an
entire iovec element ->iov is incremented to point to the next one
(and ->iov_offset is reset to 0 at that point). *Contents* of
iter->iov is never modified.
^ permalink raw reply
* RFC: Fix "tc filter show" for basic filters
From: Ignacy Gawedzki @ 2015-02-03 14:11 UTC (permalink / raw)
To: netdev
Hi everyone,
I have a problem with tc filter and very simple "basic" filters with no
associated action.
The thing is I have an HTB qdisc with handle 1: with a single class 1:1
attached to it. When I add a basic filter that does nothing,
tc filter add dev eth0 prio 1 handle 1 parent 1: basic classid 1:1
it doesn't completely appear when I type
tc filter show dev eth0
When debugging basic_dump() in net/sched/cls_basic.c, I noticed that
tcf_exts_dump_stats() returns -1, which triggers a jump to nla_put_failure
which ends up removing all the added attributes so far. When looking at
tcf_action_copy_stats() in net/sched/act_api.c, which is ultimately called by
tcf_exts_dump_stats(), I see that the returned error is triggered by a->priv
being NULL.
Although I confess I didn't make the effort of understanding all the workings
of a->priv in this context, it seems to me that if that is NULL, this is
probably not a good reason to return an error. I made the change below and so
far it works for me.
Can anyone take a critical look at this?
Thanks.
Ignacy
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 3d43e49..6dd46be 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -602,7 +602,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct
tc_action *a,
struct tcf_common *p = a->priv;
if (p == NULL)
- goto errout;
+ return 0;
/* compat_mode being true specifies a call that is supposed
* to add additional backward compatibility statistic TLVs.
--
Ignacy Gawędzki
R&D Engineer
Green Communications
^ permalink raw reply related
* Re: [PATCHv3, ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: Nicolas Dichtel @ 2015-02-03 14:02 UTC (permalink / raw)
To: Steffen Klassert; +Cc: Fan Du, herbert, davem, netdev, fengyuleidian0615
In-Reply-To: <20150203122432.GV13046@secunet.com>
Le 03/02/2015 13:24, Steffen Klassert a écrit :
> On Mon, Feb 02, 2015 at 10:02:50AM +0100, Nicolas Dichtel wrote:
>
> I tend to apply this patch unless you can come up with a real world
> application that will break if we do so.
It's a custom patch made for strongswan (not included upstream).
My suggestion was to display an error message instead of rejecting the message.
But fair enough, let's apply this patch, it will force people to come up with a
proper solution.
^ permalink raw reply
* [PATCH net-next 4/4] tipc: separate link starting event from link timeout event
From: Jon Maloy @ 2015-02-03 13:59 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1422971960-9172-1-git-send-email-jon.maloy@ericsson.com>
When a new link instance is created, it is trigged to start by
sending it a TIPC_STARTING_EVT, whereafter a regular link
reset is applied to it.
The starting event is codewise treated as a timeout event, and prompts
a link RESET message to be sent to the peer node, carrying a link
session identifier. The later link_reset() call nudges this session
identifier, whereafter all subsequent RESET messages will be sent out
with the new identifier. The latter session number overrides the former,
causing the peer to unconditionally accept it irrespective of its
current working state.
We don't think that this causes any problem, but it is not in accordance
with the protocol spec, and may cause confusion when debugging TIPC
sessions.
To avoid this, we make the starting event distinct from the
subsequent timeout events, by not allowing the former to send
out any RESET message. This eliminates the described problem.
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 46aa599..77c7ccd 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -649,7 +649,9 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
break;
case STARTING_EVT:
l_ptr->flags |= LINK_STARTED;
- /* fall through */
+ l_ptr->fsm_msg_cnt++;
+ link_set_timer(l_ptr, cont_intv);
+ break;
case TIMEOUT_EVT:
tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
l_ptr->fsm_msg_cnt++;
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 3/4] tipc: eliminate race during node creation
From: Jon Maloy @ 2015-02-03 13:59 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1422971960-9172-1-git-send-email-jon.maloy@ericsson.com>
Instances of struct node are created in the function tipc_disc_rcv()
under the assumption that there is no race between received discovery
messages arriving from the same node. This assumption is wrong.
When we use more than one bearer, it is possible that discovery
messages from the same node arrive at the same moment, resulting in
creation of two instances of struct tipc_node. This may later cause
confusion during link establishment, and may result in one of the links
never becoming activated.
We fix this by making lookup and potential creation of nodes atomic.
Instead of first looking up the node, and in case of failure, create it,
we now start with looking up the node inside node_link_create(), and
return a reference to that one if found. Otherwise, we go ahead and
create the node as we did before.
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/discover.c | 9 ++-------
net/tipc/node.c | 11 +++++------
2 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 5b40cb8..a580a40 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -1,7 +1,7 @@
/*
* net/tipc/discover.c
*
- * Copyright (c) 2003-2006, 2014, Ericsson AB
+ * Copyright (c) 2003-2006, 2014-2015, Ericsson AB
* Copyright (c) 2005-2006, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -47,7 +47,6 @@
/* indicates no timer in use */
#define TIPC_LINK_REQ_INACTIVE 0xffffffff
-
/**
* struct tipc_link_req - information about an ongoing link setup request
* @bearer_id: identity of bearer issuing requests
@@ -163,13 +162,9 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
if (!tipc_in_scope(bearer->domain, onode))
return;
- /* Locate, or if necessary, create, node: */
- node = tipc_node_find(net, onode);
- if (!node)
- node = tipc_node_create(net, onode);
+ node = tipc_node_create(net, onode);
if (!node)
return;
-
tipc_node_lock(node);
link = node->links[bearer->identity];
diff --git a/net/tipc/node.c b/net/tipc/node.c
index d4cb8c1..842bd7a 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -96,14 +96,14 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
struct tipc_node *n_ptr, *temp_node;
spin_lock_bh(&tn->node_list_lock);
-
+ n_ptr = tipc_node_find(net, addr);
+ if (n_ptr)
+ goto exit;
n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
if (!n_ptr) {
- spin_unlock_bh(&tn->node_list_lock);
pr_warn("Node creation failed, no memory\n");
- return NULL;
+ goto exit;
}
-
n_ptr->addr = addr;
n_ptr->net = net;
spin_lock_init(&n_ptr->lock);
@@ -123,9 +123,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
list_add_tail_rcu(&n_ptr->list, &temp_node->list);
n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
n_ptr->signature = INVALID_NODE_SIG;
-
tn->num_nodes++;
-
+exit:
spin_unlock_bh(&tn->node_list_lock);
return n_ptr;
}
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 2/4] tipc: avoid stale link after aborted failover
From: Jon Maloy @ 2015-02-03 13:59 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1422971960-9172-1-git-send-email-jon.maloy@ericsson.com>
During link failover it may happen that the remaining link goes
down while it is still in the process of taking over traffic
from a previously failed link. When this happens, we currently
abort the failover procedure and reset the first failed link to
non-failover mode, so that it will be ready to re-establish
contact with its peer when it comes available.
However, if the first link goes down because its bearer was manually
disabled, it is not enough to reset it; it must also be deleted;
which is supposed to happen when the failover procedure is finished.
Otherwise it will remain a zombie link: attached to the owner node
structure, in mode LINK_STOPPED, and permanently blocking any re-
establishing of the link to the peer via the interface in question.
We fix this by amending the failover abort procedure. Apart from
resetting the link to non-failover state, we test if the link is
also in LINK_STOPPED mode. If so, we delete it, using the conditional
tipc_link_delete() function introduced in the previous commit.
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.h | 1 +
net/tipc/node.c | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/net/tipc/link.h b/net/tipc/link.h
index f06b779..3e3432b 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -202,6 +202,7 @@ struct tipc_port;
struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
struct tipc_bearer *b_ptr,
const struct tipc_media_addr *media_addr);
+void tipc_link_delete(struct tipc_link *link);
void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
bool shutting_down);
void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ee5d33c..d4cb8c1 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -406,6 +406,10 @@ static void node_lost_contact(struct tipc_node *n_ptr)
l_ptr->reset_checkpoint = l_ptr->next_in_no;
l_ptr->exp_msg_count = 0;
tipc_link_reset_fragments(l_ptr);
+
+ /* Link marked for deletion after failover? => do it now */
+ if (l_ptr->flags & LINK_STOPPED)
+ tipc_link_delete(l_ptr);
}
n_ptr->action_flags &= ~TIPC_WAIT_OWN_LINKS_DOWN;
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 1/4] tipc: add reference count to struct tipc_link
From: Jon Maloy @ 2015-02-03 13:59 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1422971960-9172-1-git-send-email-jon.maloy@ericsson.com>
When a bearer is disabled, all pertaining links will be reset and
deleted. However, if there is a second active link towards a killed
link's destination, the delete has to be postponed until the failover
is finished. During this interval, we currently put the link in zombie
mode, i.e., we take it out of traffic, delete its timer, but leave it
attached to the owner node structure until all missing packets have
been received. When this is done, we detach the link from its node
and delete it, assuming that the synchronous timer deletion that was
initiated earlier in a different thread has finished.
This is unsafe, as the failover may finish before del_timer_sync()
has returned in the other thread.
We fix this by adding an atomic reference counter of type kref in
struct tipc_link. The counter keeps track of the references kept
to the link by the owner node and the timer. We then do a conditional
delete, based on the reference counter, both after the failover has
been finished and when the timer expires, if applicable. Whoever
comes last, will actually delete the link. This approach also implies
that we can make the deletion of the timer asynchronous.
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/link.c | 79 +++++++++++++++++++++++++++++++++++----------------------
net/tipc/link.h | 2 ++
2 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2846ad80..46aa599 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -127,6 +127,21 @@ static unsigned int align(unsigned int i)
return (i + 3) & ~3u;
}
+static void tipc_link_release(struct kref *kref)
+{
+ kfree(container_of(kref, struct tipc_link, ref));
+}
+
+static void tipc_link_get(struct tipc_link *l_ptr)
+{
+ kref_get(&l_ptr->ref);
+}
+
+static void tipc_link_put(struct tipc_link *l_ptr)
+{
+ kref_put(&l_ptr->ref, tipc_link_release);
+}
+
static void link_init_max_pkt(struct tipc_link *l_ptr)
{
struct tipc_node *node = l_ptr->owner;
@@ -222,11 +237,13 @@ static void link_timeout(unsigned long data)
tipc_link_push_packets(l_ptr);
tipc_node_unlock(l_ptr->owner);
+ tipc_link_put(l_ptr);
}
static void link_set_timer(struct tipc_link *link, unsigned long time)
{
- mod_timer(&link->timer, jiffies + time);
+ if (!mod_timer(&link->timer, jiffies + time))
+ tipc_link_get(link);
}
/**
@@ -267,7 +284,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
pr_warn("Link creation failed, no memory\n");
return NULL;
}
-
+ kref_init(&l_ptr->ref);
l_ptr->addr = peer;
if_name = strchr(b_ptr->name, ':') + 1;
sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
@@ -305,46 +322,48 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
skb_queue_head_init(&l_ptr->waiting_sks);
link_reset_statistics(l_ptr);
-
tipc_node_attach_link(n_ptr, l_ptr);
-
setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
-
link_state_event(l_ptr, STARTING_EVT);
return l_ptr;
}
+/**
+ * link_delete - Conditional deletion of link.
+ * If timer still running, real delete is done when it expires
+ * @link: link to be deleted
+ */
+void tipc_link_delete(struct tipc_link *link)
+{
+ tipc_link_reset_fragments(link);
+ tipc_node_detach_link(link->owner, link);
+ tipc_link_put(link);
+}
+
void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
bool shutting_down)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
- struct tipc_link *l_ptr;
- struct tipc_node *n_ptr;
+ struct tipc_link *link;
+ struct tipc_node *node;
rcu_read_lock();
- list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
- tipc_node_lock(n_ptr);
- l_ptr = n_ptr->links[bearer_id];
- if (l_ptr) {
- tipc_link_reset(l_ptr);
- if (shutting_down || !tipc_node_is_up(n_ptr)) {
- tipc_node_detach_link(l_ptr->owner, l_ptr);
- tipc_link_reset_fragments(l_ptr);
- tipc_node_unlock(n_ptr);
-
- /* Nobody else can access this link now: */
- del_timer_sync(&l_ptr->timer);
- kfree(l_ptr);
- } else {
- /* Detach/delete when failover is finished: */
- l_ptr->flags |= LINK_STOPPED;
- tipc_node_unlock(n_ptr);
- del_timer_sync(&l_ptr->timer);
- }
+ list_for_each_entry_rcu(node, &tn->node_list, list) {
+ tipc_node_lock(node);
+ link = node->links[bearer_id];
+ if (!link) {
+ tipc_node_unlock(node);
continue;
}
- tipc_node_unlock(n_ptr);
+ tipc_link_reset(link);
+ if (del_timer(&link->timer))
+ tipc_link_put(link);
+ link->flags |= LINK_STOPPED;
+ /* Delete link now, or when failover is finished: */
+ if (shutting_down || !tipc_node_is_up(node))
+ tipc_link_delete(link);
+ tipc_node_unlock(node);
}
rcu_read_unlock();
}
@@ -1837,10 +1856,8 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
}
}
exit:
- if ((l_ptr->exp_msg_count == 0) && (l_ptr->flags & LINK_STOPPED)) {
- tipc_node_detach_link(l_ptr->owner, l_ptr);
- kfree(l_ptr);
- }
+ if ((!l_ptr->exp_msg_count) && (l_ptr->flags & LINK_STOPPED))
+ tipc_link_delete(l_ptr);
return buf;
}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 9df7fa4..f06b779 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -103,6 +103,7 @@ struct tipc_stats {
* @media_addr: media address to use when sending messages over link
* @timer: link timer
* @owner: pointer to peer node
+ * @refcnt: reference counter for permanent references (owner node & timer)
* @flags: execution state flags for link endpoint instance
* @checkpoint: reference point for triggering link continuity checking
* @peer_session: link session # being used by peer end of link
@@ -142,6 +143,7 @@ struct tipc_link {
struct tipc_media_addr media_addr;
struct timer_list timer;
struct tipc_node *owner;
+ struct kref ref;
/* Management and link supervision data */
unsigned int flags;
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply related
* [PATCH net-next 0/4] tipc: some small fixes
From: Jon Maloy @ 2015-02-03 13:59 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
During extensive testing and analysis of running dual links between
nodes, we have encountered some issues that potentially may cause
problems. We choose to fix those proactively in this series.
Jon Maloy (4):
tipc: add reference count to struct tipc_link
tipc: avoid stale link after aborted failover
tipc: eliminate race during node creation
tipc: separate link starting event from link timeout event
net/tipc/discover.c | 9 ++----
net/tipc/link.c | 83 ++++++++++++++++++++++++++++++++---------------------
net/tipc/link.h | 3 ++
net/tipc/node.c | 15 ++++++----
4 files changed, 65 insertions(+), 45 deletions(-)
--
1.9.1
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
^ permalink raw reply
* [PATCH] net: rds: use correct size for max unacked packets and bytes
From: Sasha Levin @ 2015-02-03 13:55 UTC (permalink / raw)
To: linux-kernel
Cc: Sasha Levin, Chien Yen, David S. Miller,
moderated list:RDS - RELIABLE DA...,
open list:NETWORKING [GENERAL]
Max unacked packets/bytes is an int while sizeof(long) was used in the
sysctl table.
This means that when they were getting read we'd also leak kernel memory
to userspace along with the timeout values.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
net/rds/sysctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c
index c3b0cd4..c173f69 100644
--- a/net/rds/sysctl.c
+++ b/net/rds/sysctl.c
@@ -71,14 +71,14 @@ static struct ctl_table rds_sysctl_rds_table[] = {
{
.procname = "max_unacked_packets",
.data = &rds_sysctl_max_unacked_packets,
- .maxlen = sizeof(unsigned long),
+ .maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "max_unacked_bytes",
.data = &rds_sysctl_max_unacked_bytes,
- .maxlen = sizeof(unsigned long),
+ .maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
--
1.7.10.4
^ permalink raw reply related
* pull-request: mac80211-next 2015-02-03
From: Johannes Berg @ 2015-02-03 13:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi,
Here's a last pull request for net-next - I hope it can still make it,
we fixed a fairly large number of issues. Also there's a bunch of new
ciphers, but see the details below.
Let me know if there's any problem.
Thanks,
johannes
The following changes since commit c1e140bf79d817d4a7aa9932eb98b0359c87af33:
mac80211: delete the assoc/auth timer upon suspend (2015-01-19 18:59:20 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git tags/mac80211-next-for-davem-2015-02-03
for you to fetch changes up to 79044f60caa7c377333dc8f13cf1e48c144e2521:
net: rfkill: Add Broadcom BCM2E40 bluetooth ACPI ID (2015-02-03 14:38:22 +0100)
----------------------------------------------------------------
Last round of updates for net-next:
* revert a patch that caused a regression with mesh userspace (Bob)
* fix a number of suspend/resume related races
(from Emmanuel, Luca and myself - we'll look at backporting later)
* add software implementations for new ciphers (Jouni)
* add a new ACPI ID for Broadcom's rfkill (Mika)
* allow using netns FD for wireless (Vadim)
* some other cleanups (various)
----------------------------------------------------------------
Bob Copeland (1):
Revert "mac80211: keep sending peer candidate events while in listen state"
Emmanuel Grumbach (2):
mac80211: synchronize_net() before flushing the queues
mac80211: avoid races related to suspend flow
Johannes Berg (9):
mac80211: fix HW registration error paths
mac80211: allow drivers to control software crypto
nl80211: suppress smatch warnings
mac80211: tdls: remove shadowing variable
mac80211: tdls: disentangle HT supported conditions
mac80211: fix per-TID RX-MSDU counter
mac80211: support beacon statistics
ath10k: use IEEE80211_HW_SW_CRYPTO_CONTROL
nl80211: don't document per-wiphy interface dump
Jouni Malinen (6):
cfg80211: Fix BIP (AES-CMAC) cipher validation
cfg80211: Add new GCMP, CCMP-256, BIP-GMAC, BIP-CMAC-256 ciphers
mac80111: Add GCMP and GCMP-256 ciphers
mac80111: Add CCMP-256 cipher
mac80111: Add BIP-CMAC-256 cipher
mac80111: Add BIP-GMAC-128 and BIP-GMAC-256 ciphers
Lorenzo Bianconi (1):
mac80211: enable TPC through mac80211 stack
Luciano Coelho (3):
nl80211: add an attribute to allow delaying the first scheduled scan cycle
mac80211: complete scan work immediately if quiesced or suspended
mac80211: handle potential race between suspend and scan completion
Mika Westerberg (1):
net: rfkill: Add Broadcom BCM2E40 bluetooth ACPI ID
Sharon Dvir (1):
wireless: docs: fix 'make pdfdocs' failure
Vadim Kochan (1):
nl80211: Allow set network namespace by fd
Documentation/DocBook/80211.tmpl | 4 +-
drivers/net/wireless/ath/ath10k/mac.c | 16 +-
include/linux/ieee80211.h | 27 +++
include/net/cfg80211.h | 5 +
include/net/mac80211.h | 39 ++-
include/uapi/linux/nl80211.h | 26 +-
net/core/net_namespace.c | 1 +
net/mac80211/Kconfig | 1 +
net/mac80211/Makefile | 2 +
net/mac80211/aes_ccm.c | 21 +-
net/mac80211/aes_ccm.h | 10 +-
net/mac80211/aes_cmac.c | 34 ++-
net/mac80211/aes_cmac.h | 5 +-
net/mac80211/aes_gcm.c | 95 ++++++++
net/mac80211/aes_gcm.h | 22 ++
net/mac80211/aes_gmac.c | 84 +++++++
net/mac80211/aes_gmac.h | 20 ++
net/mac80211/cfg.c | 50 +++-
net/mac80211/chan.c | 4 +-
net/mac80211/debugfs_key.c | 55 +++++
net/mac80211/ieee80211_i.h | 36 ++-
net/mac80211/iface.c | 12 +-
net/mac80211/key.c | 185 +++++++++++++-
net/mac80211/key.h | 18 ++
net/mac80211/main.c | 107 +++++---
net/mac80211/mesh_plink.c | 7 -
net/mac80211/mlme.c | 3 +
net/mac80211/rx.c | 48 +++-
net/mac80211/scan.c | 5 +
net/mac80211/sta_info.c | 14 ++
net/mac80211/tdls.c | 37 ++-
net/mac80211/tx.c | 20 +-
net/mac80211/util.c | 27 ++-
net/mac80211/wpa.c | 443 +++++++++++++++++++++++++++++++++-
net/mac80211/wpa.h | 19 +-
net/rfkill/rfkill-gpio.c | 1 +
net/wireless/nl80211.c | 31 ++-
net/wireless/util.c | 68 +++++-
38 files changed, 1426 insertions(+), 176 deletions(-)
create mode 100644 net/mac80211/aes_gcm.c
create mode 100644 net/mac80211/aes_gcm.h
create mode 100644 net/mac80211/aes_gmac.c
create mode 100644 net/mac80211/aes_gmac.h
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [V2,for,3.19,3/7] rtlwifi: rtl8192ee: Fix adhoc fail
From: Kalle Valo @ 2015-02-03 13:23 UTC (permalink / raw)
To: Larry Finger; +Cc: linux-wireless, Troy Tan, netdev, Stable
In-Reply-To: <20150203131516.799471409D0@smtp.codeaurora.org>
Kalle Valo <kvalo@codeaurora.org> writes:
>> From: Troy Tan <troy_tan@realsil.com.cn>
>>
>> When the buffer descriptor index exceeds 2, then a TX HANG condition
>> will result.
>>
>> Signed-off-by: Troy Tan <troy_tan@realsil.com.cn>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> Cc: Stable <stable@vger.kernel.org> [V3.18]
>
> Thanks, 4 patches applied to wireless-drivers-next.git:
>
> b661a5da5776 rtlwifi: rtl8192ee: Fix adhoc fail
> 6e5f44361628 rtlwifi: rtl8192ee: Fix TX hang due to failure to update TX write point
> 92ff754240b8 rtlwifi: rtl8192ee: Fix parsing of received packet
> 21b39ddb5bb2 rtlwifi: rtl8192ee: Fix DMA stalls
>
> 3 patches skipped:
I had to skip these three patches because of my mistake. So what I did
was that I had merged ("fast forwarded") the net tree into my
wireless-drivers tree and not realising I should not do that. So now I
can't merge wireless-drivers into wireless-drivers-next anymore, as it
will pull unnecessary net changes.
> [V2,for,3.19,1/7] rtlwifi: Remove logging statement that is no longer
> needed
I'll apply this after 3.20-rc1 is released, it should apply then without
problems (or the conflicts are easy for me to fix). Luckily this is just
a cosmetic error and can wait for 3.20-rc2, right?
> [V2,for,3.19,2/7] rtlwifi: rtl8192ee: Fix handling of new style descriptors
> [V2,for,3.19,6/7] rtlwifi: rtl8192ee: Fix problems with calculating free space in FIFO
Not sure what to do with these one. Should you rebase and send them now?
--
Kalle Valo
^ permalink raw reply
* Re: [V2,for,3.19,3/7] rtlwifi: rtl8192ee: Fix adhoc fail
From: Kalle Valo @ 2015-02-03 13:15 UTC (permalink / raw)
To: Larry Finger; +Cc: linux-wireless, Troy Tan, netdev, Larry Finger, Stable
In-Reply-To: <1421773286-1039-4-git-send-email-Larry.Finger@lwfinger.net>
> From: Troy Tan <troy_tan@realsil.com.cn>
>
> When the buffer descriptor index exceeds 2, then a TX HANG condition
> will result.
>
> Signed-off-by: Troy Tan <troy_tan@realsil.com.cn>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> Cc: Stable <stable@vger.kernel.org> [V3.18]
Thanks, 4 patches applied to wireless-drivers-next.git:
b661a5da5776 rtlwifi: rtl8192ee: Fix adhoc fail
6e5f44361628 rtlwifi: rtl8192ee: Fix TX hang due to failure to update TX write point
92ff754240b8 rtlwifi: rtl8192ee: Fix parsing of received packet
21b39ddb5bb2 rtlwifi: rtl8192ee: Fix DMA stalls
3 patches skipped:
[V2,for,3.19,1/7] rtlwifi: Remove logging statement that is no longer needed
[V2,for,3.19,2/7] rtlwifi: rtl8192ee: Fix handling of new style descriptors
[V2,for,3.19,6/7] rtlwifi: rtl8192ee: Fix problems with calculating free space in FIFO
Kalle Valo
^ permalink raw reply
* Re: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
From: Kalle Valo @ 2015-02-03 13:08 UTC (permalink / raw)
To: Fu, Zhonghui
Cc: brudley, Arend van Spriel, Franky Lin, meuleman, linville,
pieterpg, hdegoede, wens, linux-wireless, brcm80211-dev-list,
netdev, linux-kernel@vger.kernel.org
In-Reply-To: <54C5AA8C.4010005@linux.intel.com>
"Fu, Zhonghui" <zhonghui.fu@linux.intel.com> writes:
>>From ff39ed4af9f1c50358fe92ec4c8eaac9db183e00 Mon Sep 17 00:00:00 2001
> From: Zhonghui Fu <zhonghui.fu@linux.intel.com>
> Date: Mon, 26 Jan 2015 10:13:21 +0800
> Subject: [PATCH] brcmfmac: avoid duplicated suspend/resume operation
>
> WiFi chip has 2 SDIO functions, and PM core will trigger
> twice suspend/resume operations for one WiFi chip to do
> the same things. This patch avoid this case.
>
> Acked-by: Arend van Spriel<arend@broadcom.com>
> Signed-off-by: Zhonghui Fu <zhonghui.fu@linux.intel.com>
This doesn't apply:
Applying: brcmfmac: avoid duplicated suspend/resume operation
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
CONFLICT (content): Merge conflict in drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Failed to merge in the changes.
Patch failed at 0001 brcmfmac: avoid duplicated suspend/resume operation
BTW, when you resend a patch please use "[PATCH v2]" (or v3, v4...) in
the Subject field.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH V2 1/6] rtlwifi: Change logging level for key change
From: Kalle Valo @ 2015-02-03 13:01 UTC (permalink / raw)
To: Larry Finger; +Cc: linux-wireless, netdev
In-Reply-To: <54CBA794.90508@lwfinger.net>
Larry Finger <Larry.Finger@lwfinger.net> writes:
> On 01/26/2015 02:42 PM, Larry Finger wrote:
>> A recent change in key handling included logging of these changes for
>> all debug levels. Such key changes should only be logged when a high
>> level of debugging is enabled.
>>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> ---
>> drivers/net/wireless/rtlwifi/cam.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
>> index 3ef870d..6e64792 100644
>> --- a/drivers/net/wireless/rtlwifi/cam.c
>> +++ b/drivers/net/wireless/rtlwifi/cam.c
>> @@ -406,7 +406,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
>> }
>> }
>> if (found) {
>> - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
>> + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
>> "key_index=%d,cam_bitmap: 0x%x entry_idx=%d\n",
>> key_index, rtlpriv->sec.cam_bitmap, entry_idx);
>> return entry_idx;
>>
>
> Kalle,
>
> Please include this patch even though the rest of this set should be
> dropped.
I tried to do that but it failed:
Applying: rtlwifi: Change logging level for key change
fatal: sha1 information is lacking or useless (drivers/net/wireless/rtlwifi/cam.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 rtlwifi: Change logging level for key change
I was not even able to find that code from cam.c. Have I missed a patch?
> Once the wifi-BT communications problem is resolved, new versions of
> those will be presented.
Sounds good.
> I'm sorry that my commit message was not as informative as it could
> have been. I was presented with this material that I did not
> understand. One saving grace is that the RTL8812AE hardware is
> apparently rare - I certainly do not have any samples. I'm not sure of
> the value of a 1x1 implementation of 802.11ac, but that may be another
> example of my ignorance.
No worries. But stuff like this is usually best to send as RFC first and
ask people to analyse it before sending it officially.
--
Kalle Valo
^ permalink raw reply
* btcoex subsystem
From: Kalle Valo @ 2015-02-03 12:29 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Larry Finger, linux-wireless, Troy Tan, netdev, linux-bluetooth
In-Reply-To: <B814EF26-CBC9-43E4-A6C9-761A013F85C1@holtmann.org>
Marcel Holtmann <marcel@holtmann.org> writes:
>> I will work on combining the latest BT drivers from Realtek with
>> btusb to see if I can achieve a patch that will both work with the
>> Realtek hardware, and get approval from the reviewers.
>>
>> What would be an approved method of communicating between two kernel
>> modules? Is there some example in the kernel that I could study?
>
> We need a btcoex subsystem that both WiFi and Bluetooth can register
> to and communicate with.
The need for this seems to periodically come up, I remember needing
something like that back in the Maemo wl1251 days and also ath6kl needed
this. Are there any ideas for this subsystem? How would this btcoex
subsystem work? What kind of information would it provide?
Is this something we should discuss at Ottawa?
--
Kalle Valo
^ permalink raw reply
* Re: [PATCHv3, ipsec-next] xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host
From: Steffen Klassert @ 2015-02-03 12:24 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: Fan Du, herbert, davem, netdev, fengyuleidian0615
In-Reply-To: <54CF3D3A.5040607@6wind.com>
On Mon, Feb 02, 2015 at 10:02:50AM +0100, Nicolas Dichtel wrote:
> Le 02/02/2015 09:44, Steffen Klassert a écrit :
> >On Thu, Jan 29, 2015 at 11:29:51AM +0100, Nicolas Dichtel wrote:
> [snip]
> >>
> >>The point I try to make is that patching userland apps allows to use xfrm on a
> >>32bits userland / 64bits kernel.
> >
> >Ugh, I did not know that this is used that way. Which applications do this?
> >So the situation is worse than I thought. What happens to such applications
> >if we add a compat layer in the kernel? I'd guess they will break, right?
> A compat layer will be perfect. I just wanted to highlight the fact that without
> this patch, it's possible to have a workaround to use netlink-xfrm and after it,
> it will be impossible.
You did not answer my question about the applications that do this.
If it is just possible, but there are no actual users, we should
apply this patch as soon as possible to avoid any abuse of this ABI.
I tend to apply this patch unless you can come up with a real world
application that will break if we do so.
^ permalink raw reply
* Re: Question: should local address be expired when updating PMTU?
From: Steffen Klassert @ 2015-02-03 12:01 UTC (permalink / raw)
To: shengyong; +Cc: davem, netdev, yangyingliang, hannes
In-Reply-To: <54D0A8DB.4010106@huawei.com>
On Tue, Feb 03, 2015 at 06:54:19PM +0800, shengyong wrote:
>
>
> 在 2015/2/3 17:28, Steffen Klassert 写道:
> > On Mon, Feb 02, 2015 at 04:20:24PM +0800, shengyong wrote:
> >
> > We first need to find out why you receive this Packet Too Big message,
> The packet is sent by a commercial-off-the-shelf testcase, and I can reproduce the
> situation by using scapy and creating a packet as the following:
>
> $ cat packet-too-big.py
> #!/usr/bin/python
>
> from scapy.all import *
>
> # fe80::800:27ff:fe00:0 is linklocal addr of PC
> # fe80::a00:27ff:fe1a:e2a0 is linklocal addr of VM
> base=IPv6(src='fe80::800:27ff:fe00:0',dst='fe80::a00:27ff:fe1a:e2a0')
> pkt_too_big=ICMPv6PacketTooBig(mtu=1024)
> ext_base=IPv6(src='fe80::a00:27ff:fe1a:e2a0',dst='fe80::a00:27ff:fe1a:e2a0',plen=24)
> ext_nd_na=ICMPv6ND_NA()
>
> packet=base/pkt_too_big/ext_base/ext_nd_na
> send(packet)
So it is not a valid pmtu update, this make life easier.
Can you please test the patch below (compile tested only)?
This should fix your problem, and in combination with the two patches I sent
out last week, it should cure the whole 'expiring of uncached routes' problem.
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 49596535..4ccfb9c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1156,7 +1156,8 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct rt6_info *rt6 = (struct rt6_info *)dst;
dst_confirm(dst);
- if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128) {
+ if (mtu < dst_mtu(dst) && rt6->rt6i_dst.plen == 128 &&
+ (rt6->rt6i_flags & RTF_CACHE)) {
struct net *net = dev_net(dst->dev);
rt6->rt6i_flags |= RTF_MODIFIED;
^ permalink raw reply related
* Re: [PATCH] ath9k_htc: add adaptive usb flow control to repair soft lockup with monitor mode
From: Kalle Valo @ 2015-02-03 11:52 UTC (permalink / raw)
To: yuweizheng
Cc: linux-kernel, ath9k-devel, linux-wireless, ath9k-devel, netdev,
Yuwei Zheng
In-Reply-To: <1422957585-19736-1-git-send-email-yuweizheng@139.com>
yuweizheng@139.com writes:
> From: Yuwei Zheng <yuweizheng@139.com>
>
> In the environment with heavy wifi traffic, set the ar9271 into monitor mode, will
> trigger a deadloop panic.
>
> The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
> on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
> ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
> and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
The word wrapping is still wrong, please limit the width to 72 chars or
so. But no need to wrap log snippets, they can exceed the limit.
> Signed-off-by: Yuwei Zheng <zhengyuwei@360.cn>
> Signed-off-by: Yuwei Zheng <yuweizheng@139.com>
Why two of these? Please use just one Signed-off-by line. Unless these
are two different persons with the same name :)
--
Kalle Valo
^ permalink raw reply
* Re: Throughput regression with `tcp: refine TSO autosizing`
From: Michal Kazior @ 2015-02-03 11:50 UTC (permalink / raw)
To: Eric Dumazet; +Cc: linux-wireless, Network Development, eyalpe
In-Reply-To: <1422926330.21689.138.camel@edumazet-glaptop2.roam.corp.google.com>
On 3 February 2015 at 02:18, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Mon, 2015-02-02 at 10:52 -0800, Eric Dumazet wrote:
>
>> It seems to break ACK clocking badly (linux stack has a somewhat buggy
>> tcp_tso_should_defer(), which relies on ACK being received smoothly, as
>> no timer is setup to split the TSO packet.)
>
> Following patch might help the TSO split defer logic.
>
> It would avoid setting the TSO defer 'pseudo timer' twice, if/when TCP
> Small Queue logic prevented the xmit at the expiration of first 'timer'.
>
> This patch clears the tso_deferred variable only if we could really
> send something.
>
> Please try it, thanks !
[..patch..]
I've done a second round of tests. I've added the A-MSDU count
parameter I've mentioned in my other email into the mix.
net - net/master (includes stretch ack patches)
net-tso - net/master + your TSO defer patch
net-gro - net/master + my ath10k GRO patch
net-gro-tso - net/master + duh
Here's the best of amsdu count 1 and 3:
; for (i in */output.txt) { echo $i; for (j in (1 3)) { cat $i | awk
'x && /Mbits/ {y=$0}; x && y && !/Mbits/ {print y; x=0; y=""}; /set
amsdu cnt to '$j'/{x=1}' | awk '{ if (x < $(NF-1)) {x=$(NF-1)} }
END{print "A-MSDU limit='$j', " x " Mbits/sec"}' } }
net-gro-tso/output.txt
A-MSDU limit=1, 436 Mbits/sec
A-MSDU limit=3, 284 Mbits/sec
net-gro/output.txt
A-MSDU limit=1, 444 Mbits/sec
A-MSDU limit=3, 283 Mbits/sec
net-tso/output.txt
A-MSDU limit=1, 376 Mbits/sec
A-MSDU limit=3, 251 Mbits/sec
net/output.txt
A-MSDU limit=1, 387 Mbits/sec
A-MSDU limit=3, 260 Mbits/sec
IOW:
- stretch acks / TSO defer don't seem to help much (when compared to
throughput results from yesterday)
- GRO helps
- disabling A-MSDU on sender helps
- net/master+GRO still doesn't reach the performance from before the
regression (~600mbps w/ GRO)
You can grab logs and dumps here: http://www.filedropper.com/test2tar
Michał
^ permalink raw reply
* [PATCH] csiostor:Use firmware version from cxgb4/t4fw_version.h
From: Praveen Madhavan @ 2015-02-03 11:48 UTC (permalink / raw)
To: netdev, linux-scsi; +Cc: davem, JBottomley, hch, hariprasad, praveenm
This patch is to use firmware version macros from t4fw_version.h
and also enables 40g T5 adapter.
Signed-off-by: Praveen Madhavan <praveenm@chelsio.com>
---
drivers/scsi/csiostor/csio_hw.c | 6 ++++--
drivers/scsi/csiostor/csio_hw_chip.h | 6 +-----
drivers/scsi/csiostor/csio_mb.c | 3 ++-
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index c81b06b..2e66f34 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -1372,7 +1372,8 @@ csio_config_device_caps(struct csio_hw *hw)
}
/* Validate device capabilities */
- if (csio_hw_validate_caps(hw, mbp))
+ rv = csio_hw_validate_caps(hw, mbp);
+ if (rv != 0)
goto out;
/* Don't config device capabilities if already configured */
@@ -1776,7 +1777,8 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param)
}
/* Validate device capabilities */
- if (csio_hw_validate_caps(hw, mbp))
+ rv = csio_hw_validate_caps(hw, mbp);
+ if (rv != 0)
goto bye;
/*
* Note that we're operating with parameters
diff --git a/drivers/scsi/csiostor/csio_hw_chip.h b/drivers/scsi/csiostor/csio_hw_chip.h
index a5f624f..b56a11d 100644
--- a/drivers/scsi/csiostor/csio_hw_chip.h
+++ b/drivers/scsi/csiostor/csio_hw_chip.h
@@ -45,11 +45,6 @@
#define FW_FNAME_T5 "cxgb4/t5fw.bin"
#define FW_CFG_NAME_T5 "cxgb4/t5-config.txt"
-#define T5FW_VERSION_MAJOR 0x01
-#define T5FW_VERSION_MINOR 0x0B
-#define T5FW_VERSION_MICRO 0x1B
-#define T5FW_VERSION_BUILD 0x00
-
#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
#define CHELSIO_CHIP_FPGA 0x100
#define CHELSIO_CHIP_VERSION(code) (((code) >> 12) & 0xf)
@@ -74,6 +69,7 @@ static inline int csio_is_t5(uint16_t chip)
{ PCI_VENDOR_ID_CHELSIO, (devid), PCI_ANY_ID, PCI_ANY_ID, 0, 0, (idx) }
#include "t4fw_api.h"
+#include "t4fw_version.h"
#define FW_VERSION(chip) ( \
FW_HDR_FW_VER_MAJOR_G(chip##FW_VERSION_MAJOR) | \
diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c
index 1132c41..9451787 100644
--- a/drivers/scsi/csiostor/csio_mb.c
+++ b/drivers/scsi/csiostor/csio_mb.c
@@ -327,7 +327,8 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
}
#define CSIO_ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
- FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)
+ FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G |\
+ FW_PORT_CAP_ANEG)
/*
* csio_mb_port- FW PORT command helper
--
2.0.2
^ permalink raw reply related
* Re: [GIT PULL nf] IPVS Fixes for v3.19
From: Pablo Neira Ayuso @ 2015-02-03 11:47 UTC (permalink / raw)
To: Simon Horman
Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
Julian Anastasov
In-Reply-To: <1422580938-31520-1-git-send-email-horms@verge.net.au>
On Fri, Jan 30, 2015 at 10:22:17AM +0900, Simon Horman wrote:
> Hi Pablo,
>
> please consider this fix for v3.19.
>
> It resolves a crash in xfrm reported by Florian Wiessner.
>
> I believe this problem manifests since 0a5ebb8000c5 ("ipv4: Pass explicit
> daddr arg to ip_send_reply().") which was included in v2.6.39.
>
> Julian reports that the patch has been tested on net tree (Dec 7), 3.14.25,
> 3.12.33, 3.10.61. 3.4.104 needs a modified fix that resolves rejects. It
> applies with little fuzz on 3.2.64. Please let us know if we should post
> separate 3.2 and 3.4 patches.
Regarding -stable. This seems to apply cleanly to:
3.10.x
3.12.x
3.14.x
3.18.x
Not compiled tested yet, just clean application.
Lower versions need some backporting, I leave this to you to evaluate
if it is worth the effort.
Thanks!
^ permalink raw reply
* Re: Question: should local address be expired when updating PMTU?
From: shengyong @ 2015-02-03 10:54 UTC (permalink / raw)
To: Steffen Klassert; +Cc: davem, netdev, yangyingliang, hannes
In-Reply-To: <20150203092845.GT13046@secunet.com>
在 2015/2/3 17:28, Steffen Klassert 写道:
> On Mon, Feb 02, 2015 at 04:20:24PM +0800, shengyong wrote:
>> Hi, David Miller
>> Since commit 81aded246 (ipv6: Handle PMTU in ICMP error handlers), the entries
>> in neigh table may get expired. But in the situation:
>>
>> Host only
>> PC <------------> Virtual Machine
>>
>> a packet is sent from PC to VM, and the packet looks like:
>> -----------------------------------
>> | IPv6 (src=PC-addr, dst=VM-addr) |
>> |---------------------------------|
>> | ICMPv6 (Packet Too Big) |
>> |---------------------------------|
>> | IPv6 (src=VM-addr, dst=VM-addr) |
>> |---------------------------------|
>> | ICMPv6 (Neighbor Advertisement) |
>> -----------------------------------
>>
>> Then the local addr on VM will be updated with an expire value. After the
>> lifetime of the local addr is expired, the VM is unreachable from PC.
>>
>> # ip -6 route list table local
>> local fe80::1 dev lo metric 0 *expire 596*
>
> We first need to find out why you receive this Packet Too Big message,
The packet is sent by a commercial-off-the-shelf testcase, and I can reproduce the
situation by using scapy and creating a packet as the following:
$ cat packet-too-big.py
#!/usr/bin/python
from scapy.all import *
# fe80::800:27ff:fe00:0 is linklocal addr of PC
# fe80::a00:27ff:fe1a:e2a0 is linklocal addr of VM
base=IPv6(src='fe80::800:27ff:fe00:0',dst='fe80::a00:27ff:fe1a:e2a0')
pkt_too_big=ICMPv6PacketTooBig(mtu=1024)
ext_base=IPv6(src='fe80::a00:27ff:fe1a:e2a0',dst='fe80::a00:27ff:fe1a:e2a0',plen=24)
ext_nd_na=ICMPv6ND_NA()
packet=base/pkt_too_big/ext_base/ext_nd_na
send(packet)
> can you capture this packet somehow?
I captured the packet in wireshark, it is exact the packet created by the script.
> Then we have to see why this loopback
> route gets a pmtu update from that packet.
I tried to print info when the VM receives pkt-too-big packet. The calling stack is
icmpv6_rcv->icmpv6_notify->icmpv6_err->ip6_update_pmtu->ip6_rt_update_pmtu->rt6_update_expires.
In ip6_update_pmtu, ip6_route_output looks up the route table, and returns the dst_entry of the
linklocal addr. Then it is set to expire.
> Is the destination address
> of the Packet Too Big message really fe80::1?
In fact, if the dst of the above `ext_base' is the local addr of the VM, the local addr on VM
will be expired.
thx,
Sheng
>
> --
> 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] ath9k_htc: add adaptive rate control to repair soft lockup with monitor mode
From: Oleksij Rempel @ 2015-02-03 10:39 UTC (permalink / raw)
To: yuweizheng, linux-kernel, ath9k-devel, linux-wireless, kvalo,
ath9k-devel
Cc: netdev, Yuwei Zheng
In-Reply-To: <1422955270-19499-1-git-send-email-yuweizheng@139.com>
[-- Attachment #1: Type: text/plain, Size: 12884 bytes --]
Looks good,
please just one note. Rename "rate control" to "usb flow control", or
some thing like this. In this context "rate control" has different meaning.
I'll run you patches on my system with different adapters.
Am 03.02.2015 um 10:21 schrieb yuweizheng@139.com:
> From: Yuwei Zheng <yuweizheng@139.com>
>
> In the environment with heavy wifi traffic, set the ar9271 into monitor mode, will
> trigger a deadloop panic.
> The ath9k_hif_usb_rx_cb function excute on the interrupt context, and ath9k_rx_tasklet excute
> on the soft irq context. In other words, the ath9k_hif_usb_rx_cb have more chance to excute than
> ath9k_rx_tasklet. So in the worst condition, the rx.rxbuf receive list is always full,
> and the do {}while(true) loop will not be break. The kernel get a soft lockup panic.
> [59011.007210] BUG: soft lockup - CPU#0 stuck for 23s!
> [kworker/0:0:30609]
> [59011.030560] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.804486] BUG: scheduling while atomic: kworker/0:0/30609/0x40010100
> [59013.858522] Kernel panic - not syncing: softlockup: hung tasks
> [59014.038891] Exception stack(0xdf4bbc38 to 0xdf4bbc80)
> [59014.046834] bc20: de57b950 60000113
> [59014.059579] bc40: 00000000 bb32bb32 60000113 de57b948 de57b500 dc7bb440 df4bbcd0 00000000
> [59014.072337] bc60: de57b950 60000113 df4bbcd0 df4bbc80 c04c259d c04c25a0 60000133 ffffffff
> [59014.085233] [<c04c28db>] (__irq_svc+0x3b/0x5c) from [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10)
> [59014.100437] [<c04c25a0>] (_raw_spin_unlock_irqrestore+0xc/0x10) from [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc])
> [59014.118267] [<bf9c2089>] (ath9k_rx_tasklet+0x290/0x490 [ath9k_htc]) from [<c0036d23>] (tasklet_action+0x3b/0x98)
> [59014.134132] [<c0036d23>] (tasklet_action+0x3b/0x98) from [<c0036709>] (__do_softirq+0x99/0x16c)
> [59014.147784] [<c0036709>] (__do_softirq+0x99/0x16c) from [<c00369f7>] (irq_exit+0x5b/0x5c)
> [59014.160653] [<c00369f7>] (irq_exit+0x5b/0x5c) from [<c000cfc3>] (handle_IRQ+0x37/0x78)
> [59014.173124] [<c000cfc3>] (handle_IRQ+0x37/0x78) from [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68)
> [59014.187225] [<c00085df>] (omap3_intc_handle_irq+0x5f/0x68) from [<c04c28db>](__irq_svc+0x3b/0x5c)
> This bug can be see with low performance board, such as uniprocessor beagle bone board.
> Signed-off-by: Yuwei Zheng <zhengyuwei@360.cn>
> Signed-off-by: Yuwei Zheng <yuweizheng@139.com>
>
> ---
> drivers/net/wireless/ath/ath9k/hif_usb.c | 61 +++++++++++++++++++++++---
> drivers/net/wireless/ath/ath9k/hif_usb.h | 6 +++
> drivers/net/wireless/ath/ath9k/htc.h | 18 ++++++++
> drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 46 +++++++++++++++++++
> drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 25 +++++++++++
> 5 files changed, 149 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index 8e7153b..9166f10 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -640,6 +640,7 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
> struct hif_device_usb *hif_dev =
> usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
> int ret;
> + int delay;
>
> if (!skb)
> return;
> @@ -658,7 +659,6 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
> default:
> goto resubmit;
> }
> -
> if (likely(urb->actual_length != 0)) {
> skb_put(skb, urb->actual_length);
> ath9k_hif_usb_rx_stream(hif_dev, skb);
> @@ -667,12 +667,18 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb)
> resubmit:
> skb_reset_tail_pointer(skb);
> skb_trim(skb, 0);
> -
> - usb_anchor_urb(urb, &hif_dev->rx_submitted);
> - ret = usb_submit_urb(urb, GFP_ATOMIC);
> - if (ret) {
> - usb_unanchor_urb(urb);
> - goto free;
> + if (atomic_read(&hif_dev->rx_urb_submit_delay) > 0) {
> + usb_anchor_urb(urb, &hif_dev->rx_delayed_submitted);
> + delay = atomic_read(&hif_dev->rx_urb_submit_delay);
> + schedule_delayed_work(&hif_dev->rx_submit_delayed_work,
> + usecs_to_jiffies(delay));
> + } else {
> + usb_anchor_urb(urb, &hif_dev->rx_submitted);
> + ret = usb_submit_urb(urb, GFP_ATOMIC);
> + if (ret) {
> + usb_unanchor_urb(urb);
> + goto free;
> + }
> }
>
> return;
> @@ -818,9 +824,43 @@ err:
> return -ENOMEM;
> }
>
> +static void rx_urb_delayed_submit_handler(struct work_struct *work)
> +{
> + struct hif_device_usb *hif_dev =
> + container_of(work,
> + struct hif_device_usb,
> + rx_submit_delayed_work.work);
> +
> + struct urb *urb = NULL;
> + struct sk_buff *skb = NULL;
> + int ret;
> + int loop_times = 0;
> +
> + while (true) {
> + loop_times++;
> + if (loop_times > (MAX_RX_URB_NUM))
> + atomic_add(ARC_RX_STEP, &hif_dev->rx_urb_submit_delay);
> +
> + urb = usb_get_from_anchor(&hif_dev->rx_delayed_submitted);
> + if (urb) {
> + skb = (struct sk_buff *)urb->context;
> + ret = usb_submit_urb(urb, GFP_KERNEL);
> + if (ret != 0) {
> + usb_unanchor_urb(urb);
> + dev_kfree_skb_any(skb);
> + urb->context = NULL;
> + }
> + } else {
> + break;
> + }
> + }
> +}
> +
> static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
> {
> usb_kill_anchored_urbs(&hif_dev->rx_submitted);
> + usb_kill_anchored_urbs(&hif_dev->rx_delayed_submitted);
> + flush_delayed_work(&hif_dev->rx_submit_delayed_work);
> }
>
> static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
> @@ -830,6 +870,8 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
> int i, ret;
>
> init_usb_anchor(&hif_dev->rx_submitted);
> + init_usb_anchor(&hif_dev->rx_delayed_submitted);
> +
> spin_lock_init(&hif_dev->rx_lock);
>
> for (i = 0; i < MAX_RX_URB_NUM; i++) {
> @@ -871,6 +913,11 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
> usb_free_urb(urb);
> }
>
> + /* add for adaptive rate control*/
> + atomic_set(&hif_dev->rx_urb_submit_delay, 0);
> + INIT_DELAYED_WORK(&hif_dev->rx_submit_delayed_work,
> + rx_urb_delayed_submit_handler);
> +
> return 0;
>
> err_submit:
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
> index 51496e7..2127e50 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.h
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
> @@ -41,6 +41,7 @@
> #define MAX_RX_URB_NUM 8
> #define MAX_RX_BUF_SIZE 16384
> #define MAX_PKT_NUM_IN_TRANSFER 10
> +#define ARC_RX_STEP 100 /* 100us */
>
> #define MAX_REG_OUT_URB_NUM 1
> #define MAX_REG_IN_URB_NUM 64
> @@ -98,9 +99,14 @@ struct hif_device_usb {
> struct hif_usb_tx tx;
> struct usb_anchor regout_submitted;
> struct usb_anchor rx_submitted;
> + struct usb_anchor rx_delayed_submitted; /* delayed submit anchor */
> struct usb_anchor reg_in_submitted;
> struct usb_anchor mgmt_submitted;
> struct sk_buff *remain_skb;
> +
> + struct delayed_work rx_submit_delayed_work;
> + atomic_t rx_urb_submit_delay; /*us*/
> +
> const char *fw_name;
> int rx_remain_len;
> int rx_pkt_len;
> diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
> index 9dde265..3061dfa 100644
> --- a/drivers/net/wireless/ath/ath9k/htc.h
> +++ b/drivers/net/wireless/ath/ath9k/htc.h
> @@ -331,6 +331,13 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
>
> #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
>
> +#define ARCRX_STAT_INC(c) \
> + (hif_dev->htc_handle->drv_priv->debug.arcrx_stats.c++)
> +#define ARCRX_STAT_ADD(c, a) \
> + (hif_dev->htc_handle->drv_priv->debug.arcrx_stats.c += a)
> +#define ARCRX_STAT_SET(c, a) \
> + (hif_dev->htc_handle->drv_priv->debug.arcrx_stats.c = a)
> +
> void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
> struct ath_rx_status *rs);
>
> @@ -352,11 +359,19 @@ struct ath_skbrx_stats {
> u32 skb_dropped;
> };
>
> +struct ath_arcrx_stats {
> + u32 arcrx_highwater;
> + u32 arcrx_lowwater;
> + u32 arcrx_watermark_triggered;
> + u32 arcrx_urb_submit_delay;
> +};
> +
> struct ath9k_debug {
> struct dentry *debugfs_phy;
> struct ath_tx_stats tx_stats;
> struct ath_rx_stats rx_stats;
> struct ath_skbrx_stats skbrx_stats;
> + struct ath_arcrx_stats arcrx_stats;
> };
>
> void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
> @@ -377,6 +392,9 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
>
> #define TX_QSTAT_INC(c) do { } while (0)
>
> +#define ARCRX_STAT_INC(c) do {} while (0)
> +#define ARCRX_STAT_ADD(c, a) do {} while (0)
> +#define ARCRX_STAT_SET(c, a) do {} while (0)
> static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
> struct ath_rx_status *rs)
> {
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> index 8cef1ed..ddc8f4f 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
> @@ -286,6 +286,48 @@ static const struct file_operations fops_skb_rx = {
> .llseek = default_llseek,
> };
>
> +static ssize_t read_file_arc_rx(struct file *file, char __user *user_buf,
> + size_t count, loff_t *ppos)
> +{
> + struct ath9k_htc_priv *priv = file->private_data;
> + char *buf;
> + unsigned int len = 0, size = 1500;
> + ssize_t retval = 0;
> +
> + buf = kzalloc(size, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
> +
> + len += scnprintf(buf + len, size - len,
> + "%20s : %10u\n", "High watermark",
> + priv->debug.arcrx_stats.arcrx_highwater);
> + len += scnprintf(buf + len, size - len,
> + "%20s : %10u\n", "Low watermark",
> + priv->debug.arcrx_stats.arcrx_lowwater);
> +
> + len += scnprintf(buf + len, size - len,
> + "%20s : %10u\n", "WM triggered",
> + priv->debug.arcrx_stats.arcrx_watermark_triggered);
> +
> + len += scnprintf(buf + len, size - len,
> + "%20s : %10u\n", "URB delay",
> + priv->debug.arcrx_stats.arcrx_urb_submit_delay);
> + if (len > size)
> + len = size;
> +
> + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
> + kfree(buf);
> +
> + return retval;
> +}
> +
> +static const struct file_operations fops_arc_rx = {
> + .read = read_file_arc_rx,
> + .open = simple_open,
> + .owner = THIS_MODULE,
> + .llseek = default_llseek,
> +};
> +
> static ssize_t read_file_slot(struct file *file, char __user *user_buf,
> size_t count, loff_t *ppos)
> {
> @@ -518,7 +560,11 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
> debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy,
> priv, &fops_skb_rx);
>
> + debugfs_create_file("arc_rx", S_IRUSR, priv->debug.debugfs_phy,
> + priv, &fops_arc_rx);
> +
> ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
> +
> ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
>
> debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> index a0f58e2..9d2dc33 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
> @@ -1061,7 +1061,27 @@ void ath9k_rx_tasklet(unsigned long data)
> unsigned long flags;
> struct ieee80211_hdr *hdr;
>
> + /* add for adaptive flow control*/
> + int looptimes = 0;
> + int highwatermark = ATH9K_HTC_RXBUF*3/4;
> + int lowwatermark = ATH9K_HTC_RXBUF/32;
> + unsigned int delay = 0;
> +
> + struct htc_target *htc = priv->htc;
> + struct hif_device_usb *hif_dev = htc->hif_dev;
> +
> + ARCRX_STAT_SET(arcrx_highwater, highwatermark);
> + ARCRX_STAT_SET(arcrx_lowwater, lowwatermark);
> +
> do {
> + looptimes++;
> + if (looptimes > highwatermark) {
> + delay = looptimes*ARC_RX_STEP;
> + atomic_set(&hif_dev->rx_urb_submit_delay, delay);
> + ARCRX_STAT_INC(arcrx_watermark_triggered);
> + ARCRX_STAT_SET(arcrx_urb_submit_delay, delay);
> + }
> +
> spin_lock_irqsave(&priv->rx.rxbuflock, flags);
> list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
> if (tmp_buf->in_process) {
> @@ -1072,6 +1092,11 @@ void ath9k_rx_tasklet(unsigned long data)
>
> if (rxbuf == NULL) {
> spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
> + if (looptimes < lowwatermark) {
> + atomic_set(&hif_dev->rx_urb_submit_delay, 0);
> + ARCRX_STAT_SET(arcrx_urb_submit_delay, 0);
> + }
> +
> break;
> }
>
>
--
Regards,
Oleksij
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]
^ permalink raw reply
* Re: [PATCH v2 08/17] {macvtap,tun}_get_user(): switch to iov_iter
From: Michael S. Tsirkin @ 2015-02-03 10:10 UTC (permalink / raw)
To: Al Viro; +Cc: David Miller, netdev, linux-kernel
In-Reply-To: <1416924151-28698-8-git-send-email-viro@ZenIV.linux.org.uk>
On Tue, Nov 25, 2014 at 02:02:22PM +0000, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
>
> allows to switch macvtap and tun from ->aio_write() to ->write_iter()
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
> drivers/net/macvtap.c | 44 +++++++++++++++++++++-----------------------
> drivers/net/tun.c | 44 ++++++++++++++++++++++++--------------------
> 2 files changed, 45 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index 8f80045..22b4cf2 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -640,12 +640,12 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
>
> /* Get packet from user space buffer */
> static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> - const struct iovec *iv, unsigned long total_len,
> - size_t count, int noblock)
> + struct iov_iter *from, int noblock)
> {
> int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN);
> struct sk_buff *skb;
> struct macvlan_dev *vlan;
> + unsigned long total_len = iov_iter_count(from);
> unsigned long len = total_len;
> int err;
> struct virtio_net_hdr vnet_hdr = { 0 };
> @@ -653,6 +653,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> int copylen = 0;
> bool zerocopy = false;
> size_t linear;
> + ssize_t n;
>
> if (q->flags & IFF_VNET_HDR) {
> vnet_hdr_len = q->vnet_hdr_sz;
> @@ -662,10 +663,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> goto err;
> len -= vnet_hdr_len;
>
> - err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
> - sizeof(vnet_hdr));
> - if (err < 0)
> + err = -EFAULT;
> + n = copy_from_iter(&vnet_hdr, sizeof(vnet_hdr), from);
> + if (n != sizeof(vnet_hdr))
> goto err;
> + iov_iter_advance(from, vnet_hdr_len - sizeof(vnet_hdr));
> if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
> vnet_hdr.csum_start + vnet_hdr.csum_offset + 2 >
> vnet_hdr.hdr_len)
> @@ -680,17 +682,16 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> if (unlikely(len < ETH_HLEN))
> goto err;
>
> - err = -EMSGSIZE;
> - if (unlikely(count > UIO_MAXIOV))
> - goto err;
> -
> if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
> + struct iov_iter i;
> +
> copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
> if (copylen > good_linear)
> copylen = good_linear;
> linear = copylen;
> - if (iov_pages(iv, vnet_hdr_len + copylen, count)
> - <= MAX_SKB_FRAGS)
> + i = *from;
> + iov_iter_advance(&i, copylen);
> + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
> zerocopy = true;
> }
>
> @@ -708,10 +709,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> goto err;
>
> if (zerocopy)
> - err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
> + err = zerocopy_sg_from_iter(skb, from);
> else {
> - err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
> - len);
> + err = skb_copy_datagram_from_iter(skb, 0, from, len);
> if (!err && m && m->msg_control) {
> struct ubuf_info *uarg = m->msg_control;
> uarg->callback(uarg, false);
> @@ -764,16 +764,12 @@ err:
> return err;
> }
>
> -static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
> - unsigned long count, loff_t pos)
> +static ssize_t macvtap_write_iter(struct kiocb *iocb, struct iov_iter *from)
> {
> struct file *file = iocb->ki_filp;
> - ssize_t result = -ENOLINK;
> struct macvtap_queue *q = file->private_data;
>
> - result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count,
> - file->f_flags & O_NONBLOCK);
> - return result;
> + return macvtap_get_user(q, NULL, from, file->f_flags & O_NONBLOCK);
> }
>
> /* Put packet to the user space buffer */
> @@ -1081,8 +1077,9 @@ static const struct file_operations macvtap_fops = {
> .open = macvtap_open,
> .release = macvtap_release,
> .read = new_sync_read,
> + .write = new_sync_write,
> .read_iter = macvtap_read_iter,
> - .aio_write = macvtap_aio_write,
> + .write_iter = macvtap_write_iter,
> .poll = macvtap_poll,
> .llseek = no_llseek,
> .unlocked_ioctl = macvtap_ioctl,
> @@ -1095,8 +1092,9 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,
> struct msghdr *m, size_t total_len)
> {
> struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
> - return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen,
> - m->msg_flags & MSG_DONTWAIT);
> + struct iov_iter from;
> + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
> + return macvtap_get_user(q, m, &from, m->msg_flags & MSG_DONTWAIT);
> }
>
> static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 405dfdf..4b743c6 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1012,28 +1012,29 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile,
>
> /* Get packet from user space buffer */
> static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> - void *msg_control, const struct iovec *iv,
> - size_t total_len, size_t count, int noblock)
> + void *msg_control, struct iov_iter *from,
> + int noblock)
> {
> struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
> struct sk_buff *skb;
> + size_t total_len = iov_iter_count(from);
> size_t len = total_len, align = NET_SKB_PAD, linear;
> struct virtio_net_hdr gso = { 0 };
> int good_linear;
> - int offset = 0;
> int copylen;
> bool zerocopy = false;
> int err;
> u32 rxhash;
> + ssize_t n;
>
> if (!(tun->flags & TUN_NO_PI)) {
> if (len < sizeof(pi))
> return -EINVAL;
> len -= sizeof(pi);
>
> - if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
> + n = copy_from_iter(&pi, sizeof(pi), from);
> + if (n != sizeof(pi))
> return -EFAULT;
> - offset += sizeof(pi);
> }
>
> if (tun->flags & TUN_VNET_HDR) {
> @@ -1041,7 +1042,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> return -EINVAL;
> len -= tun->vnet_hdr_sz;
>
> - if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
> + n = copy_from_iter(&gso, sizeof(gso), from);
> + if (n != sizeof(gso))
> return -EFAULT;
>
> if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
> @@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>
> if (gso.hdr_len > len)
> return -EINVAL;
> - offset += tun->vnet_hdr_sz;
> + iov_iter_advance(from, tun->vnet_hdr_sz);
> }
>
> if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
Hmm does copy_from_iter actually modify the iovec?
If so, won't this break aio on tun/macvtap, by
reversing the effect of
commit 6f26c9a7555e5bcca3560919db9b852015077dae
tun: fix tun_chr_aio_write so that aio works
?
Maybe we should change iovec_iter to avoid modifying the
underlying iovec?
> @@ -1063,6 +1065,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> good_linear = SKB_MAX_HEAD(align);
>
> if (msg_control) {
> + struct iov_iter i = *from;
> +
> /* There are 256 bytes to be copied in skb, so there is
> * enough room for skb expand head in case it is used.
> * The rest of the buffer is mapped from userspace.
> @@ -1071,7 +1075,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> if (copylen > good_linear)
> copylen = good_linear;
> linear = copylen;
> - if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
> + iov_iter_advance(&i, copylen);
> + if (iov_iter_npages(&i, INT_MAX) <= MAX_SKB_FRAGS)
> zerocopy = true;
> }
>
> @@ -1091,9 +1096,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> }
>
> if (zerocopy)
> - err = zerocopy_sg_from_iovec(skb, iv, offset, count);
> + err = zerocopy_sg_from_iter(skb, from);
> else {
> - err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len);
> + err = skb_copy_datagram_from_iter(skb, 0, from, len);
> if (!err && msg_control) {
> struct ubuf_info *uarg = msg_control;
> uarg->callback(uarg, false);
> @@ -1207,8 +1212,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> return total_len;
> }
>
> -static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
> - unsigned long count, loff_t pos)
> +static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
> {
> struct file *file = iocb->ki_filp;
> struct tun_struct *tun = tun_get(file);
> @@ -1218,10 +1222,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
> if (!tun)
> return -EBADFD;
>
> - tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count);
> -
> - result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count),
> - count, file->f_flags & O_NONBLOCK);
> + result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK);
>
> tun_put(tun);
> return result;
> @@ -1445,11 +1446,14 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,
> int ret;
> struct tun_file *tfile = container_of(sock, struct tun_file, socket);
> struct tun_struct *tun = __tun_get(tfile);
> + struct iov_iter from;
>
> if (!tun)
> return -EBADFD;
> - ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len,
> - m->msg_iovlen, m->msg_flags & MSG_DONTWAIT);
> +
> + iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
> + ret = tun_get_user(tun, tfile, m->msg_control, &from,
> + m->msg_flags & MSG_DONTWAIT);
> tun_put(tun);
> return ret;
> }
> @@ -2233,9 +2237,9 @@ static const struct file_operations tun_fops = {
> .owner = THIS_MODULE,
> .llseek = no_llseek,
> .read = new_sync_read,
> + .write = new_sync_write,
> .read_iter = tun_chr_read_iter,
> - .write = do_sync_write,
> - .aio_write = tun_chr_aio_write,
> + .write_iter = tun_chr_write_iter,
> .poll = tun_chr_poll,
> .unlocked_ioctl = tun_chr_ioctl,
> #ifdef CONFIG_COMPAT
> --
> 1.7.10.4
>
> --
> 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
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