Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2123

kernel-2.6.18-238.el5.src.rpm

From: Amerigo Wang <amwang@redhat.com>
Date: Thu, 7 May 2009 21:18:37 -0400
Subject: [misc] undefined reference to `__udivdi3'
Message-id: 20090508011934.22045.5523.sendpatchset@localhost.localdomain
O-Subject: [RHEL5 PATCH][V2] BZ499063: undefined reference to `__udivdi3'
Bugzilla: 499063
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>
RH-Nacked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Brian Maly <bmaly@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Eugene Teo <eugene@redhat.com>

BZ499063
https://bugzilla.redhat.com/show_bug.cgi?id=499063

Description:
When I built the latest rhel5 kernel, I got the following compile error:

kernel/built-in.o: In function `getnstimeofday':
(.text+0xb6ae): undefined reference to `__umoddi3'
kernel/built-in.o: In function `getnstimeofday':
(.text+0xb6ce): undefined reference to `__udivdi3'

This is due to that gcc optimizes the loop in timespec_add_ns() into mod
operation, but i686 doesn't support 64-bit integer mod operation, so gcc
will use libgcc's __umoddi3() and __udivdi3.

The patch below prevents gcc to do this optimization.

Upstream Status of this patch:
This patch was already merged into upstream as commit
38332cb98772f5ea757e6486bed7ed0381cb5f98.
See:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blobdiff;f=include/linux/time.h;h=d32ef0ad4c0aaf8964d94abe215c5dbf4dde8aaf;hp=2091a19f1655aab8e5130256f83af4103efa9e3f;hb=38332cb98772f5ea757e6486bed7ed0381cb5f98;hpb=e48af19f56eb47a1f908ee8f16df9d246f955b21

Test Status:
I have tested this patch by compiling, it works fine on i686 with gcc 4.3.2.

Acked-by: Brian Maly <bmaly@redhat.com>

diff --git a/include/linux/time.h b/include/linux/time.h
index a5b7399..49e4708 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -169,6 +169,10 @@ static inline void timespec_add_ns(struct timespec *a, u64 ns)
 {
 	ns += a->tv_nsec;
 	while(unlikely(ns >= NSEC_PER_SEC)) {
+		/* The following asm() prevents the compiler from
+		 * optimising this loop into a modulo operation.  */
+		asm("" : "+r"(ns));
+
 		ns -= NSEC_PER_SEC;
 		a->tv_sec++;
 	}