netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] fragment: add fast path
@ 2010-06-25  2:54 Changli Gao
  2010-06-29 13:54 ` Eric Dumazet
  0 siblings, 1 reply; 4+ messages in thread
From: Changli Gao @ 2010-06-25  2:54 UTC (permalink / raw)
  To: David Miller
  Cc: Alexey Kuznetsov, Pekka Savola (ipv6), James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, Eric Dumazet, netdev,
	Mitchell Erblich, Changli Gao

add fast path

As the fragments are sent in order in most of OSes, such as Windows, Darwin and
FreeBSD, it is likely the new fragments are at the end of the inet_frag_queue.
In the fast path, we check if the skb at the end of the inet_frag_queue is the
prev we expect.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
 include/net/inet_frag.h |    1 +
 net/ipv4/ip_fragment.c  |   12 ++++++++++++
 net/ipv6/reassembly.c   |   11 +++++++++++
 3 files changed, 24 insertions(+)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 39f2dc9..16ff29a 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -20,6 +20,7 @@ struct inet_frag_queue {
 	atomic_t		refcnt;
 	struct timer_list	timer;      /* when will this queue expire? */
 	struct sk_buff		*fragments; /* list of received fragments */
+	struct sk_buff		*fragments_tail;
 	ktime_t			stamp;
 	int			len;        /* total length of orig datagram */
 	int			meat;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 858d346..dbe8999 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -314,6 +314,7 @@ static int ip_frag_reinit(struct ipq *qp)
 	qp->q.len = 0;
 	qp->q.meat = 0;
 	qp->q.fragments = NULL;
+	qp->q.fragments_tail = NULL;
 	qp->iif = 0;
 
 	return 0;
@@ -386,6 +387,11 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 	 * in the chain of fragments so far.  We must know where to put
 	 * this fragment, right?
 	 */
+	prev = qp->q.fragments_tail;
+	if (!prev || FRAG_CB(prev)->offset < offset) {
+			next = NULL;
+			goto found;
+	}
 	prev = NULL;
 	for (next = qp->q.fragments; next != NULL; next = next->next) {
 		if (FRAG_CB(next)->offset >= offset)
@@ -393,6 +399,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 		prev = next;
 	}
 
+found:
 	/* We found where to put this one.  Check for overlap with
 	 * preceding fragment, and, if needed, align things so that
 	 * any overlaps are eliminated.
@@ -451,6 +458,8 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 
 	/* Insert this fragment in the chain of fragments. */
 	skb->next = next;
+	if (!next)
+		qp->q.fragments_tail = skb;
 	if (prev)
 		prev->next = skb;
 	else
@@ -504,6 +513,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 			goto out_nomem;
 
 		fp->next = head->next;
+		if (!fp->next)
+			qp->q.fragments_tail = fp;
 		prev->next = fp;
 
 		skb_morph(head, qp->q.fragments);
@@ -574,6 +585,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 	iph->tot_len = htons(len);
 	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
 	qp->q.fragments = NULL;
+	qp->q.fragments_tail = NULL;
 	return 0;
 
 out_nomem:
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 0b97230..b832f7b 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -333,6 +333,11 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
 	 * in the chain of fragments so far.  We must know where to put
 	 * this fragment, right?
 	 */
+	prev = fq->q.fragments_tail;
+	if (!prev || FRAG6_CB(prev)->offset < offset) {
+			next = NULL;
+			goto found;
+	}
 	prev = NULL;
 	for(next = fq->q.fragments; next != NULL; next = next->next) {
 		if (FRAG6_CB(next)->offset >= offset)
@@ -340,6 +345,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
 		prev = next;
 	}
 
+found:
 	/* We found where to put this one.  Check for overlap with
 	 * preceding fragment, and, if needed, align things so that
 	 * any overlaps are eliminated.
@@ -397,6 +403,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
 
 	/* Insert this fragment in the chain of fragments. */
 	skb->next = next;
+	if (!next)
+		fq->q.fragments_tail = skb;
 	if (prev)
 		prev->next = skb;
 	else
@@ -463,6 +471,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
 			goto out_oom;
 
 		fp->next = head->next;
+		if (!fp->next)
+			fq->q.fragments_tail = fp;
 		prev->next = fp;
 
 		skb_morph(head, fq->q.fragments);
@@ -549,6 +559,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
 	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
 	rcu_read_unlock();
 	fq->q.fragments = NULL;
+	fq->q.fragments_tail = NULL;
 	return 1;
 
 out_oversize:

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] fragment: add fast path
  2010-06-25  2:54 [PATCH v2] fragment: add fast path Changli Gao
@ 2010-06-29 13:54 ` Eric Dumazet
  2010-06-29 14:15   ` Changli Gao
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Dumazet @ 2010-06-29 13:54 UTC (permalink / raw)
  To: Changli Gao
  Cc: David Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, netdev, Mitchell Erblich

Le vendredi 25 juin 2010 à 10:54 +0800, Changli Gao a écrit :
> add fast path
> 
> As the fragments are sent in order in most of OSes, such as Windows, Darwin and
> FreeBSD, it is likely the new fragments are at the end of the inet_frag_queue.
> In the fast path, we check if the skb at the end of the inet_frag_queue is the
> prev we expect.
> 
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>

This patch is fine, but they are two indentation glitches.

> ----
>  include/net/inet_frag.h |    1 +
>  net/ipv4/ip_fragment.c  |   12 ++++++++++++
>  net/ipv6/reassembly.c   |   11 +++++++++++
>  3 files changed, 24 insertions(+)
> diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
> index 39f2dc9..16ff29a 100644
> --- a/include/net/inet_frag.h
> +++ b/include/net/inet_frag.h
> @@ -20,6 +20,7 @@ struct inet_frag_queue {
>  	atomic_t		refcnt;
>  	struct timer_list	timer;      /* when will this queue expire? */
>  	struct sk_buff		*fragments; /* list of received fragments */
> +	struct sk_buff		*fragments_tail;
>  	ktime_t			stamp;
>  	int			len;        /* total length of orig datagram */
>  	int			meat;
> diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
> index 858d346..dbe8999 100644
> --- a/net/ipv4/ip_fragment.c
> +++ b/net/ipv4/ip_fragment.c
> @@ -314,6 +314,7 @@ static int ip_frag_reinit(struct ipq *qp)
>  	qp->q.len = 0;
>  	qp->q.meat = 0;
>  	qp->q.fragments = NULL;
> +	qp->q.fragments_tail = NULL;
>  	qp->iif = 0;
>  
>  	return 0;
> @@ -386,6 +387,11 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
>  	 * in the chain of fragments so far.  We must know where to put
>  	 * this fragment, right?
>  	 */
> +	prev = qp->q.fragments_tail;
> +	if (!prev || FRAG_CB(prev)->offset < offset) {

strange indentation : one tab in excess

> +			next = NULL;
> +			goto found;
> +	}
>  	prev = NULL;
>  	for (next = qp->q.fragments; next != NULL; next = next->next) {
>  		if (FRAG_CB(next)->offset >= offset)
> @@ -393,6 +399,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
>  		prev = next;
>  	}
>  
> +found:
>  	/* We found where to put this one.  Check for overlap with
>  	 * preceding fragment, and, if needed, align things so that
>  	 * any overlaps are eliminated.
> @@ -451,6 +458,8 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
>  
>  	/* Insert this fragment in the chain of fragments. */
>  	skb->next = next;
> +	if (!next)
> +		qp->q.fragments_tail = skb;
>  	if (prev)
>  		prev->next = skb;
>  	else
> @@ -504,6 +513,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
>  			goto out_nomem;
>  
>  		fp->next = head->next;
> +		if (!fp->next)
> +			qp->q.fragments_tail = fp;
>  		prev->next = fp;
>  
>  		skb_morph(head, qp->q.fragments);
> @@ -574,6 +585,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
>  	iph->tot_len = htons(len);
>  	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
>  	qp->q.fragments = NULL;
> +	qp->q.fragments_tail = NULL;
>  	return 0;
>  
>  out_nomem:
> diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
> index 0b97230..b832f7b 100644
> --- a/net/ipv6/reassembly.c
> +++ b/net/ipv6/reassembly.c
> @@ -333,6 +333,11 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
>  	 * in the chain of fragments so far.  We must know where to put
>  	 * this fragment, right?
>  	 */
> +	prev = fq->q.fragments_tail;
> +	if (!prev || FRAG6_CB(prev)->offset < offset) {

same here : one tab in excess

> +			next = NULL;
> +			goto found;
> +	}
>  	prev = NULL;
>  	for(next = fq->q.fragments; next != NULL; next = next->next) {
>  		if (FRAG6_CB(next)->offset >= offset)
> @@ -340,6 +345,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
>  		prev = next;
>  	}
>  
> +found:
>  	/* We found where to put this one.  Check for overlap with
>  	 * preceding fragment, and, if needed, align things so that
>  	 * any overlaps are eliminated.
> @@ -397,6 +403,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
>  
>  	/* Insert this fragment in the chain of fragments. */
>  	skb->next = next;
> +	if (!next)
> +		fq->q.fragments_tail = skb;
>  	if (prev)
>  		prev->next = skb;
>  	else
> @@ -463,6 +471,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
>  			goto out_oom;
>  
>  		fp->next = head->next;
> +		if (!fp->next)
> +			fq->q.fragments_tail = fp;
>  		prev->next = fp;
>  
>  		skb_morph(head, fq->q.fragments);
> @@ -549,6 +559,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
>  	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
>  	rcu_read_unlock();
>  	fq->q.fragments = NULL;
> +	fq->q.fragments_tail = NULL;
>  	return 1;
>  
>  out_oversize:



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] fragment: add fast path
  2010-06-29 13:54 ` Eric Dumazet
