It works fine here (VMware). Martin ----- Original Message ---- From: Mike Silbersack <silby_at_silby.com> To: Robert Watson <rwatson_at_FreeBSD.org> Cc: current_at_freebsd.org Sent: Sunday, December 30, 2007 1:01:43 AM Subject: Re: [patch] Auto-setting hz to 100 inside QEMU/VMWare On Fri, 28 Dec 2007, Robert Watson wrote: > I like the general idea, but one thing that does worry me is that this > prevents me from using config to set HZ at all, I have to set it at runtime > using the tunable. Could we add an: Attached is a patch which attempts to address all of Robert's concerns and includes all the strings for the various VMs that people have mailed in to me. Please test/review. :) Mike "Silby" Silbersack -----Inline Attachment Follows----- diff -u -r /usr/src/sys.old/amd64/amd64/machdep.c /usr/src/sys/amd64/amd64/machdep.c --- /usr/src/sys.old/amd64/amd64/machdep.c 2007-12-29 03:01:02.000000000 -0600 +++ /usr/src/sys/amd64/amd64/machdep.c 2007-12-29 18:57:01.000000000 -0600 _at__at_ -1935,3 +1935,33 _at__at_ } #endif /* KDB */ + +/* kenv strings used to identify various VM environments */ + +static char *vm_strings[] = { + "hint.acpi.0.oem", "QEMU", + "hint.acpi.0.oem", "VBOX", /* VirtualBox */ + "smbios.system.maker", "VMware, Inc.", + "smbios.bios.vendor", "Parallels Software International Inc.", + NULL + }; + +int +detect_virtualmachine(void) +{ + char *envptr; + int i; + for (i = 0; ; i += 2) { + if (vm_strings[i] == NULL) + break; + envptr = getenv(vm_strings[i]); + if (envptr) { + if (strncmp(envptr, vm_strings[i+1], strlen(vm_strings[i+1])) == 0) { + freeenv(envptr); + return 1; + } + freeenv(envptr); + } + } + return 0; +} diff -u -r /usr/src/sys.old/arm/arm/machdep.c /usr/src/sys/arm/arm/machdep.c --- /usr/src/sys.old/arm/arm/machdep.c 2007-12-29 03:01:06.000000000 -0600 +++ /usr/src/sys/arm/arm/machdep.c 2007-12-29 18:57:21.000000000 -0600 _at__at_ -631,3 +631,9 _at__at_ pcb->un_32.pcb32_lr = tf->tf_usr_lr; pcb->un_32.pcb32_sp = tf->tf_usr_sp; } + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/conf/NOTES /usr/src/sys/conf/NOTES --- /usr/src/sys.old/conf/NOTES 2007-12-29 03:01:19.000000000 -0600 +++ /usr/src/sys/conf/NOTES 2007-12-29 18:54:40.000000000 -0600 _at__at_ -1115,6 +1115,7 _at__at_ # the accuracy of operation. options HZ=100 +options VIRTUAL_HZ=100 # Enable support for the kernel PLL to use an external PPS signal, # under supervision of [x]ntpd(8) diff -u -r /usr/src/sys.old/conf/options /usr/src/sys/conf/options --- /usr/src/sys.old/conf/options 2007-12-29 03:01:19.000000000 -0600 +++ /usr/src/sys/conf/options 2007-12-29 03:06:22.000000000 -0600 _at__at_ -262,6 +262,7 _at__at_ # Options used only in subr_param.c. HZ opt_param.h +VIRTUAL_HZ opt_param.h MAXFILES opt_param.h NBUF opt_param.h NSFBUFS opt_param.h diff -u -r /usr/src/sys.old/i386/i386/machdep.c /usr/src/sys/i386/i386/machdep.c --- /usr/src/sys.old/i386/i386/machdep.c 2007-12-29 03:01:29.000000000 -0600 +++ /usr/src/sys/i386/i386/machdep.c 2007-12-29 03:59:05.000000000 -0600 _at__at_ -3110,3 +3110,33 _at__at_ } #endif /* KDB */ + +/* kenv strings used to identify various VM environments */ + +static char *vm_strings[] = { + "hint.acpi.0.oem", "QEMU", + "hint.acpi.0.oem", "VBOX", /* VirtualBox */ + "smbios.system.maker", "VMware, Inc.", + "smbios.bios.vendor", "Parallels Software International Inc.", + NULL + }; + +int +detect_virtualmachine(void) +{ + char *envptr; + int i; + for (i = 0; ; i += 2) { + if (vm_strings[i] == NULL) + break; + envptr = getenv(vm_strings[i]); + if (envptr) { + if (strncmp(envptr, vm_strings[i+1], strlen(vm_strings[i+1])) == 0) { + freeenv(envptr); + return 1; + } + freeenv(envptr); + } + } + return 0; +} diff -u -r /usr/src/sys.old/ia64/ia64/machdep.c /usr/src/sys/ia64/ia64/machdep.c --- /usr/src/sys.old/ia64/ia64/machdep.c 2007-12-29 03:01:29.000000000 -0600 +++ /usr/src/sys/ia64/ia64/machdep.c 2007-12-29 19:02:23.000000000 -0600 _at__at_ -1531,3 +1531,9 _at__at_ { return (ENODEV); } + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/kern/subr_param.c /usr/src/sys/kern/subr_param.c --- /usr/src/sys.old/kern/subr_param.c 2007-12-29 03:01:29.000000000 -0600 +++ /usr/src/sys/kern/subr_param.c 2007-12-29 03:14:23.000000000 -0600 _at__at_ -58,6 +58,9 _at__at_ # define HZ 100 # endif #endif +#ifndef VIRTUAL_HZ +# define VIRTUAL_HZ 100 +#endif #define NPROC (20 + 16 * maxusers) #ifndef NBUF #define NBUF 0 _at__at_ -109,7 +112,16 _at__at_ init_param1(void) { - hz = HZ; + /* Virtualization environments can't keep up with a + * 1000hz tick rate, leading to highly inaccurate + * timekeeping by FreeBSD guests. To fix this problem, + * drop back to 100hz when we detect that we are running + * inside a virtual machine. + */ + if (detect_virtualmachine()) + hz = VIRTUAL_HZ; + else + hz = HZ; TUNABLE_INT_FETCH("kern.hz", &hz); tick = 1000000 / hz; diff -u -r /usr/src/sys.old/pc98/pc98/machdep.c /usr/src/sys/pc98/pc98/machdep.c --- /usr/src/sys.old/pc98/pc98/machdep.c 2007-12-29 03:01:34.000000000 -0600 +++ /usr/src/sys/pc98/pc98/machdep.c 2007-12-29 19:01:49.000000000 -0600 _at__at_ -2791,3 +2791,9 _at__at_ } #endif /* KDB */ + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/powerpc/powerpc/intr_machdep.c /usr/src/sys/powerpc/powerpc/intr_machdep.c --- /usr/src/sys.old/powerpc/powerpc/intr_machdep.c 2007-12-29 03:01:34.000000000 -0600 +++ /usr/src/sys/powerpc/powerpc/intr_machdep.c 2007-12-29 18:59:36.000000000 -0600 _at__at_ -304,3 +304,9 _at__at_ if (i != NULL) PIC_MASK(pic, i->irq); } + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/sparc64/sparc64/machdep.c /usr/src/sys/sparc64/sparc64/machdep.c --- /usr/src/sys.old/sparc64/sparc64/machdep.c 2007-12-29 03:01:35.000000000 -0600 +++ /usr/src/sys/sparc64/sparc64/machdep.c 2007-12-29 19:01:33.000000000 -0600 _at__at_ -910,3 +910,9 _at__at_ mtx_pool_unlock(mtxpool_sleep, ut); return (ut); } + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/sun4v/sun4v/machdep.c /usr/src/sys/sun4v/sun4v/machdep.c --- /usr/src/sys.old/sun4v/sun4v/machdep.c 2007-12-29 03:01:01.000000000 -0600 +++ /usr/src/sys/sun4v/sun4v/machdep.c 2007-12-29 18:58:49.000000000 -0600 _at__at_ -999,3 +999,9 _at__at_ if (rdpr(pil) < PIL_TICK) hv_cpu_yield(); } + +int +detect_virtualmachine(void) +{ + return 0; +} diff -u -r /usr/src/sys.old/sys/systm.h /usr/src/sys/sys/systm.h --- /usr/src/sys.old/sys/systm.h 2007-12-29 03:01:35.000000000 -0600 +++ /usr/src/sys/sys/systm.h 2007-12-29 03:50:59.000000000 -0600 _at__at_ -245,6 +245,8 _at__at_ int unsetenv(const char *name); int testenv(const char *name); +int detect_virtualmachine(void); + typedef uint64_t (cpu_tick_f)(void); void set_cputicker(cpu_tick_f *func, uint64_t freq, unsigned var); extern cpu_tick_f *cpu_ticks; -----Inline Attachment Follows----- _______________________________________________ freebsd-current_at_freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd.org" ____________________________________________________________________________________ Looking for last minute shopping deals? Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shoppingReceived on Tue Jan 01 2008 - 19:52:43 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:24 UTC