diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c --- a/sys/netinet/libalias/alias_db.c +++ b/sys/netinet/libalias/alias_db.c @@ -176,6 +176,7 @@ #endif static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead); +int LibAliasTime; /* Constants (note: constants are also defined @@ -820,7 +821,7 @@ if (lnk == NULL || *lnk == NULL) return; - if (la->timeStamp - (*lnk)->timestamp > (*lnk)->expire_time) { + if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire_time) { DeleteLink(lnk); if ((*lnk) == NULL) return; @@ -940,7 +941,7 @@ #endif lnk->flags = 0; lnk->pflags = 0; - lnk->timestamp = la->timeStamp; + lnk->timestamp = LibAliasTime; /* Expiration time */ switch (link_type) { @@ -1109,7 +1110,7 @@ CleanupLink(la, &lnk); if (lnk != NULL) - lnk->timestamp = la->timeStamp; + lnk->timestamp = LibAliasTime; /* Search for partially specified links. */ if (lnk == NULL && replace_partial_links) { @@ -1240,7 +1241,7 @@ CleanupLink(la, &lnk_fully_specified); if (lnk_fully_specified != NULL) { - lnk_fully_specified->timestamp = la->timeStamp; + lnk_fully_specified->timestamp = LibAliasTime; lnk = lnk_fully_specified; } else if (lnk_unknown_dst_port != NULL) lnk = lnk_unknown_dst_port; @@ -2101,24 +2102,45 @@ void HouseKeeping(struct libalias *la) { - struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire); -#ifndef _KERNEL - struct timeval tv; -#endif + static unsigned int packets = 0; + static unsigned int packet_limit = 1000; LIBALIAS_LOCK_ASSERT(la); + packets++; + /* - * Save system time (seconds) in global variable timeStamp for use - * by other functions. This is done so as not to unnecessarily - * waste timeline by making system calls. + * User space time/gettimeofday/... is very expensive. + * Kernel space cache trashing is unnecessary. + * + * Save system time (seconds) in global variable LibAliasTime + * for use by other functions. This is done so as not to + * unnecessarily waste timeline by making system calls. + * + * Reduce the amount of house keeping work substantially by + * sampling over the packets. */ + if (packets % packet_limit == 0) { + time_t now; + #ifdef _KERNEL - la->timeStamp = time_uptime; + now = time_uptime; #else - gettimeofday(&tv, NULL); - la->timeStamp = tv.tv_sec; + now = time(NULL); #endif - CleanupLink(la, &lnk); + if (now != LibAliasTime) { + /* retry three times a second */ + packet_limit = packets / 3; + packets = 0; + LibAliasTime = now; + } + + } + /* Do a cleanup for the first packets of the new second only */ + if (packets < (la->udpLinkCount + la->tcpLinkCount)) { + struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire); + + CleanupLink(la, &lnk); + } } /* Init the log file and enable logging */ @@ -2392,9 +2414,6 @@ LibAliasInit(struct libalias *la) { int i; -#ifndef _KERNEL - struct timeval tv; -#endif if (la == NULL) { #ifdef _KERNEL @@ -2414,10 +2433,9 @@ LIST_INSERT_HEAD(&instancehead, la, instancelist); #ifdef _KERNEL - la->timeStamp = time_uptime; + LibAliasTime = time_uptime; #else - gettimeofday(&tv, NULL); - la->timeStamp = tv.tv_sec; + LibAliasTime = time(NULL); #endif for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h --- a/sys/netinet/libalias/alias_local.h +++ b/sys/netinet/libalias/alias_local.h @@ -105,8 +105,6 @@ unsigned int fragmentIdLinkCount; unsigned int fragmentPtrLinkCount; unsigned int sockCount; - /* System time in seconds for current packet */ - int timeStamp; /* If equal to zero, DeleteLink() * will not remove permanent links */ int deleteAllLinks; @@ -206,6 +204,9 @@ /* Prototypes */ +/* System time in seconds for current packet */ +extern int LibAliasTime; + /* * SctpFunction prototypes * diff --git a/sys/netinet/libalias/alias_sctp.c b/sys/netinet/libalias/alias_sctp.c --- a/sys/netinet/libalias/alias_sctp.c +++ b/sys/netinet/libalias/alias_sctp.c @@ -298,10 +298,10 @@ #define SN_MAX_TIMER 600 #define SN_TIMER_QUEUE_SIZE SN_MAX_TIMER+2 -#define SN_I_T(la) (la->timeStamp + sysctl_init_timer) /**< INIT State expiration time in seconds */ -#define SN_U_T(la) (la->timeStamp + sysctl_up_timer) /**< UP State expiration time in seconds */ -#define SN_C_T(la) (la->timeStamp + sysctl_shutdown_timer) /**< CL State expiration time in seconds */ -#define SN_X_T(la) (la->timeStamp + sysctl_holddown_timer) /**< Wait after a shutdown complete in seconds */ +#define SN_I_T(la) (LibAliasTime + sysctl_init_timer) /**< INIT State expiration time in seconds */ +#define SN_U_T(la) (LibAliasTime + sysctl_up_timer) /**< UP State expiration time in seconds */ +#define SN_C_T(la) (LibAliasTime + sysctl_shutdown_timer) /**< CL State expiration time in seconds */ +#define SN_X_T(la) (LibAliasTime + sysctl_holddown_timer) /**< Wait after a shutdown complete in seconds */ /** @} * @defgroup sysctl SysCtl Variable and callback function declarations * @@ -667,9 +667,9 @@ for (i = 0; i < SN_TIMER_QUEUE_SIZE; i++) LIST_INIT(&la->sctpNatTimer.TimerQ[i]); #ifdef _KERNEL - la->sctpNatTimer.loc_time=time_uptime; /* la->timeStamp is not set yet */ + la->sctpNatTimer.loc_time=time_uptime; /* LibAliasTime is not set yet */ #else - la->sctpNatTimer.loc_time=la->timeStamp; + la->sctpNatTimer.loc_time=LibAliasTime; #endif la->sctpNatTimer.cur_loc = 0; la->sctpLinkCount = 0; @@ -2493,12 +2493,12 @@ struct sctp_nat_assoc *assoc; LIBALIAS_LOCK_ASSERT(la); - while(la->timeStamp >= la->sctpNatTimer.loc_time) { + while(LibAliasTime >= la->sctpNatTimer.loc_time) { while (!LIST_EMPTY(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc])) { assoc = LIST_FIRST(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc]); //SLIST_REMOVE_HEAD(&la->sctpNatTimer.TimerQ[la->sctpNatTimer.cur_loc], timer_Q); LIST_REMOVE(assoc, timer_Q); - if (la->timeStamp >= assoc->exp) { /* state expired */ + if (LibAliasTime >= assoc->exp) { /* state expired */ SN_LOG(((assoc->state == SN_CL) ? (SN_LOG_DEBUG) : (SN_LOG_INFO)), logsctperror("Timer Expired", assoc->g_vtag, assoc->state, SN_TO_NODIR)); RmSctpAssoc(la, assoc);