aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLutz Donnerhacke <donner@FreeBSD.org>2021-05-25 07:07:21 +0000
committerLutz Donnerhacke <donner@FreeBSD.org>2021-07-06 06:55:53 +0000
commit390866d47effe8f5a11f3f852ae891f14dd4d15c (patch)
treef7de05b7d6944e1e3ab77bbce70d4254df5a0d5a
parent69965155a5c24c7794e61fc5a91ca3ba23468f50 (diff)
downloadsrc-390866d47effe8f5a11f3f852ae891f14dd4d15c.tar.gz
src-390866d47effe8f5a11f3f852ae891f14dd4d15c.zip
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 Differential Revision: https://reviews.freebsd.org/D30566 (cherry picked from commit ef828d39be8e4b6d922db080ed41611702dec56d)
-rw-r--r--sys/netinet/libalias/alias_db.c60
-rw-r--r--sys/netinet/libalias/alias_local.h5
-rw-r--r--sys/netinet/libalias/alias_sctp.c16
3 files changed, 50 insertions, 31 deletions
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 1b1cddc0b6fd..d42948efad8d 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -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++)
diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h
index 8e2fe88fe620..f1b40f0438da 100644
--- a/sys/netinet/libalias/alias_local.h
+++ b/sys/netinet/libalias/alias_local.h
@@ -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
*
diff --git a/sys/netinet/libalias/alias_sctp.c b/sys/netinet/libalias/alias_sctp.c
index 719af1512a05..b88ad2b28ca8 100644
--- a/sys/netinet/libalias/alias_sctp.c
+++ b/sys/netinet/libalias/alias_sctp.c
@@ -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);