7ac772
From d905fd132a536e9149c91816704500c659e154f0 Mon Sep 17 00:00:00 2001
7ac772
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
7ac772
Date: Tue, 26 Nov 2019 16:32:03 +0100
7ac772
Subject: [PATCH] Changed log lock from 'quick' to 'basic' because this is an
7ac772
 I/O lock.
7ac772
7ac772
We cannot use a 'quick' lock (i.e. lock spinning on the CPU) for the log
7ac772
lock because it can wait a lot on I/Os. Using a 'quick' lock leads to
7ac772
eating the CPU for no good reason.
7ac772
7ac772
Example of 'pidstat' output when using various locks for log_lock:
7ac772
7ac772
- 'quick' lock and slow log file system (tail -f on the log file on XFS on RHEL 8)
7ac772
7ac772
04:15:11 PM   UID      TGID       TID    %usr %system    %CPU CPU  Command
7ac772
04:15:21 PM   998     16431         -  100.00    4.20  100.00   2  unbound
7ac772
04:15:21 PM   998         -     16431   31.00    1.00   32.00   2  |__unbound
7ac772
04:15:21 PM   998         -     16432   31.30    0.80   32.10   0  |__unbound
7ac772
04:15:21 PM   998         -     16433   30.20    1.40   31.60   1  |__unbound
7ac772
04:15:21 PM   998         -     16434   30.70    1.00   31.70   3  |__unbound
7ac772
7ac772
- 'quick' lock and log file system being fast
7ac772
7ac772
04:15:40 PM   UID      TGID       TID    %usr %system   %CPU CPU  Command
7ac772
04:15:50 PM   998     16431         -   10.00    1.60  11.60   1  unbound
7ac772
04:15:50 PM   998         -     16431    2.50    0.50   3.00   1  |__unbound
7ac772
04:15:50 PM   998         -     16432    2.30    0.40   2.70   3  |__unbound
7ac772
04:15:50 PM   998         -     16433    2.70    0.30   3.00   0  |__unbound
7ac772
04:15:50 PM   998         -     16434    2.60    0.40   3.00   2  |__unbound
7ac772
7ac772
- 'basic' lock (this commit) and slow log file system (tail -f on the log file on XFS on RHEL 8)
7ac772
7ac772
04:29:48 PM   UID      TGID       TID    %usr %system   %CPU CPU  Command
7ac772
04:29:58 PM   998     11632         -    7.10   14.10  21.20   3  unbound
7ac772
04:29:58 PM   998         -     11632    1.70    3.20   4.90   3  |__unbound
7ac772
04:29:58 PM   998         -     11633    1.60    3.30   4.90   1  |__unbound
7ac772
04:29:58 PM   998         -     11634    2.00    4.10   6.10   1  |__unbound
7ac772
04:29:58 PM   998         -     11635    1.90    3.50   5.40   1  |__unbound
7ac772
7ac772
We can see in the above example, when 'basic' lock is used, that CPU
7ac772
isn't consumed when log file system is slow.
7ac772
7ac772
Another reproducer scenario: put the log file on a NFS share with 'sync'
7ac772
option.
7ac772
---
7ac772
 util/log.c | 30 +++++++++++++++---------------
7ac772
 1 file changed, 15 insertions(+), 15 deletions(-)
7ac772
7ac772
diff --git a/util/log.c b/util/log.c
7ac772
index c14b458..5b31854 100644
7ac772
--- a/util/log.c
7ac772
+++ b/util/log.c
7ac772
@@ -70,7 +70,7 @@ static int key_created = 0;
7ac772
 static ub_thread_key_type logkey;
7ac772
 #ifndef THREADS_DISABLED
7ac772
 /** pthread mutex to protect FILE* */
7ac772
-static lock_quick_type log_lock;
7ac772
+static lock_basic_type log_lock;
7ac772
 #endif
7ac772
 /** the identity of this executable/process */
7ac772
 static const char* ident="unbound";
7ac772
@@ -90,18 +90,18 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
7ac772
 	if(!key_created) {
7ac772
 		key_created = 1;
7ac772
 		ub_thread_key_create(&logkey, NULL);
7ac772
-		lock_quick_init(&log_lock);
7ac772
+		lock_basic_init(&log_lock);
7ac772
 	}
