netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: <davem@davemloft.net>
Cc: "Ian Campbell" <ian.campbell@citrix.com>, <wei.liu2@citrix.com>,
	"Dion Kant" <g.w.kant@hunenet.nl>, <xen-devel@lists.xen.org>,
	<netdev@vger.kernel.org>, <stable@vger.kernel.org>
Subject: [PATCH] xen-netfront: pull on receive skb may need to happen earlier
Date: Fri, 05 Jul 2013 10:32:41 +0100	[thread overview]
Message-ID: <51D6AED902000078000E2EA9@nat28.tlf.novell.com> (raw)
In-Reply-To: <20130704150137.GW7483@zion.uk.xensource.com>

Due to commit 3683243b ("xen-netfront: use __pskb_pull_tail to ensure
linear area is big enough on RX") xennet_fill_frags() may end up
filling MAX_SKB_FRAGS + 1 fragments in a receive skb, and only reduce
the fragment count subsequently via __pskb_pull_tail(). That's a
result of xennet_get_responses() allowing a maximum of one more slot to
be consumed (and intermediately transformed into a fragment) if the
head slot has a size less than or equal to RX_COPY_THRESHOLD.

Hence we need to adjust xennet_fill_frags() to pull earlier if we
reached the maximum fragment count - due to the described behavior of
xennet_get_responses() this guarantees that at least the first fragment
will get completely consumed, and hence the fragment count reduced.

In order to not needlessly call __pskb_pull_tail() twice, make the
original call conditional upon the pull target not having been reached
yet, and defer the newly added one as much as possible (an alternative
would have been to always call the function right before the call to
xennet_fill_frags(), but that would imply more frequent cases of
needing to call it twice).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: stable@vger.kernel.org (3.6 onwards)

--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -831,6 +831,15 @@ static RING_IDX xennet_fill_frags(struct
 			RING_GET_RESPONSE(&np->rx, ++cons);
 		skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
 
+		if (nr_frags == MAX_SKB_FRAGS) {
+			unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
+
+			BUG_ON(pull_to <= skb_headlen(skb));
+			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+			nr_frags = shinfo->nr_frags;
+		}
+		BUG_ON(nr_frags >= MAX_SKB_FRAGS);
+
 		__skb_fill_page_desc(skb, nr_frags,
 				     skb_frag_page(nfrag),
 				     rx->offset, rx->status);
@@ -929,7 +938,8 @@ static int handle_incoming_queue(struct 
 	while ((skb = __skb_dequeue(rxq)) != NULL) {
 		int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
-		__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+		if (pull_to > skb_headlen(skb))
+			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
 
 		/* Ethernet work: Delayed to here as it peeks the header. */
 		skb->protocol = eth_type_trans(skb, dev);

       reply	other threads:[~2013-07-05  9:32 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <8511913.uMAmUdIO30@eistomin.edss.local>
     [not found] ` <20130517085923.GC14401@zion.uk.xensource.com>
     [not found]   ` <51D57C1F.8070909@hunenet.nl>
     [not found]     ` <20130704150137.GW7483@zion.uk.xensource.com>
2013-07-05  9:32       ` Jan Beulich [this message]
2013-07-05 14:53         ` [PATCH] xen-netfront: pull on receive skb may need to happen earlier Wei Liu
2013-07-07  1:10           ` David Miller
2013-07-08  9:59           ` Jan Beulich
2013-07-08 12:16             ` Dion Kant
2013-07-08 12:41               ` Jan Beulich
2013-07-08 14:20             ` [Xen-devel] " Jan Beulich
2013-07-08 15:22               ` Eric Dumazet
2013-07-09  7:47                 ` Jan Beulich
2013-07-08 15:48               ` Wei Liu
2013-07-09  6:52                 ` Jan Beulich
2013-07-09 16:51                   ` Wei Liu
2013-07-10  6:58                     ` Jan Beulich
2013-07-10 10:04                       ` Wei Liu
2013-07-10 10:46                         ` Jan Beulich
2013-07-10 12:50                           ` Ian Campbell
2013-07-10 12:53                             ` Wei Liu
2013-07-10 13:58                             ` Jan Beulich
2013-07-10 13:19                       ` Eric Dumazet
2013-07-12  8:32               ` Wei Liu
2013-07-12  8:56                 ` Jan Beulich
2013-07-13 11:26                   ` Dion Kant

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51D6AED902000078000E2EA9@nat28.tlf.novell.com \
    --to=jbeulich@suse.com \
    --cc=davem@davemloft.net \
    --cc=g.w.kant@hunenet.nl \
    --cc=ian.campbell@citrix.com \
    --cc=netdev@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).