Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 May 2018 14:50:30 +0300
From:      Andriy Gapon <avg@FreeBSD.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@FreeBSD.org>
Subject:   Re: hpet vs suspend to ram
Message-ID:  <18935a5e-cd60-a434-f226-1c4ab258c044@FreeBSD.org>
In-Reply-To: <20180503095558.GJ6887@kib.kiev.ua>
References:  <8d3f5a6f-f2be-f2e1-18d5-f774f4909694@icyb.net.ua> <20180503095558.GJ6887@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On 03/05/2018 12:55, Konstantin Belousov wrote:
> On Thu, May 03, 2018 at 11:40:24AM +0300, Andriy Gapon wrote:
>>
>> Just want to share a strange problem that I see on one system.
>>
>> If I use HPET as an eventtimer, then after a seemingly successful resume
>> the system starts to act weird.  It becomes unresponsive for periods of
>> time, then it gets more normal, then it's sluggish, then unresponsive
>> again.  After some time struggling the system finally locks up entirely.
>>
>> I see this problem both with FreeBSD and Linux (tested with Ubuntu 16
>> and 17).
>>
>> If I use any other timer hardware, then everything is okay.
>> Also, if I switch to HPET after a resume, then it's okay too.
>> I tried uncommenting the code in acpi_hpet.c that disables the HPET
>> before suspend, but it didn't change anything.
>>
>> I suspect that the problem is with SMM code, but don't know how to check
>> it or whether it would make any difference.
>> I also tried disabling various devices (e.g. USB) through BIOS config, but that
>> also didn't help.
> Did you tried to clear comparators, besides disabling the HPET ?

Thank you very much for the suggestion!
It seems that doing that (and a little bit more[*]) helps indeed.

However there seems to be another issue.
hpet_suspend() is called too early.  [Some] Other drivers require a working
event timer for their suspend routines.  So after HPET is stopped the suspend
process gets stuck.  Repeatedly pressing keyboard keys helps the process to
finally reach the firmware suspend.  Everything is okay after resume.

[*] The change:
@@ -838,15 +842,29 @@
 static int
 hpet_suspend(device_t dev)
 {
-//	struct hpet_softc *sc;
+	struct hpet_softc *sc;
+	struct hpet_timer *t;
+	int i;

 	/*
 	 * Disable the timer during suspend.  The timer will not lose
 	 * its state in S1 or S2, but we are required to disable
 	 * it.
 	 */
-//	sc = device_get_softc(dev);
-//	hpet_disable(sc);
+	sc = device_get_softc(dev);
+	hpet_disable(sc);
+	for (i = 0; i < sc->num_timers; i++) {
+		t = &sc->t[i];
+
+		/*
+		 * Clear timer state to minimize chances of confusing
+		 * the firmware after resuming from S3.
+		 */
+		bus_write_4(sc->mem_res, HPET_TIMER_CAP_CNF(t->num),
+		    t->caps & ~(HPET_TCNF_INT_ENB | HPET_TCNF_TYPE));
+		bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num), 0);
+		bus_write_4(sc->mem_res, HPET_ISR, 1 << t->num);
+	}

 	return (0);
 }



-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?18935a5e-cd60-a434-f226-1c4ab258c044>