aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ananyev <konstantin.ananyev@intel.com>2017-06-11 13:22:41 +0100
committerKonstantin Ananyev <konstantin.ananyev@intel.com>2017-06-11 13:23:51 +0100
commit2c33ba7b74d4e61a29db34c650d96eef9134f6a7 (patch)
tree02c32f69a9fcb3a2add74efe01b3786a2a473049
parente49446d6c07fd64b2b40d6a9a6ccec7c06a88366 (diff)
libtle_l4p: fix at termination tcp stream not always cleanup it's send queue.
Change-Id: I8ab713c98712fafe2550a6954224ebc741cf9029 Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
-rw-r--r--lib/libtle_l4p/tcp_ctl.h14
-rw-r--r--lib/libtle_l4p/tcp_rxtx.c17
2 files changed, 24 insertions, 7 deletions
diff --git a/lib/libtle_l4p/tcp_ctl.h b/lib/libtle_l4p/tcp_ctl.h
index f7e70e3..32faaa2 100644
--- a/lib/libtle_l4p/tcp_ctl.h
+++ b/lib/libtle_l4p/tcp_ctl.h
@@ -55,8 +55,16 @@ calc_rx_wnd(const struct tle_tcp_stream *s, uint32_t scale)
return _rte_ring_get_mask(s->rx.q) << scale;
}
+/* empty stream's send queue */
+static inline void
+empty_tq(struct tle_tcp_stream *s)
+{
+ s->tx.q->cons.head = s->tx.q->cons.tail;
+ empty_mbuf_ring(s->tx.q);
+}
+
/* empty stream's receive queue */
-static void
+static inline void
empty_rq(struct tle_tcp_stream *s)
{
empty_mbuf_ring(s->rx.q);
@@ -64,7 +72,7 @@ empty_rq(struct tle_tcp_stream *s)
}
/* empty stream's listen queue */
-static void
+static inline void
empty_lq(struct tle_tcp_stream *s, struct stbl *st)
{
uint32_t i, n;
@@ -117,7 +125,7 @@ tcp_stream_reset(struct tle_ctx *ctx, struct tle_tcp_stream *s)
}
/* empty TX queue */
- empty_mbuf_ring(s->tx.q);
+ empty_tq(s);
/*
* mark the stream as free again.
diff --git a/lib/libtle_l4p/tcp_rxtx.c b/lib/libtle_l4p/tcp_rxtx.c
index 7429bf0..a1c7d09 100644
--- a/lib/libtle_l4p/tcp_rxtx.c
+++ b/lib/libtle_l4p/tcp_rxtx.c
@@ -1080,8 +1080,17 @@ rx_fin(struct tle_tcp_stream *s, uint32_t state,
return -ENOBUFS;
}
- /* process ack here */
- rx_ackdata(s, si->ack);
+ /*
+ * fast-path: all data & FIN was already sent out
+ * and now is acknowledged.
+ */
+ if (s->tcb.snd.fss == s->tcb.snd.nxt &&
+ si->ack == (uint32_t)s->tcb.snd.nxt) {
+ s->tcb.snd.una = s->tcb.snd.fss;
+ empty_tq(s);
+ /* conventional ACK processiing */
+ } else
+ rx_ackdata(s, si->ack);
/* some fragments still missing */
if (seq + plen != s->tcb.rcv.nxt) {
@@ -1470,7 +1479,7 @@ rx_ackfin(struct tle_tcp_stream *s)
uint32_t state;
s->tcb.snd.una = s->tcb.snd.fss;
- empty_mbuf_ring(s->tx.q);
+ empty_tq(s);
state = s->tcb.state;
if (state == TCP_ST_LAST_ACK)
@@ -1656,7 +1665,7 @@ rx_stream(struct tle_tcp_stream *s, uint32_t ts,
* and now is acknowledged.
*/
if (s->tcb.snd.fss == s->tcb.snd.nxt &&
- tack.ack == (uint32_t) s->tcb.snd.nxt)
+ tack.ack == (uint32_t)s->tcb.snd.nxt)
rx_ackfin(s);
else
rx_process_ack(s, ts, &tack);