PERFORCE change 133826 for review
Andre Oppermann
andre at FreeBSD.org
Mon Jan 21 15:12:49 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=133826
Change 133826 by andre at andre_flirtbox on 2008/01/21 23:12:42
Touch up comments.
Affected files ...
.. //depot/projects/tcp_reass/netinet/tcp_reass.c#12 edit
Differences ...
==== //depot/projects/tcp_reass/netinet/tcp_reass.c#12 (text+ko) ====
@@ -73,7 +73,6 @@
* them in place. Only when trimming from the tail it actually frees them.
* Normally we don't get mbuf chains so this isn't too much of a concern
* right now. TODO.
- * Add a timer that cleans out the reassembly queue after 2MSL or so. TODO.
*/
#include "opt_inet.h"
@@ -105,7 +104,7 @@
static int tcp_reass_enabled = 1;
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, enable, CTLFLAG_WR,
&tcp_reass_enabled, 0,
- "Use of TCP Reassembly Queue");
+ "Enable/disable use of TCP Reassembly Queue");
static int tcp_reass_maxblocks = 0;
SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxblocks, CTLFLAG_RDTUN,
@@ -124,7 +123,11 @@
static void tcp_reass_merge(struct tcpcb *, struct trq *, struct trq *);
-/* Initialize TCP reassembly queue */
+uma_zone_t tcp_reass_zone;
+
+/*
+ * Adjust TCP reassembly zone limits when the nmbclusters zone changes.
+ */
static void
tcp_reass_zone_change(void *tag)
{
@@ -133,8 +136,9 @@
uma_zone_set_max(tcp_reass_zone, tcp_reass_maxblocks);
}
-uma_zone_t tcp_reass_zone;
-
+/*
+ * Initialize TCP reassembly zone on startup.
+ */
void
tcp_reass_init(void)
{
@@ -150,6 +154,9 @@
tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY);
}
+/*
+ * Insert segments into the reassembly queue.
+ */
int
tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
{
@@ -164,6 +171,7 @@
/*
* Call with th==NULL after becoming established to
* force pre-ESTABLISHED data up to user socket.
+ * XXX: Was used for T/TCP of which code remains.
*/
if (th == NULL) {
if (!TCPS_HAVEESTABLISHED(tp->t_state) ||
@@ -207,6 +215,7 @@
* holding on to too many segments (and thus running out of mbufs).
* Make sure to let the missing segment through which caused this
* queue.
+ *
* Count the gross space used by the mbufs in the reassembly queue
* and limit it to the free space in the socket buffer. This way
* the reassembly queue can never consume more mbuf space than the
@@ -214,6 +223,7 @@
* amount of kernel memory used. This effectively prevents mbuf
* exhaustion due to pathological traffic (one byte segments with
* a hole each time) on a single connection.
+ *
* Counting the gross mbuf space effectively sets the net data
* limit lower than the socket buffer would allow.
* It underestimates the effective free space in the socket buffer
@@ -408,9 +418,14 @@
insert:
/* Prepare to insert into block queue. */
- if (tp->rcv_nxt == th->th_seq)
+ if (tp->rcv_nxt == th->th_seq) {
+ /*
+ * Use temporary struct trq on the stack for missing
+ * segment to prevent blocking of all reassembly queues
+ * due to zone exhaustion.
+ */
tqen = &tqes;
- else {
+ } else {
tqen = uma_zalloc(tcp_reass_zone, (M_NOWAIT|M_ZERO));
if (tqen == NULL) {
tcpstat.tcps_rcvmemdrop++;
@@ -441,7 +456,8 @@
TAILQ_INSERT_HEAD(&tp->t_trq, tqen, trq_q);
/*
* Flush the reassembly queue after four times the
- * current retransmit interval.
+ * current retransmit interval measured from the
+ * arrival time of the first segment.
*/
tcp_timer_activate(tp, TT_REASS, tp->t_rxtcur * 4);
}
@@ -489,7 +505,11 @@
/* NB: sorwakeup_locked() does an implicit socket buffer unlock. */
sorwakeup_locked(so);
- /* Reset the flush timer if queue is not empty. */
+ /*
+ * Restart the reassembly queue flush timer after advancing
+ * the sequence space and if queue is not empty. Otherwise
+ * deactivate it.
+ */
if (!TAILQ_EMPTY(&tp->t_trq))
tcp_timer_activate(tp, TT_REASS, tp->t_rxtcur * 4);
else
@@ -503,6 +523,9 @@
#endif
}
+/*
+ * Merge one or more consecutive blocks together.
+ */
static void
tcp_reass_merge(struct tcpcb *tp, struct trq *tqe, struct trq *tqen)
{
@@ -512,7 +535,7 @@
int i;
KASSERT(tqe != NULL && tqen != NULL,
- ("%s: ", __func__));
+ ("%s: incomplete input", __func__));
KASSERT(SEQ_GEQ(tqe->trq_seq + tqe->trq_len, tqen->trq_seq),
("%s: blocks do not overlap, nothing to merge", __func__));
@@ -577,7 +600,7 @@
KASSERT(!TAILQ_EMPTY(&tp->t_trq),
("%s: ", __func__));
- /* The most recent block must appear first. */
+ /* The most recent block must appear first. RFC2018, Section 4. */
if (tp->t_trq_last != NULL) {
sack_seq = htonl(tp->t_trq_last->trq_seq);
bcopy((u_char *)&sack_seq, optp, sizeof(sack_seq));
@@ -589,7 +612,7 @@
nsacks++;
}
- /* Add the other less recent blocks. */
+ /* Add the other less recent blocks in ascending order. */
TAILQ_FOREACH(tqe, &tp->t_trq, trq_q) {
if (numsacks < 1)
break;
@@ -609,7 +632,7 @@
}
/*
- * Free the reassembly queue on tcpcb free and on general memory shortage.
+ * Free the reassembly queue on tcpcb disposal or on general memory shortage.
*/
void
tcp_reass_qfree(struct tcpcb *tp)
More information about the p4-projects
mailing list