-
Notifications
You must be signed in to change notification settings - Fork 1.2k
hwclock Timed out waiting for time change Error #1387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What hardware? It seems your RTC does not support RTC_UIE_ON, in this case, hwclock uses a busy-loop with RTC_RD_TIME ioctl and it waits for the next tick (change of the second in clock). For some reason, the change is bigger than 1.5 seconds. Frankly, the best solution is to ask kernel RTC developers, I'm not sure what happened in your case. Maybe hwclock should be more patient and tried to sync in more attempts. |
Hi, Thanks for the response. My HW is this https://wiki.friendlyarm.com/wiki/index.php/Matrix_-_RTC Is possible to change the 1.5sec? Thanks! |
The 1.5 check is correct if we want to sync with 1sec tick, the question is why it's so slow and why it does not support RTC_UIE_ON. Please, try the following patch: diff --git a/sys-utils/hwclock-rtc.c b/sys-utils/hwclock-rtc.c
index 07af9c83c..a033e6419 100644
--- a/sys-utils/hwclock-rtc.c
+++ b/sys-utils/hwclock-rtc.c
@@ -213,6 +213,7 @@ static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
struct tm nowtime;
int rc;
struct timeval begin = { 0 }, now = { 0 };
+ int try_counter = 0;
if (ctl->verbose) {
printf("ioctl(%d, RTC_UIE_ON, 0): %s\n",
@@ -221,6 +222,7 @@ static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
rtc_dev_name);
}
+again:
if (do_rtc_read_ioctl(rtc_fd, &start_time))
return 1;
@@ -236,8 +238,12 @@ static int busywait_for_rtc_clock_tick(const struct hwclock_control *ctl,
break;
gettime_monotonic(&now);
if (time_diff(now, begin) > 1.5) {
- warnx(_("Timed out waiting for time change."));
- return 1;
+ try_counter++;
+ warnx(_("[#%d] Timed out waiting for time change (delay: %g)"),
+ try_counter, time_diff(now, begin));
+ if (try_counter >= 10)
+ return 1;
+ goto again;
}
} while (1);
to get more details. It will try it 10 times and print the delay. |
Hi! Thanks for you time. Thank! |
Addresses: #1387 Signed-off-by: Karel Zak <kzak@redhat.com>
OK, I have created a branch with the change. Try:
|
Hello, Dont work.. hwclock from util-linux 2.37.202-3ade7 :( |
Well, try to change 1.5 to 1.6 in the code ;-) https://github.com/karelzak/util-linux/blob/hwclock-releap-busywait/sys-utils/hwclock-rtc.c#L239 (sys-utils/hwclock-rtc.c line 239). |
Or we can round the number. |
I have encountered the same error on my embedded target. Probably 50% of the time I get the "Timed out waiting for time change" error when trying to use hwclock to show the RTC time. I even applied the above patch but as @Ataraxiall experienced, the error continues. My platform is a Xilinx 7000 based target based on Xilinx PetaLinux 2022.1 (Kernel 5.15.19-rt40) with the PREEMPT_RT patches applied. I build my system with Yocto hornister (util-linux_2.37.2.bb) and I have a Micro Crystal RTC (RV-3028-C7) so there is an existing Linux driver. I've used a JTAG debugger to set breakpoints in the rtc-rv3028 driver and the IOCTL(RTC_RD_TIME) ultimately lands in rtc-rv3028.c:rv3028_get_time() where the RTC time is read via calls to regmap_bulk_read(). This triggers I2C reads to the RTC chip itself. From the Linux command-line on the target I can easily read the current RTC with this command:
This too ends up in the same rv3028_get_time() function. Using this command I can get the RTC time as fast as I can repeat the command. There is no perceptible delay or timeout. So there appears to be something different about the IOCTL(RTC_RD_TIME) pathway. It seems if I insert additional "printf's" in the above patch so there is more console I/O the process executes "slower" and the number of re-occurring timeout errors diminish. With this in mind I developed another work-around. The patch is shown below:
Basically, I introduce a delay (usleep) between successive ioctl() calls to read the RTC. This delay is generally based on the execution quantum of the scheduler. On my target platform this is typically 10 msec. With the above patch, I have not been able to reproduce the "timeout" error I was getting 50% of the time when trying to show the RTC time with I hope someone might have more insights into this issue and can devise a better fix (or can at least describe the underlying root cause). Until then, I think this patch might work for others experiencing the same issue. |
Maybe the delay is not so bad idea. Frankly, the busy loop is a pretty nasty thing, and I can imagine that kernel tries to optimize this behavior. And for example, for read/write on EAGAIN, we already use delay in the loops (in other tools), so why not here? :-) |
@gschmottlach-xse, we're using the same RTC as you (RV-3028). We recently started seeing similar problems when we run
We don't have those patches, so I don't think the problem is related to them, unless the two of us are seeing two separate problems. We're going to try some debugging. I'll reply here if we find anything useful. |
Unfortunately, my hack/patch above is not 100% successful at preventing the timeout although it is much less frequent. I hope you can figure out the root cause of this issue because I'd like to correct it. The strange thing is if you Good luck! |
This is basically our theory, too, but we still can't quite explain it. The RV-3028's application manual describes a suspicious feature where it will "lock" its clock registers during I2C transactions. While we're reading the registers over I2C, it will postpone updating them, to avoid a torn-read hazard. If the clock would have incremented during the read, it's supposed to apply that update whenever the I2C transaction ends, after the stop condition. See section 4.5. I've confirmed with a logic analyzer that the kernel driver is sending that I2C stop condition when I expect it to. So the chip should have a chance to apply its clock update. The application note does require a "Bus free time before a new transmission" of 4.7 µs, but we're far above that. So it seems like there's either:
:(
I think the overhead of spawning processes and going through sysfs is effectively doing the same thing as your patch: slowing down the polling with artificial delays. On my Pi-based system, if I run On the other hand, if I run this: while true; do cat /sys/class/rtc/rtc0/time; done There's about 4000 µS between each pair of status-register-reading and clock-register-reading I2C transactions.
As measured with a logic analyzer. So far, I think we're approaching the same place as you. It seems like adding artificial delays in between individual I2C transactions mitigates the problem. But it remains unclear whose fault the problem is, or what a proper fix would be. |
Given your findings, if you manage to come up with a more consistent (and effective) patch than mine, please post it. I doubt it's an electrical problem on your board since we are apparently suffering the same fate. More likely an operational nuance or an undisclosed silicon errata. I can live with a 4msec pause between polling the chip if that makes it 100% reliable. Please share your findings if this approach proves effective. |
@gschmottlach-xse Why does your patch calculate a delay based on the execution quantum of the scheduler? Why not sleep for some constant, hard-coded duration? |
I was hoping to avoid a hard-coded sleep since I didn't have a good measurement (like you have with your scope) of the amount of time to pause between transactions with the RTC. If you can get things working reliably using a hard-coded value between successive RTC requests then I would be happy. I just want a predictable experience and avoid the timeouts. |
We ended up inserting an artificial 2-4 ms delay in the Linux device driver for the RV-3028. This appears to work more consistently than the patch suggested above to insert these delays at the Mind you, this is only based on testing with a single problematic board. It remains to be seen how effective this kernel patch will be in mass use. [Update 2023-05-14: as far as I know, we haven't seen this problem since applying the patch 9 months ago, so it seems effective.] If anybody else runs into this and wants to keep digging, here are my I2C captures, with some notes. They compare the I had to split the archive up into multiple files to work around a GitHub upload limit. Extract with:
|
Thanks for your patch. I'll apply the same to our kernel and see if it improves our situation. |
@SyntaxColoring - after a number of consecutive runs, it seems my timeouts are now elminated. Either we both have poorly designed boards (not likely) or there is indeed an issue with the RTC chip, driver, or elsewhere. Regardless, your patch seems to have reliably solved my problem. - Thanks |
@SyntaxColoring thanks! Closing ... |
If anybody else runs into this in the future, I'm curious what kind of hardware they're on. The workaround that I posted is specific to problematic RV-3028 chips. But the original poster, @Ataraxiall, reported using a different chip. |
Hi |
@gauthamikosanam Is that the exact error message? If yes, it doesn't look like anything we've seen so far in this thread. If your RTC hardware is an RV-3028, you can try the Linux kernel patch that I described above. Otherwise, I don't know, but I'd guess you're seeing an unrelated problem. |
I am using rtc-isl1208 ic and working on raspberryPi 4. I am able to detect the slave address i.e 0x6f. |
If I do sudo hwclock -r |
Good morning,
I have installed an RTC module with and when trying to read the time it gives me this error.
hwclock -r -v --rtc /dev/rtc1 hwclock from util-linux 2.37.154-c2ca2 System Time: 1625749015.843650 Using the rtc interface to the clock. Last drift adjustment done at 1625749005 seconds after 1969 Last calibration done at 1625749005 seconds after 1969 Hardware clock is on UTC time Assuming hardware clock is kept in UTC time. Waiting for clock tick... ioctl(3, RTC_UIE_ON, 0): Invalid argument Waiting in loop for time from /dev/rtc1 to change hwclock: Timed out waiting for time change. ...synchronization failed
Any idea?
Thanks!
The text was updated successfully, but these errors were encountered: