From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Dumazet Subject: Re: [PATCH 1/2] net: Stop decapitating clones that have a head_frag Date: Thu, 03 May 2012 05:56:41 +0200 Message-ID: <1336017401.12425.2.camel@edumazet-glaptop> References: <20120503033018.5482.89902.stgit@gitlad.jf.intel.com> <20120503033856.5482.70122.stgit@gitlad.jf.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Cc: netdev@vger.kernel.org, davem@davemloft.net, Eric Dumazet , Jeff Kirsher To: Alexander Duyck Return-path: Received: from mail-wi0-f178.google.com ([209.85.212.178]:40920 "EHLO mail-wi0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753882Ab2ECD4q (ORCPT ); Wed, 2 May 2012 23:56:46 -0400 Received: by wibhr7 with SMTP id hr7so233474wib.1 for ; Wed, 02 May 2012 20:56:45 -0700 (PDT) In-Reply-To: <20120503033856.5482.70122.stgit@gitlad.jf.intel.com> Sender: netdev-owner@vger.kernel.org List-ID: On Wed, 2012-05-02 at 20:38 -0700, Alexander Duyck wrote: > This change is meant ot prevent stealing the skb->head to use as a page in > the event that the skb->head was cloned. This allows the other clones to > track each other via shinfo->dataref. > > Without this we break down to two methods for tracking the reference count, > one being dataref, the other being the page count. As a result it becomes > difficult to track how many references there are to skb->head. > > Signed-off-by: Alexander Duyck > Cc: Eric Dumazet > Cc: Jeff Kirsher > --- > > net/core/skbuff.c | 2 +- > net/ipv4/tcp_input.c | 9 ++------- > 2 files changed, 3 insertions(+), 8 deletions(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index 52ba2b5..8703754 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -1699,7 +1699,7 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe, > struct splice_pipe_desc *spd, struct sock *sk) > { > int seg; > - bool head_is_linear = !skb->head_frag; > + bool head_is_linear = !skb->head_frag || skb_cloned(skb); > Can you chose a better name than head_is_linear maybe ? > /* map the linear part : > * If skb->head_frag is set, this 'linear' part is backed > diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c > index 2f696ef..c6f78e2 100644 > --- a/net/ipv4/tcp_input.c > +++ b/net/ipv4/tcp_input.c > @@ -4589,7 +4589,7 @@ copyfrags: > to->data_len += len; > goto merge; > } > - if (from->head_frag) { > + if (from->head_frag && !skb_cloned(from)) { > struct page *page; > unsigned int offset; > > @@ -4599,12 +4599,7 @@ copyfrags: > offset = from->data - (unsigned char *)page_address(page); > skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, > page, offset, skb_headlen(from)); > - > - if (skb_cloned(from)) > - get_page(page); > - else > - *fragstolen = true; > - > + *fragstolen = true; > delta = len; /* we dont know real truesize... */ > goto copyfrags; > } Thanks