7ac772
-	lock_quick_lock(&log_lock);
7ac772
+	lock_basic_lock(&log_lock);
7ac772
 	if(logfile 
7ac772
 #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS)
7ac772
 	|| logging_to_syslog
7ac772
 #endif
7ac772
 	) {
7ac772
-		lock_quick_unlock(&log_lock); /* verbose() needs the lock */
7ac772
+		lock_basic_unlock(&log_lock); /* verbose() needs the lock */
7ac772
 		verbose(VERB_QUERY, "switching log to %s", 
7ac772
 			use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"));
7ac772
-		lock_quick_lock(&log_lock);
7ac772
+		lock_basic_lock(&log_lock);
7ac772
 	}
7ac772
 	if(logfile && logfile != stderr) {
7ac772
 		FILE* cl = logfile;
7ac772
@@ -119,7 +119,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
7ac772
 		 * chroot and no longer be able to access dev/log and so on */
7ac772
 		openlog(ident, LOG_NDELAY, LOG_DAEMON);
7ac772
 		logging_to_syslog = 1;
7ac772
-		lock_quick_unlock(&log_lock);
7ac772
+		lock_basic_unlock(&log_lock);
7ac772
 		return;
7ac772
 	}
7ac772
 #elif defined(UB_ON_WINDOWS)
7ac772
@@ -128,13 +128,13 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
7ac772
 	}
7ac772
 	if(use_syslog) {
7ac772
 		logging_to_syslog = 1;
7ac772
-		lock_quick_unlock(&log_lock);
7ac772
+		lock_basic_unlock(&log_lock);
7ac772
 		return;
7ac772
 	}
7ac772
 #endif /* HAVE_SYSLOG_H */
7ac772
 	if(!filename || !filename[0]) {
7ac772
 		logfile = stderr;
7ac772
-		lock_quick_unlock(&log_lock);
7ac772
+		lock_basic_unlock(&log_lock);
7ac772
 		return;
7ac772
 	}
7ac772
 	/* open the file for logging */
7ac772
@@ -143,7 +143,7 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
7ac772
 		filename += strlen(chrootdir);
7ac772
 	f = fopen(filename, "a");
7ac772
 	if(!f) {
7ac772
-		lock_quick_unlock(&log_lock);
7ac772
+		lock_basic_unlock(&log_lock);
7ac772
 		log_err("Could not open logfile %s: %s", filename, 
7ac772
 			strerror(errno));
7ac772
 		return;
7ac772
@@ -153,14 +153,14 @@ log_init(const char* filename, int use_syslog, const char* chrootdir)
7ac772
 	setvbuf(f, NULL, (int)_IOLBF, 0);
7ac772
 #endif
7ac772
 	logfile = f;
7ac772
-	lock_quick_unlock(&log_lock);
7ac772
+	lock_basic_unlock(&log_lock);
7ac772
 }
7ac772
 
7ac772
 void log_file(FILE *f)
7ac772
 {
7ac772
-	lock_quick_lock(&log_lock);
7ac772
+	lock_basic_lock(&log_lock);
7ac772
 	logfile = f;
7ac772
-	lock_quick_unlock(&log_lock);
7ac772
+	lock_basic_unlock(&log_lock);
7ac772
 }
7ac772
 
7ac772
 void log_thread_set(int* num)
7ac772
@@ -239,9 +239,9 @@ log_vmsg(int pri, const char* type,
7ac772
 		return;
7ac772
 	}
7ac772
 #endif /* HAVE_SYSLOG_H */
7ac772
-	lock_quick_lock(&log_lock);
7ac772
+	lock_basic_lock(&log_lock);
7ac772
 	if(!logfile) {
7ac772
-		lock_quick_unlock(&log_lock);
7ac772
+		lock_basic_unlock(&log_lock);
7ac772
 		return;
7ac772
 	}
7ac772
 	if(log_now)
7ac772
@@ -268,7 +268,7 @@ log_vmsg(int pri, const char* type,
7ac772
 	/* line buffering does not work on windows */
7ac772
 	fflush(logfile);
7ac772
 #endif
7ac772
-	lock_quick_unlock(&log_lock);
7ac772
+	lock_basic_unlock(&log_lock);
7ac772
 }
7ac772
 
7ac772
 /**
7ac772
-- 
7ac772
2.21.0
7ac772