@ 2010-06-29 14:15   ` Changli Gao
  2010-06-29 14:29     ` YOSHIFUJI Hideaki
  0 siblings, 1 reply; 4+ messages in thread
From: Changli Gao @ 2010-06-29 14:15 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Alexey Kuznetsov, Pekka Savola (ipv6), James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, netdev, Mitchell Erblich

On Tue, Jun 29, 2010 at 9:54 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 25 juin 2010 à 10:54 +0800, Changli Gao a écrit :
>> add fast path
>>
>> As the fragments are sent in order in most of OSes, such as Windows, Darwin and
>> FreeBSD, it is likely the new fragments are at the end of the inet_frag_queue.
>> In the fast path, we check if the skb at the end of the inet_frag_queue is the
>> prev we expect.
>>
>> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
>
> This patch is fine, but they are two indentation glitches.
>

Oh, Thanks. I'll fix them.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] fragment: add fast path
  2010-06-29 14:15   ` Changli Gao
@ 2010-06-29 14:29     ` YOSHIFUJI Hideaki
  0 siblings, 0 replies; 4+ messages in thread
From: YOSHIFUJI Hideaki @ 2010-06-29 14:29 UTC (permalink / raw)
  To: Changli Gao
  Cc: Eric Dumazet, David Miller, Alexey Kuznetsov, Pekka Savola (ipv6),
	James Morris, Patrick McHardy, netdev, Mitchell Erblich,
	YOSHIFUJI Hideaki

Changli Gao wrote:
> On Tue, Jun 29, 2010 at 9:54 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> Le vendredi 25 juin 2010 à 10:54 +0800, Changli Gao a écrit :
>>> add fast path
>>>
>>> As the fragments are sent in order in most of OSes, such as Windows, Darwin and
>>> FreeBSD, it is likely the new fragments are at the end of the inet_frag_queue.
>>> In the fast path, we check if the skb at the end of the inet_frag_queue is the
>>> prev we expect.
>>>
>>> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
>> This patch is fine, but they are two indentation glitches.
>>
> 
> Oh, Thanks. I'll fix them.

And, I think it is better not to just say it as "fast path"
because it does not sufficient.  Probably "fast path for
in-order fragments" or something like that.

Regards,

--yoshfuji

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-06-29 14:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-25  2:54 [PATCH v2] fragment: add fast path Changli Gao
2010-06-29 13:54 ` Eric Dumazet
2010-06-29 14:15   ` Changli Gao
2010-06-29 14:29     ` YOSHIFUJI Hideaki

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).