Date: Sun, 28 Mar 2010 08:46:34 +1100 From: Peter Jeremy <peterjeremy@acm.org> To: Dag-Erling =?iso-8859-1?Q?Sm=F8rgrav?= <des@des.no> Cc: freebsd-hackers@FreeBSD.org, Andriy Gapon <avg@icyb.net.ua> Subject: Re: periodically save current time to time-of-day hardware Message-ID: <20100327214634.GI32799@server.vk2pj.dyndns.org> In-Reply-To: <86pr2qlhtf.fsf@ds4.des.no> References: <4BACC791.70502@icyb.net.ua> <86zl1v84vy.fsf@ds4.des.no> <4BACD88E.2040803@icyb.net.ua> <86vdcj82qx.fsf@ds4.des.no> <20100326213022.GD32799@server.vk2pj.dyndns.org> <86pr2qlhtf.fsf@ds4.des.no>
next in thread | previous in thread | raw e-mail | index | archive | help
--ZY5CS28jBCfb727c Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On 2010-Mar-27 01:38:36 +0100, Dag-Erling Sm=F8rgrav <des@des.no> wrote: >Peter Jeremy <peterjeremy@acm.org> writes: >> It's not especially important how regularly the RTC is updated, just >> that it _is_ updated. This suggests that an alternative approach >> would be for adjtime() / ntp_adjtime() to directly call resettodr() if >> it's more than P minutes since resettodr() was last called. > >It just occurred to me that resettodr() is very slow (it usually >involves writing to NVRAM over an I2C bus), so it might not be a good >idea to call it from adjtime(). Traditionally, the (PC) RTC is on the ISA bus (though it's possible it might use I2C on other architectures or LPC on current PCs). I thought about speed but only in terms of simulated ISA accesses and didn't think that adjtime() / ntp_adjtime() were especially time critical (resettodr() should occur after they have updated the kernel TOD parameters). The alternative would be a kthread to update the RTC and I didn't think that was worth it. Note that resettodr() is currently called with Giant held so if it _is_ excesssively slow, it might be worthwhile reviewing the existing code in kern_time.c::settime() and subr_clock.c::sysctl_machdep_adjkerntz(). >> As a general comment, whilst resettodr() needs to be serialised, there >> is no need for it to block. If thread B wants to call resettodr() >> whilst thread A is doing so, thread B can just skip the call because >> calling resettodr() twice in quick succession has no benefit. > >It does if thread B set the system clock before calling resettodr() >(think ntpd -gq). Yes - I hadn't considered resettodr() taking a non-trivial time to execute. This could allow the scenario: Thread A grabs the RTC update lock and begin updating the RTC and, whilst it's doing so, thread B updates the system clock and then calls resettodr() - which turns into a no-op because the update lock is held. > Actually, it might be a good idea to call resettodr() >any time the clock is stepped. This should occur now via kern_time.c::settime(). Given that: - resettodr() needs to be serialised; - resettodr() may take a significant amount of time; and - resettodr() should ideally be synchronised to the second boundary; maybe creating a kthread to manage the RTC updating is reasonable. A rough outline of my idea would be: A new kthread which sleeps on channel "update_rtc". When woken, it checks to see if it's within (say) 50msec of a second boundary and so, it does a trylock on the (new) RTC mutex. If it grabs the mutex then it performs the update. If it was too far from the second boundary or it fails to grab the mutex then it sleeps until the next second boundary and tries again. The existing resettodr() would then turn into a wakeup(update_rtc). Or is this overkill? --=20 Peter Jeremy --ZY5CS28jBCfb727c Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (FreeBSD) iEYEARECAAYFAkuufLoACgkQ/opHv/APuIeSmgCaApSP1xoxTFh+zUi02AcG0X/S I2cAn27crdOwqShdrSHiQyhRO5BbxqIb =J3KG -----END PGP SIGNATURE----- --ZY5CS28jBCfb727c--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100327214634.GI32799>