From owner-svn-src-head@freebsd.org Tue Mar 29 19:54:14 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 48D61AE22B1; Tue, 29 Mar 2016 19:54:14 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0AA2B1EF1; Tue, 29 Mar 2016 19:54:13 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u2TJsDQC036509; Tue, 29 Mar 2016 19:54:13 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u2TJsDSC036508; Tue, 29 Mar 2016 19:54:13 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201603291954.u2TJsDSC036508@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Tue, 29 Mar 2016 19:54:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297398 - head/sys/x86/x86 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Mar 2016 19:54:14 -0000 Author: kib Date: Tue Mar 29 19:54:13 2016 New Revision: 297398 URL: https://svnweb.freebsd.org/changeset/base/297398 Log: Fix several bugs in r297374: - fix UP build [1] - do not obliterate initial reading of rdtsc by the loop counter [2] - restore the meaning of the argument -1 to native_lapic_ipi_wait() as wait until LAPIC acknowledge without timeout - correct formula for calculating loop iteration count for 1us, it was inverted, and ensure that even on unlikely slow CPUs at least one check for ack is performed. Reported by: Michael Butler [1], rpokala[2], jhb[3] Tested by: Michael Butler Pointy hat to: kib Sponsored by: The FreeBSD Foundation Modified: head/sys/x86/x86/local_apic.c Modified: head/sys/x86/x86/local_apic.c ============================================================================== --- head/sys/x86/x86/local_apic.c Tue Mar 29 19:23:00 2016 (r297397) +++ head/sys/x86/x86/local_apic.c Tue Mar 29 19:54:13 2016 (r297398) @@ -172,7 +172,9 @@ int lapic_eoi_suppression; static int lapic_timer_tsc_deadline; static u_long lapic_timer_divisor; static struct eventtimer lapic_et; +#ifdef SMP static uint64_t lapic_ipi_wait_mult; +#endif SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options"); SYSCTL_INT(_hw_apic, OID_AUTO, x2apic_mode, CTLFLAG_RD, &x2apic_mode, 0, ""); @@ -404,7 +406,9 @@ lvt_mode(struct lapic *la, u_int pin, ui static void native_lapic_init(vm_paddr_t addr) { - uint64_t r; +#ifdef SMP + uint64_t r, r1, r2, rx; +#endif uint32_t ver; u_int regs[4]; int i, arat; @@ -506,6 +510,7 @@ native_lapic_init(vm_paddr_t addr) &lapic_eoi_suppression); } +#ifdef SMP #define LOOPS 1000000 /* * Calibrate the busy loop waiting for IPI ack in xAPIC mode. @@ -521,18 +526,21 @@ native_lapic_init(vm_paddr_t addr) KASSERT((cpu_feature & CPUID_TSC) != 0 && tsc_freq != 0, ("TSC not initialized")); r = rdtsc(); - for (r = 0; r < LOOPS; r++) { + for (rx = 0; rx < LOOPS; rx++) { (void)lapic_read_icr_lo(); ia32_pause(); } r = rdtsc() - r; - lapic_ipi_wait_mult = (r * 1000000) / tsc_freq / LOOPS; + r1 = tsc_freq * LOOPS; + r2 = r * 1000000; + lapic_ipi_wait_mult = r1 >= r2 ? r1 / r2 : 1; if (bootverbose) { printf("LAPIC: ipi_wait() us multiplier %jd (r %jd tsc %jd)\n", (uintmax_t)lapic_ipi_wait_mult, (uintmax_t)r, (uintmax_t)tsc_freq); } #undef LOOPS +#endif /* SMP */ } /* @@ -1757,11 +1765,11 @@ native_lapic_ipi_wait(int delay) uint64_t i, counter; /* LAPIC_ICR.APIC_DELSTAT_MASK is undefined in x2APIC mode */ - if (x2apic_mode || delay == -1) + if (x2apic_mode) return (1); counter = lapic_ipi_wait_mult * delay; - for (i = 0; i < counter; i++) { + for (i = 0; delay == -1 || i < counter; i++) { if ((lapic_read_icr_lo() & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) return (1);