From 5c312079417908381ffca44d18150b6a990c4f0b Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 12 Mar 2014 11:48:18 +0000 Subject: [PATCH 1/3] Detect pthread_setname_np at configure time Warn if no way of setting thread name is available. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- configure | 28 ++++++++++++++++++++++++++++ util/qemu-thread-posix.c | 21 ++++++++++++++++++--- util/qemu-thread-win32.c | 2 ++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/configure b/configure index aae617e765..01e637f546 100755 --- a/configure +++ b/configure @@ -2696,6 +2696,24 @@ if test "$mingw32" != yes -a "$pthread" = no; then "Make sure to have the pthread libs and headers installed." fi +# check for pthread_setname_np +pthread_setname_np=no +cat > $TMPC << EOF +#include + +static void *f(void *p) { return NULL; } +int main(void) +{ + pthread_t thread; + pthread_create(&thread, 0, f, 0); + pthread_setname_np(thread, "QEMU"); + return 0; +} +EOF +if compile_prog "" "$pthread_lib" ; then + pthread_setname_np=yes +fi + ########################################## # rbd probe if test "$rbd" != "no" ; then @@ -4628,6 +4646,16 @@ if test "$rdma" = "yes" ; then echo "CONFIG_RDMA=y" >> $config_host_mak fi +# Hold two types of flag: +# CONFIG_THREAD_SETNAME_BYTHREAD - we've got a way of setting the name on +# a thread we have a handle to +# CONFIG_PTHREAD_SETNAME_NP - A way of doing it on a particular +# platform +if test "$pthread_setname_np" = "yes" ; then + echo "CONFIG_THREAD_SETNAME_BYTHREAD=y" >> $config_host_mak + echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak +fi + if test "$tcg_interpreter" = "yes"; then QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES" elif test "$ARCH" = "sparc64" ; then diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 960d7f5d42..d05a6497e1 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -32,6 +32,13 @@ static bool name_threads; void qemu_thread_naming(bool enable) { name_threads = enable; + +#ifndef CONFIG_THREAD_SETNAME_BYTHREAD + /* This is a debugging option, not fatal */ + if (enable) { + fprintf(stderr, "qemu: thread naming not supported on this host\n"); + } +#endif } static void error_exit(int err, const char *msg) @@ -394,6 +401,16 @@ void qemu_event_wait(QemuEvent *ev) } } +/* Attempt to set the threads name; note that this is for debug, so + * we're not going to fail if we can't set it. + */ +static void qemu_thread_set_name(QemuThread *thread, const char *name) +{ +#ifdef CONFIG_PTHREAD_SETNAME_NP + pthread_setname_np(thread->thread, name); +#endif +} + void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void*), void *arg, int mode) @@ -420,11 +437,9 @@ void qemu_thread_create(QemuThread *thread, const char *name, if (err) error_exit(err, __func__); -#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 12)) if (name_threads) { - pthread_setname_np(thread->thread, name); + qemu_thread_set_name(thread, name); } -#endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index b9c957b6a0..c405c9bef6 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -22,6 +22,8 @@ void qemu_thread_naming(bool enable) { /* But note we don't actually name them on Windows yet */ name_threads = enable; + + fprintf(stderr, "qemu: thread naming not supported on this host\n"); } static void error_exit(int err, const char *msg) From c36ad13fe9ece9a21a8c1dd082473a2b182298ee Mon Sep 17 00:00:00 2001 From: Matt Lupfer Date: Fri, 21 Feb 2014 21:37:23 -0700 Subject: [PATCH 2/3] Don't enable a HPET timer if HPET is disabled A HPET timer can be started when HPET is not yet enabled. This will not generate an interrupt to the guest, but causes problems when HPET is later enabled. A timer that is created and expires at least once before HPET is enabled will have an initialized comparator based on a hpet_offset of 0 (uninitialized). When HPET is enabled, hpet_set_timer() is called a second time, which modifies the timer expiry to a time based on the difference between current ticks (measured with the newly initialized hpet_offset) and the timer's comparator (which was generated before hpet_offset was initialized). This results in a long period of no HPET timer ticks. When this occurs with a CentOS 5.x guest, the guest may not receive timer interrupts during its narrow timer check window and panic on boot. Signed-off-by: Matt Lupfer Acked-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini --- hw/timer/hpet.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 1264dfd46a..e15d6bcac7 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -506,7 +506,8 @@ static void hpet_ram_write(void *opaque, hwaddr addr, timer->cmp = (uint32_t)timer->cmp; timer->period = (uint32_t)timer->period; } - if (activating_bit(old_val, new_val, HPET_TN_ENABLE)) { + if (activating_bit(old_val, new_val, HPET_TN_ENABLE) && + hpet_enabled(s)) { hpet_set_timer(timer); } else if (deactivating_bit(old_val, new_val, HPET_TN_ENABLE)) { hpet_del_timer(timer); From b89834f4d79070a26536cb73fe5216a2364551eb Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Thu, 27 Mar 2014 17:35:36 +0200 Subject: [PATCH 3/3] acpi: fix ACPI generation for pci bridges Commit 8dcf525abc5dff785251a881f9764dd961065c0d acpi-build: append description for non-hotplug appended description for all occupied non hotpluggable PCI slots. However the bridge devices are already added to SSDT, adding them again will create an incorrect SSDT table. Fixed by skipping the pci bridge devices, marking them as 'system'. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 7597517b97..90ef95cccf 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -841,7 +841,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) pc = PCI_DEVICE_GET_CLASS(pdev); dc = DEVICE_GET_CLASS(pdev); - if (pc->class_id == PCI_CLASS_BRIDGE_ISA) { + if (pc->class_id == PCI_CLASS_BRIDGE_ISA || pc->is_bridge) { set_bit(slot, slot_device_system); } @@ -882,7 +882,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF); patch_pcivga(i, pcihp); } else if (system) { - /* Nothing to do: system devices are in DSDT. */ + /* Nothing to do: system devices are in DSDT or in SSDT above. */ } else if (present) { void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF);