From owner-svn-src-head@FreeBSD.ORG Wed Sep 8 16:59:23 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6A1FE10656AB; Wed, 8 Sep 2010 16:59:23 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3F1CB8FC16; Wed, 8 Sep 2010 16:59:23 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o88GxNvO050601; Wed, 8 Sep 2010 16:59:23 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o88GxNOn050599; Wed, 8 Sep 2010 16:59:23 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201009081659.o88GxNOn050599@svn.freebsd.org> From: Alexander Motin Date: Wed, 8 Sep 2010 16:59:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212323 - head/sys/dev/acpica X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 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: Wed, 08 Sep 2010 16:59:23 -0000 Author: mav Date: Wed Sep 8 16:59:22 2010 New Revision: 212323 URL: http://svn.freebsd.org/changeset/base/212323 Log: During SMP startup there is time window, when SMP started, but interrupts are still bound to BSP. It confuses timer management logic in per-CPU mode and may cause timer not being reloaded. Check such cases on interrupt arival and reload timer to give system some more time to manage proper binding. Modified: head/sys/dev/acpica/acpi_hpet.c Modified: head/sys/dev/acpica/acpi_hpet.c ============================================================================== --- head/sys/dev/acpica/acpi_hpet.c Wed Sep 8 16:58:06 2010 (r212322) +++ head/sys/dev/acpica/acpi_hpet.c Wed Sep 8 16:59:22 2010 (r212323) @@ -89,6 +89,8 @@ struct hpet_softc { int mode; int intr_rid; int irq; + int pcpu_cpu; + int pcpu_misrouted; int pcpu_master; int pcpu_slaves[MAXCPU]; struct resource *intr_res; @@ -185,7 +187,7 @@ restart: if (fdiv < 5000) { bus_read_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num)); t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); - if ((int32_t)(t->last - cmp) < 0) { + if ((int32_t)(t->last - cmp) >= 0) { fdiv *= 2; goto restart; } @@ -215,6 +217,26 @@ hpet_intr_single(void *arg) struct hpet_softc *sc = t->sc; uint32_t now; + /* Check that per-CPU timer interrupt reached right CPU. */ + if (t->pcpu_cpu >= 0 && t->pcpu_cpu != curcpu) { + if ((++t->pcpu_misrouted) % 32 == 0) { + printf("HPET interrupt routed to the wrong CPU" + " (timer %d CPU %d -> %d)!\n", + t->num, t->pcpu_cpu, curcpu); + } + + /* + * Reload timer, hoping that next time may be more lucky + * (system will manage proper interrupt binding). + */ + if ((t->mode == 1 && (t->caps & HPET_TCAP_PER_INT) == 0) || + t->mode == 2) { + t->last = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER); + bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), + t->last + sc->freq / 8); + } + return (FILTER_HANDLED); + } if (t->mode == 1 && (t->caps & HPET_TCAP_PER_INT) == 0) { t->last += t->div; @@ -394,6 +416,8 @@ hpet_attach(device_t dev) t->mode = 0; t->intr_rid = -1; t->irq = -1; + t->pcpu_cpu = -1; + t->pcpu_misrouted = 0; t->pcpu_master = -1; t->caps = bus_read_4(sc->mem_res, HPET_TIMER_CAP_CNF(i)); t->vectors = bus_read_4(sc->mem_res, HPET_TIMER_CAP_CNF(i) + 4); @@ -534,6 +558,7 @@ hpet_attach(device_t dev) if (t->irq >= 0 && num_percpu_t > 0) { if (cur_cpu == CPU_FIRST()) pcpu_master = i; + t->pcpu_cpu = cur_cpu; t->pcpu_master = pcpu_master; sc->t[pcpu_master]. pcpu_slaves[cur_cpu] = i;