From 7606488c0efa8f631d31ab9ff8d33b7cf3e2a4c9 Mon Sep 17 00:00:00 2001 From: Robert Foley Date: Mon, 18 Nov 2019 16:15:27 -0500 Subject: Add use of RCU for qemu_logfile. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This now allows changing the logfile while logging is active, and also solves the issue of a seg fault while changing the logfile. Any read access to the qemu_logfile handle will use the rcu_read_lock()/unlock() around the use of the handle. To fetch the handle we will use atomic_rcu_read(). We also in many cases do a check for validity of the logfile handle before using it to deal with the case where the file is closed and set to NULL. The cases where we write to the qemu_logfile will use atomic_rcu_set(). Writers will also use call_rcu() with a newly added qemu_logfile_free function for freeing/closing when readers have finished. Signed-off-by: Robert Foley Reviewed-by: Alex Bennée Signed-off-by: Alex Bennée Message-Id: <20191118211528.3221-6-robert.foley@linaro.org> --- include/exec/log.h | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'include/exec') diff --git a/include/exec/log.h b/include/exec/log.h index e2cfd436e6..9bd1e4aa20 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -15,8 +15,15 @@ */ static inline void log_cpu_state(CPUState *cpu, int flags) { + QemuLogFile *logfile; + if (qemu_log_enabled()) { - cpu_dump_state(cpu, qemu_logfile, flags); + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + cpu_dump_state(cpu, logfile->fd, flags); + } + rcu_read_unlock(); } } @@ -40,19 +47,37 @@ static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags) static inline void log_target_disas(CPUState *cpu, target_ulong start, target_ulong len) { - target_disas(qemu_logfile, cpu, start, len); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + target_disas(logfile->fd, cpu, start, len); + } + rcu_read_unlock(); } static inline void log_disas(void *code, unsigned long size) { - disas(qemu_logfile, code, size); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + disas(logfile->fd, code, size); + } + rcu_read_unlock(); } #if defined(CONFIG_USER_ONLY) /* page_dump() output to the log file: */ static inline void log_page_dump(void) { - page_dump(qemu_logfile); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + page_dump(logfile->fd); + } + rcu_read_unlock(); } #endif #endif -- cgit v1.2.3 From 10d0d505de750590c21a78c0652bf5a9c142302a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 5 Dec 2019 12:25:15 +0000 Subject: linux-user: log page table changes under -d page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU_LOG_PAGE flag is woefully underused and could stand to do extra duty tracking page changes. If the user doesn't want to see the details as things change they still have the tracepoints available. We push the locking into log_page_dump and pass a reason for the banner text. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Laurent Vivier Message-Id: <20191205122518.10010-5-alex.bennee@linaro.org> --- include/exec/log.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/exec') diff --git a/include/exec/log.h b/include/exec/log.h index 9bd1e4aa20..fcc7b9e00b 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -69,15 +69,14 @@ static inline void log_disas(void *code, unsigned long size) #if defined(CONFIG_USER_ONLY) /* page_dump() output to the log file: */ -static inline void log_page_dump(void) +static inline void log_page_dump(const char *operation) { - QemuLogFile *logfile; - rcu_read_lock(); - logfile = atomic_rcu_read(&qemu_logfile); + FILE *logfile = qemu_log_lock(); if (logfile) { - page_dump(logfile->fd); + qemu_log("page layout changed following %s\n", operation); + page_dump(logfile); } - rcu_read_unlock(); + qemu_log_unlock(logfile); } #endif #endif -- cgit v1.2.3