* Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 @ 2010-08-12 20:18 Larry Finger 2010-08-12 20:26 ` Linus Torvalds 2010-08-12 20:52 ` john stultz 0 siblings, 2 replies; 8+ messages in thread From: Larry Finger @ 2010-08-12 20:18 UTC (permalink / raw) To: Jason Wessel, John Stultz; +Cc: Linus Torvalds, LKML Guys, With the above commit, building an i386 version of the kernel results in the following from the build: kernel/built-in.o: In function `logarithmic_accumulation': /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to `__umoddi3' /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to `__udivdi3' make: *** [.tmp_vmlinux1] Error 1 Reverting the patch allows the system to build correctly. Larry ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-12 20:18 Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 Larry Finger @ 2010-08-12 20:26 ` Linus Torvalds 2010-08-12 20:41 ` Larry Finger 2010-08-12 20:52 ` john stultz 1 sibling, 1 reply; 8+ messages in thread From: Linus Torvalds @ 2010-08-12 20:26 UTC (permalink / raw) To: Larry Finger; +Cc: Jason Wessel, John Stultz, LKML On Thu, Aug 12, 2010 at 1:18 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: > > With the above commit, building an i386 version of the kernel results in the > following from the build: > > kernel/built-in.o: In function `logarithmic_accumulation': > /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > `__umoddi3' > /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > `__udivdi3' > make: *** [.tmp_vmlinux1] Error 1 > > Reverting the patch allows the system to build correctly. Damn. It's your compiler turning a while-loop into a divide. Which likely isn't even an optimization, but whatever. John: I think that while-loop needs to be something like if (raw_nsecs >= NSEC_PER_SEC) { u64 raw_secs = raw_nsecs; raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); raw_time.tv_sec += taw_secs; } raw_time.tc_nsec = raw_nsecs; which is sad and overly complicated, but the simple thing seems to get messed up by the compiler. Untested. Maybe I got the complex do_div() semantics wrong. Somebody needs to check. Linus ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-12 20:26 ` Linus Torvalds @ 2010-08-12 20:41 ` Larry Finger 2010-08-13 8:45 ` Mikael Pettersson 0 siblings, 1 reply; 8+ messages in thread From: Larry Finger @ 2010-08-12 20:41 UTC (permalink / raw) To: Linus Torvalds; +Cc: Jason Wessel, John Stultz, LKML On 08/12/2010 03:26 PM, Linus Torvalds wrote: > On Thu, Aug 12, 2010 at 1:18 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: >> >> With the above commit, building an i386 version of the kernel results in the >> following from the build: >> >> kernel/built-in.o: In function `logarithmic_accumulation': >> /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to >> `__umoddi3' >> /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to >> `__udivdi3' >> make: *** [.tmp_vmlinux1] Error 1 >> >> Reverting the patch allows the system to build correctly. > > Damn. It's your compiler turning a while-loop into a divide. Which > likely isn't even an optimization, but whatever. > > John: I think that while-loop needs to be something like > > if (raw_nsecs >= NSEC_PER_SEC) { > u64 raw_secs = raw_nsecs; > raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); > raw_time.tv_sec += taw_secs; > } > raw_time.tc_nsec = raw_nsecs; > > which is sad and overly complicated, but the simple thing seems to get > messed up by the compiler. > > Untested. Maybe I got the complex do_div() semantics wrong. Somebody > needs to check. I'll try it. The system with the problem has gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]. That is on a 64-bit system cross compiling with ARCH=i386. The real 32-bit system with gcc (SUSE Linux) 4.5.0 20100604 [gcc-4_5-branch revision 160292] builds OK. It just wasn't finished when I wrote the first message. Larry ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-12 20:41 ` Larry Finger @ 2010-08-13 8:45 ` Mikael Pettersson 0 siblings, 0 replies; 8+ messages in thread From: Mikael Pettersson @ 2010-08-13 8:45 UTC (permalink / raw) To: Larry Finger; +Cc: Linus Torvalds, Jason Wessel, John Stultz, LKML Larry Finger writes: > On 08/12/2010 03:26 PM, Linus Torvalds wrote: > > On Thu, Aug 12, 2010 at 1:18 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: > >> > >> With the above commit, building an i386 version of the kernel results in the > >> following from the build: > >> > >> kernel/built-in.o: In function `logarithmic_accumulation': > >> /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > >> `__umoddi3' > >> /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > >> `__udivdi3' > >> make: *** [.tmp_vmlinux1] Error 1 > >> > >> Reverting the patch allows the system to build correctly. > > > > Damn. It's your compiler turning a while-loop into a divide. Which > > likely isn't even an optimization, but whatever. > > > > John: I think that while-loop needs to be something like > > > > if (raw_nsecs >= NSEC_PER_SEC) { > > u64 raw_secs = raw_nsecs; > > raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); > > raw_time.tv_sec += taw_secs; > > } > > raw_time.tc_nsec = raw_nsecs; > > > > which is sad and overly complicated, but the simple thing seems to get > > messed up by the compiler. > > > > Untested. Maybe I got the complex do_div() semantics wrong. Somebody > > needs to check. > > I'll try it. The system with the problem has gcc (SUSE Linux) 4.3.2 > [gcc-4_3-branch revision 141291]. That is on a 64-bit system cross compiling > with ARCH=i386. > > The real 32-bit system with gcc (SUSE Linux) 4.5.0 20100604 [gcc-4_5-branch > revision 160292] builds OK. It just wasn't finished when I wrote the first message. The loops-turns-into-div is a known bug in early gcc-4.3 releases, possibly only with -Os. It's fixed in 4.4 and 4.3.latest. I can probably dig up the gcc PR number if needed. /Mikael ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-12 20:18 Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 Larry Finger 2010-08-12 20:26 ` Linus Torvalds @ 2010-08-12 20:52 ` john stultz 2010-08-13 3:17 ` Larry Finger 1 sibling, 1 reply; 8+ messages in thread From: john stultz @ 2010-08-12 20:52 UTC (permalink / raw) To: Larry Finger; +Cc: Jason Wessel, Linus Torvalds, LKML On Thu, 2010-08-12 at 15:18 -0500, Larry Finger wrote: > Guys, > > With the above commit, building an i386 version of the kernel results in the > following from the build: > > kernel/built-in.o: In function `logarithmic_accumulation': > /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > `__umoddi3' > /home/finger/linux-realtek/kernel/time/timekeeping.c:715: undefined reference to > `__udivdi3' > make: *** [.tmp_vmlinux1] Error 1 > > Reverting the patch allows the system to build correctly. Ugh. I'm surprised it picks *this* loop to optimize instead of the similar one right above. I'm guessing its the local raw_nsecs value, but whatever. Also surprised Jason's testing didn't hit this issue, but its probably a gcc version thing. Regardless, I clearly need to give i386 more love in my testing. My profuse apologies. As suggested by Linus, here's the do_div explicit version. It builds ok on i386 & x86_64, but I have not yet tested it. Larry, Jason: Could you verify it works for you (and avoids the original issue)? thanks -john >From 70b106aaaa1de81a635bbd7ea6edc244ba098d7e Mon Sep 17 00:00:00 2001 From: John Stultz <johnstul@us.ibm.com> Date: Thu, 12 Aug 2010 13:45:28 -0700 Subject: [PATCH] time: Workaround gcc loop optimization that causes 64bit div errors Some versions of gcc apparently aggressively optimize the raw time accumulation loop, replacing it with a divide. On 32bit systems, this causes the following link errors: undefined reference to `__umoddi3' undefined reference to `__udivdi3' This patch replaces the accumulation loop with a do_div, as suggested by Linus. Signed-off-by: John Stultz <johnstul@us.ibm.com> --- kernel/time/timekeeping.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index dc54b72..d0ef5aa 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -710,9 +710,10 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) /* Accumulate raw time */ raw_nsecs = timekeeper.raw_interval << shift; raw_nsecs += raw_time.tv_nsec; - while (raw_nsecs >= NSEC_PER_SEC) { - raw_nsecs -= NSEC_PER_SEC; - raw_time.tv_sec++; + if (raw_nsecs >= NSEC_PER_SEC) { + u64 raw_secs = raw_nsecs; + raw_nsecs = do_div(raw_secs, NSEC_PER_SEC); + raw_time.tv_sec += raw_secs; } raw_time.tv_nsec = raw_nsecs; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-12 20:52 ` john stultz @ 2010-08-13 3:17 ` Larry Finger 2010-08-13 7:30 ` john stultz 0 siblings, 1 reply; 8+ messages in thread From: Larry Finger @ 2010-08-13 3:17 UTC (permalink / raw) To: john stultz; +Cc: Jason Wessel, Linus Torvalds, LKML On 08/12/2010 03:52 PM, john stultz wrote: > > Ugh. I'm surprised it picks *this* loop to optimize instead of the > similar one right above. I'm guessing its the local raw_nsecs value, but > whatever. Also surprised Jason's testing didn't hit this issue, but its > probably a gcc version thing. > > Regardless, I clearly need to give i386 more love in my testing. > My profuse apologies. > > As suggested by Linus, here's the do_div explicit version. It builds ok > on i386 & x86_64, but I have not yet tested it. > > Larry, Jason: Could you verify it works for you (and avoids the original > issue)? This one builds for me with both compilers. It appears to run OK. As to the original issue - I don't think I ever saw the problem. I'll leave that question for Jason. Larry ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-13 3:17 ` Larry Finger @ 2010-08-13 7:30 ` john stultz 2010-08-13 11:53 ` Jason Wessel 0 siblings, 1 reply; 8+ messages in thread From: john stultz @ 2010-08-13 7:30 UTC (permalink / raw) To: Larry Finger; +Cc: Jason Wessel, Linus Torvalds, LKML On Thu, 2010-08-12 at 22:17 -0500, Larry Finger wrote: > On 08/12/2010 03:52 PM, john stultz wrote: > > > > Ugh. I'm surprised it picks *this* loop to optimize instead of the > > similar one right above. I'm guessing its the local raw_nsecs value, but > > whatever. Also surprised Jason's testing didn't hit this issue, but its > > probably a gcc version thing. > > > > Regardless, I clearly need to give i386 more love in my testing. > > My profuse apologies. > > > > As suggested by Linus, here's the do_div explicit version. It builds ok > > on i386 & x86_64, but I have not yet tested it. > > > > Larry, Jason: Could you verify it works for you (and avoids the original > > issue)? > > This one builds for me with both compilers. It appears to run OK. As to the > original issue - I don't think I ever saw the problem. I'll leave that question > for Jason. Thanks for the testing! I also managed to trigger the link issue with a 64bit gcc-4.3 cross compiling to 32bit. However both 32bit and 64bit gcc-4.4 didn't trigger the link issue, so it looks like its fixed in gcc. Regardless, after my own testing, the change looks good to me. Raw time is accumulating properly relative to monotonic time. Assuming Jason has no complaints it should be able to be pushed in. Thanks again for the quick reporting and verification. -john ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 2010-08-13 7:30 ` john stultz @ 2010-08-13 11:53 ` Jason Wessel 0 siblings, 0 replies; 8+ messages in thread From: Jason Wessel @ 2010-08-13 11:53 UTC (permalink / raw) To: john stultz; +Cc: Larry Finger, Linus Torvalds, LKML On 08/13/2010 02:30 AM, john stultz wrote: > On Thu, 2010-08-12 at 22:17 -0500, Larry Finger wrote: > >> On 08/12/2010 03:52 PM, john stultz wrote: >> >>> Ugh. I'm surprised it picks *this* loop to optimize instead of the >>> similar one right above. I'm guessing its the local raw_nsecs value, but >>> whatever. Also surprised Jason's testing didn't hit this issue, but its >>> probably a gcc version thing. >>> >>> Regardless, I clearly need to give i386 more love in my testing. >>> My profuse apologies. >>> >>> As suggested by Linus, here's the do_div explicit version. It builds ok >>> on i386 & x86_64, but I have not yet tested it. >>> >>> Larry, Jason: Could you verify it works for you (and avoids the original >>> issue)? >>> >> This one builds for me with both compilers. It appears to run OK. As to the >> original issue - I don't think I ever saw the problem. I'll leave that question >> for Jason. >> > > Thanks for the testing! > > I also managed to trigger the link issue with a 64bit gcc-4.3 cross > compiling to 32bit. However both 32bit and 64bit gcc-4.4 didn't trigger > the link issue, so it looks like its fixed in gcc. > > Regardless, after my own testing, the change looks good to me. Raw time > is accumulating properly relative to monotonic time. > > Assuming Jason has no complaints it should be able to be pushed in. > > No complaints here. The edge case remains solved on the low MHZ 32 bit system. The reason I never saw any problem in all my test configurations was that gcc 4.4 is the oldest compiler I have in any of the configurations I am using. I could have been more specific in my original mail on the subject but it was tested with a 32bit cross compiler as well as a 64bit cross compiler. Many thanks to all who helped draw this odd ball case to closure. Jason. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-08-13 11:54 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-08-12 20:18 Problem with commit deda2e81961e96be4f2c09328baca4710a2fd1a0 Larry Finger 2010-08-12 20:26 ` Linus Torvalds 2010-08-12 20:41 ` Larry Finger 2010-08-13 8:45 ` Mikael Pettersson 2010-08-12 20:52 ` john stultz 2010-08-13 3:17 ` Larry Finger 2010-08-13 7:30 ` john stultz 2010-08-13 11:53 ` Jason Wessel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox