--- /usr/src/sys.old/netinet/tcp_syncache.c 2007-06-24 20:17:31.000000000 -0500 +++ /usr/src/sys/netinet/tcp_syncache.c 2007-07-09 00:46:18.000000000 -0500 @@ -149,7 +150,6 @@ struct mtx sch_mtx; TAILQ_HEAD(sch_head, syncache) sch_bucket; struct callout sch_timer; - int sch_nextc; u_int sch_length; u_int sch_oddeven; u_int32_t sch_secbits_odd[SYNCOOKIE_SECRET_SIZE]; @@ -240,16 +240,10 @@ #define ENDPTS6_EQ(a, b) (memcmp(a, b, sizeof(*a)) == 0) -#define SYNCACHE_TIMEOUT(sc, sch, co) do { \ +#define SYNCACHE_TIMEOUT(sc) do { \ (sc)->sc_rxmits++; \ (sc)->sc_rxttime = ticks + \ TCPTV_RTOBASE * tcp_backoff[(sc)->sc_rxmits - 1]; \ - if ((sch)->sch_nextc > (sc)->sc_rxttime) \ - (sch)->sch_nextc = (sc)->sc_rxttime; \ - if (!TAILQ_EMPTY(&(sch)->sch_bucket) && !(co)) \ - callout_reset(&(sch)->sch_timer, \ - (sch)->sch_nextc - ticks, \ - syncache_timer, (void *)(sch)); \ } while (0) #define SCH_LOCK(sch) mtx_lock(&(sch)->sch_mtx) @@ -275,6 +269,7 @@ syncache_init(void) { int i; + struct syncache_head *sch; tcp_syncache.cache_count = 0; tcp_syncache.hashsize = TCP_SYNCACHE_HASHSIZE; @@ -317,6 +312,17 @@ tcp_syncache.zone = uma_zcreate("syncache", sizeof(struct syncache), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); uma_zone_set_max(tcp_syncache.zone, tcp_syncache.cache_limit); + + /* + * Start the syncache head timers running. They each run ten times + * a second, and are spread out so that they are not all running on + * the same clock tick. + */ + for (i = 0; i < tcp_syncache.hashsize; i++) { + sch = &tcp_syncache.hashbase[i]; + callout_reset(&(sch)->sch_timer, i * (hz / 10), + syncache_timer, (void *)(sch)); + } } /* @@ -346,8 +352,8 @@ TAILQ_INSERT_HEAD(&sch->sch_bucket, sc, sc_hash); sch->sch_length++; - /* Reinitialize the bucket row's timer. */ - SYNCACHE_TIMEOUT(sc, sch, 1); + /* Set the retransmit timer for this socket. */ + SYNCACHE_TIMEOUT(sc); SCH_UNLOCK(sch); @@ -398,8 +404,6 @@ * host does the SYN/ACK->ACK. */ if (sc->sc_rxttime >= tick) { - if (sc->sc_rxttime < sch->sch_nextc) - sch->sch_nextc = sc->sc_rxttime; continue; } @@ -416,11 +420,10 @@ (void) syncache_respond(sc); tcpstat.tcps_sc_retransmitted++; - SYNCACHE_TIMEOUT(sc, sch, 0); + SYNCACHE_TIMEOUT(sc); } - if (!TAILQ_EMPTY(&(sch)->sch_bucket)) - callout_reset(&(sch)->sch_timer, (sch)->sch_nextc - tick, - syncache_timer, (void *)(sch)); + callout_reset(&(sch)->sch_timer, hz / 10, + syncache_timer, (void *)(sch)); } /* @@ -1007,7 +1010,7 @@ ("%s: label not initialized", __func__)); #endif if (syncache_respond(sc) == 0) { - SYNCACHE_TIMEOUT(sc, sch, 1); + SYNCACHE_TIMEOUT(sc); tcpstat.tcps_sndacks++; tcpstat.tcps_sndtotal++; }