From owner-freebsd-current@FreeBSD.ORG Sat Dec 23 06:45:58 2006 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 60C6C16A403 for ; Sat, 23 Dec 2006 06:45:58 +0000 (UTC) (envelope-from swhetzel@gmail.com) Received: from nz-out-0506.google.com (nz-out-0506.google.com [64.233.162.237]) by mx1.freebsd.org (Postfix) with ESMTP id 2459F13C442 for ; Sat, 23 Dec 2006 06:45:58 +0000 (UTC) (envelope-from swhetzel@gmail.com) Received: by nz-out-0506.google.com with SMTP id i11so1310601nzh for ; Fri, 22 Dec 2006 22:45:57 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=IvGMVL2iFDyP5oBkUbdZrY8CogBIHaf5jfez2ET/SJwSYr/7QzM2kZLYvABfJzMuCQW2DqK9sFgaWmy9TlGTPhAP6At7LCnDtNBo/+fS+toDUKTj8i78tGr1dULkub0GGaTCwgGGZja+nCyk2M8bZW4L+BEsIr8otHQyFElkpUk= Received: by 10.65.194.13 with SMTP id w13mr2016298qbp.1166856357452; Fri, 22 Dec 2006 22:45:57 -0800 (PST) Received: by 10.65.61.1 with HTTP; Fri, 22 Dec 2006 22:45:57 -0800 (PST) Message-ID: <790a9fff0612222245n70994662y49aebed77c8eb45b@mail.gmail.com> Date: Sat, 23 Dec 2006 00:45:57 -0600 From: "Scot Hetzel" To: "M. Warner Losh" In-Reply-To: <20061220.185514.-345500127.imp@bsdimp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <45887A31.4050801@paradise.net.nz> <790a9fff0612191741r656fbbe0ic8660a9c59ba632b@mail.gmail.com> <45889598.3030408@u.washington.edu> <20061220.185514.-345500127.imp@bsdimp.com> Cc: youshi10@u.washington.edu, freebsd-current@freebsd.org Subject: Re: settimeofday function taking 24 - 30 minutes to complete X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 Dec 2006 06:45:58 -0000 On 12/20/06, M. Warner Losh wrote: > It does run almost instantly if you use a time from 2000. The date > command also causes the lockup if you say 'date 1970010100140' as > well. Looks like there's a loop in the kernel to do division, but I > can't quite find where it is. > > If you have a good test setup, maybe you can do a binary search in the > settimeofday code to find why a large leap backwards causes problems. > Found the source of the problem by following the code in kern_settimeofday (sys/kern/kern_time.c), settime (sys/kern/kern_time.c), and finally in resettodr (sys/amd64/isa/clock.c). /* * Write system time back to RTC */ void resettodr() { : s = splclock(); tm = time_second; splx(s); : /* Calculate local time to put in RTC */ tm -= utc_offset(); : /* We have now the days since 01-01-1970 in tm */ writertc(RTC_WDAY, (tm + 4) % 7 + 1); /* Write back Weekday */ for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y); tm >= m; y++, m = DAYSPERYEAR + LEAPYEAR(y)) tm -= m; : } After adding some printf's to the resettodor, I was able to get some interesting results: hp010# ./t1 INFO: test running as root INFO: Saved current time settime: delta.tv_sec = - 1166842289 resettodr: tm = 100 resettodr: tm = -21500, utc_offset = 21600 <- value after subtracting utc_offset() resettodr: tm= 229, y = 426495804 <- the hang occurs in the calculation for year. INFO: settimeofday completed successfully settime: delta.tv_sec = 1166840819 resettodr: tm = 1166842388 resettodr: tm = 1166820788 resettodr: tm = 355, y = 2006 INFO: Reset time to original value By making the following change, the test program no longer hangs the system: /* * Calculate local time to put in RTC * Ignore UTC offset, if it would cause the time < Jan 1, 1970 00:00. */ if (tm >= utc_offset()) tm -= utc_offset(); else printf("resettodr: utc_offset > tm"); We probably need to change all the locations that use utc_offset(), to have a similar "if (x >= utc_offset()) x -= utc_offset();". Scot -- DISCLAIMER: No electrons were mamed while sending this message. Only slightly bruised.