Index: tcp_syncache.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_syncache.c,v retrieving revision 1.123 diff -u -p -r1.123 tcp_syncache.c --- tcp_syncache.c 3 Jul 2007 12:13:43 -0000 1.123 +++ tcp_syncache.c 21 Jul 2007 16:15:07 -0000 @@ -142,7 +142,6 @@ struct syncache_head { 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]; @@ -233,16 +232,10 @@ static MALLOC_DEFINE(M_SYNCACHE, "syncac #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) @@ -268,6 +261,7 @@ void syncache_init(void) { int i; + struct syncache_head *sch; tcp_syncache.cache_count = 0; tcp_syncache.hashsize = TCP_SYNCACHE_HASHSIZE; @@ -310,6 +304,17 @@ syncache_init(void) 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)); + } } /* @@ -339,8 +344,8 @@ syncache_insert(struct syncache *sc, str 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); @@ -390,11 +395,8 @@ syncache_timer(void *xsch) * then the RST will be sent by the time the remote * host does the SYN/ACK->ACK. */ - if (sc->sc_rxttime >= tick) { - if (sc->sc_rxttime < sch->sch_nextc) - sch->sch_nextc = sc->sc_rxttime; + if (sc->sc_rxttime >= tick) continue; - } if (sc->sc_rxmits > tcp_syncache.rexmt_limit) { if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) { @@ -409,11 +411,10 @@ syncache_timer(void *xsch) (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)); } /* @@ -995,7 +996,7 @@ syncache_add(struct in_conninfo *inc, st ("%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++; }