fragment: add fast path
Subsystems (3)
PATCH v2 1/1 fragment: add fast path
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.
----
include/net/inet_frag.h | 1 + net/ipv4/ip_fragment.c | 12 ++++++++++++ net/ipv6/reassembly.c | 11 +++++++++++ 3 files changed, 24 insertions(+)
include/net/inet_frag.h +1 -0
@@ -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;
net/ipv4/ip_fragment.c +12 -0
@@ -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:
net/ipv6/reassembly.c +11 -0
@@ -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:
Quoted 8 lines · 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 theinet_frag_queueis the prev we expect.Signed-off-by Changli Gao <[email protected]>
This patch is fine, but they are two indentation glitches.
Quoted 30 lines
----
include/net/inet_frag.h | 1 + net/ipv4/ip_fragment.c | 12 ++++++++++++ net/ipv6/reassembly.c | 11 +++++++++++ 3 files changed, 24 insertions(+)include/net/inet_frag.h +1
-0@@ -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;net/ipv4/ip_fragment.c +1
-0@@ -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 ;
net/ipv4/ip_fragment.c static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) · line 391
Quoted 5 lines
net/ipv4/ip_fragment.c +2
-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
Quoted 45 lines
net/ipv4/ip_fragment.c +9
-0+ 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:net/ipv6/reassembly.c +0
-0
net/ipv6/reassembly.c static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, · line 337
Quoted 5 lines
net/ipv6/reassembly.c +2
-0@@ -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
Quoted 40 lines
net/ipv6/reassembly.c +9
-0+ 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:
Quoted 12 lines · Eric Dumazet
Quoted 8 lines · 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 theinet_frag_queueis the prev we expect.Signed-off-by Changli Gao <[email protected]>This patch is fine, but they are two indentation glitches.
Oh, Thanks. I'll fix them.
Signature · 2 lines
Regards, Changli Gao([email protected])
Quoted 9 lines · Changli Gao
Quoted 8 lines · Eric Dumazet
Quoted 7 lines · 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 theinet_frag_queueis the prev we expect.
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Changli Gao <[email protected]>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