diff options
| author | Jon Grimm <jgrimm@touki.austin.ibm.com> | 2003-04-10 00:55:29 -0500 |
|---|---|---|
| committer | Sridhar Samudrala <sri@us.ibm.com> | 2003-04-10 00:55:29 -0500 |
| commit | 293f0d65e085ee73ef91c2c5ad67f765fc06ed38 (patch) | |
| tree | 37faf6c425199a483b6a2d3d74b340a97f280e9d /net/sctp/ulpqueue.c | |
| parent | 276829d1f507167bdfd474de2c870bd94b47cd5f (diff) | |
[SCTP] short-circuit reassembly & ordering for best case.
Short circuit normal case. First check if the chunk belongs at the
end of the queue. If so, don't bother walking the entire list, just
just put at end.
Diffstat (limited to 'net/sctp/ulpqueue.c')
| -rw-r--r-- | net/sctp/ulpqueue.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 4cc69b211c84..ae5cd8fc3b27 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -253,6 +253,21 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, tsn = event->sndrcvinfo.sinfo_tsn; + /* See if it belongs at the end. */ + pos = skb_peek_tail(&ulpq->reasm); + if (!pos) { + __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); + return; + } + + /* Short circuit just dropping it at the end. */ + cevent = sctp_skb2event(pos); + ctsn = cevent->sndrcvinfo.sinfo_tsn; + if (TSN_lt(ctsn, tsn)) { + __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); + return; + } + /* Find the right place in this list. We store them by TSN. */ skb_queue_walk(&ulpq->reasm, pos) { cevent = sctp_skb2event(pos); @@ -262,12 +277,9 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, break; } - /* If the queue is empty, we have a different function to call. */ - if (skb_peek(&ulpq->reasm)) - __skb_insert(sctp_event2skb(event), pos->prev, pos, - &ulpq->reasm); - else - __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); + /* Insert before pos. */ + __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->reasm); + } /* Helper function to return an event corresponding to the reassembled @@ -592,8 +604,27 @@ static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq, __u16 sid, csid; __u16 ssn, cssn; + pos = skb_peek_tail(&ulpq->lobby); + if (!pos) { + __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); + return; + } + sid = event->sndrcvinfo.sinfo_stream; ssn = event->sndrcvinfo.sinfo_ssn; + + cevent = (struct sctp_ulpevent *) pos->cb; + csid = cevent->sndrcvinfo.sinfo_stream; + cssn = cevent->sndrcvinfo.sinfo_ssn; + if (sid > csid) { + __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); + return; + } + + if ((sid == csid) && SSN_lt(cssn, ssn)) { + __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); + return; + } /* Find the right place in this list. We store them by * stream ID and then by SSN. @@ -609,12 +640,10 @@ static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq, break; } - /* If the queue is empty, we have a different function to call. */ - if (skb_peek(&ulpq->lobby)) - __skb_insert(sctp_event2skb(event), pos->prev, pos, - &ulpq->lobby); - else - __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); + + /* Insert before pos. */ + __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->lobby); + } static inline struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq, |
