libalias: Promote per instance global variable timeStamp
Summary: - Use LibAliasTime as a real global variable for central timekeeping. - Reduce number of syscalls in user space considerably. - Dynamically adjust the packet counters to match the second resolution. - Only check the first few packets after a time increase for expiry. Discussed with: hselasky MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D30566
This commit is contained in:
parent
3fd20a79e7
commit
ef828d39be
@ -176,6 +176,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
|
||||
int LibAliasTime;
|
||||
|
||||
/*
|
||||
Constants (note: constants are also defined
|
||||
@ -820,7 +821,7 @@ CleanupLink(struct libalias *la, struct alias_link **lnk)
|
||||
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 @@ AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr,
|
||||
#endif
|
||||
lnk->flags = 0;
|
||||
lnk->pflags = 0;
|
||||
lnk->timestamp = la->timeStamp;
|
||||
lnk->timestamp = LibAliasTime;
|
||||
|
||||
/* Expiration time */
|
||||
switch (link_type) {
|
||||
@ -1109,7 +1110,7 @@ _FindLinkOut(struct libalias *la, struct in_addr src_addr,
|
||||
|
||||
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 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr,
|
||||
|
||||
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 @@ SetDestCallId(struct alias_link *lnk, u_int16_t cid)
|
||||
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 @@ struct libalias *
|
||||
LibAliasInit(struct libalias *la)
|
||||
{
|
||||
int i;
|
||||
#ifndef _KERNEL
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
if (la == NULL) {
|
||||
#ifdef _KERNEL
|
||||
@ -2414,10 +2433,9 @@ LibAliasInit(struct libalias *la)
|
||||
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++)
|
||||
|
@ -105,8 +105,6 @@ struct libalias {
|
||||
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 @@ struct libalias {
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
/* System time in seconds for current packet */
|
||||
extern int LibAliasTime;
|
||||
|
||||
/*
|
||||
* SctpFunction prototypes
|
||||
*
|
||||
|
@ -298,10 +298,10 @@ static MALLOC_DEFINE(M_SCTPNAT, "sctpnat", "sctp nat dbs");
|
||||
#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 @@ AliasSctpInit(struct libalias *la)
|
||||
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 @@ sctp_CheckTimers(struct libalias *la)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user