git: 8b7b86fa6fe0 - stable/12 - libalias: Promote per instance global variable timeStamp

Lutz Donnerhacke donner at FreeBSD.org
Tue Jul 6 07:11:54 UTC 2021


The branch stable/12 has been updated by donner:

URL: https://cgit.FreeBSD.org/src/commit/?id=8b7b86fa6fe0761b7a7dc7034c078fdbfa58c4d9

commit 8b7b86fa6fe0761b7a7dc7034c078fdbfa58c4d9
Author:     Lutz Donnerhacke <donner at FreeBSD.org>
AuthorDate: 2021-05-25 07:07:21 +0000
Commit:     Lutz Donnerhacke <donner at FreeBSD.org>
CommitDate: 2021-07-06 07:07:50 +0000

    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)
---
 sys/netinet/libalias/alias_db.c    | 60 +++++++++++++++++++++++++-------------
 sys/netinet/libalias/alias_local.h |  5 ++--
 sys/netinet/libalias/alias_sctp.c  | 16 +++++-----
 3 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index d3018a400022..2759c5170b27 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 2dd57e496f7e..96a0718eae1f 100644
--- a/sys/netinet/libalias/alias_sctp.c
+++ b/sys/netinet/libalias/alias_sctp.c
@@ -297,10 +297,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
  *
@@ -642,9 +642,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;
@@ -2468,12 +2468,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);


More information about the dev-commits-src-all mailing list