I would like to be able to devide 64bit numbers in a kernel module,
but I get unresolved symbols when trying to insmod.
Does anyone have any ideas how to get around this little issue
(without the obvious of casting the hell out of all my __u64s
when doing division and throwing away precision.)?
Thanks,
Ben
--
Ben Greear <[email protected]> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear
On Fri, 19 Apr 2002, Ben Greear wrote:
| I would like to be able to devide 64bit numbers in a kernel module,
| but I get unresolved symbols when trying to insmod.
|
| Does anyone have any ideas how to get around this little issue
| (without the obvious of casting the hell out of all my __u64s
| when doing division and throwing away precision.)?
Did you look at linux/include/asm*/div64.h ?
--
~Randy
On Apr 19, 2002 14:03 -0700, Ben Greear wrote:
> I would like to be able to devide 64bit numbers in a kernel module,
> but I get unresolved symbols when trying to insmod.
>
> Does anyone have any ideas how to get around this little issue
> (without the obvious of casting the hell out of all my __u64s
> when doing division and throwing away precision.)?
When you talk about precision, it makes me think you want to have
a floating-point divide. In fact, no floating-point math can be
done in the kernel.
Cheers, Andreas
--
Andreas Dilger
http://www-mddsp.enel.ucalgary.ca/People/adilger/
http://sourceforge.net/projects/ext2resize/
Randy.Dunlap wrote:
> On Fri, 19 Apr 2002, Ben Greear wrote:
>
> | I would like to be able to devide 64bit numbers in a kernel module,
> | but I get unresolved symbols when trying to insmod.
> |
> | Does anyone have any ideas how to get around this little issue
> | (without the obvious of casting the hell out of all my __u64s
> | when doing division and throwing away precision.)?
>
> Did you look at linux/include/asm*/div64.h ?
I changed my code to look like this:
char *p = info->pg_result;
__u64 mbps = 0;
__u64 t1 = (info->pg_sofar*1000);
__u64 t2 = do_div(total, 1000);
__u64 pps = 0; /* do_div(t1, t2); */
t1 = (info->pg_sofar * 1000);
mbps = 0;/* do_div(t1, t2); */
/* mbps *= info->pkt_size; */
This code will load w/out problems. However, if I uncomment the do_div
on the line: __u64 pps = 0; /* do_div(t1, t2); */
then I get another unresolved symbol:
__umodi3
I'm guessing that there is some optimization the compiler is doing that
is using the mod operator somehow, but I am unsure about how to work around
this.
Thanks,
Ben
>
>
--
Ben Greear <[email protected]> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear
From: Ben Greear <[email protected]>
Date: Fri, 19 Apr 2002 14:58:10 -0700
then I get another unresolved symbol:
__umodi3
Someone needs to add this routine under arch/sparc/lib/
I'm guessing that there is some optimization the compiler is doing that
is using the mod operator somehow, but I am unsure about how to work around
this.
"guessing"? Have a look the definition of do_div in asm-sparc/div64.h
it explicitly does a mod operation :-)
David S. Miller wrote:
> From: Ben Greear <[email protected]>
> Date: Fri, 19 Apr 2002 14:58:10 -0700
>
> then I get another unresolved symbol:
> __umodi3
>
> Someone needs to add this routine under arch/sparc/lib/
>
> I'm guessing that there is some optimization the compiler is doing that
> is using the mod operator somehow, but I am unsure about how to work around
> this.
>
> "guessing"? Have a look the definition of do_div in asm-sparc/div64.h
> it explicitly does a mod operation :-)
Yeah, I just noticed that. What good is do_div if it calls %
which is also not resolved??? I can see why you had all the
hi/lo crap in the pktgen.c now :)
(I'm looking in asm-i386/div64.h, btw, since I'm running on x86
right now.)
--
Ben Greear <[email protected]> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear
Also, for what it's worth, do_div on x86 seems to corrupt arguments
given to it, and may do other screwy things. I'm just going to
go back to casting and let user-space do any precise division.
David S. Miller wrote:
> From: Ben Greear <[email protected]>
> Date: Fri, 19 Apr 2002 14:58:10 -0700
>
> then I get another unresolved symbol:
> __umodi3
>
> Someone needs to add this routine under arch/sparc/lib/
>
> I'm guessing that there is some optimization the compiler is doing that
> is using the mod operator somehow, but I am unsure about how to work around
> this.
>
> "guessing"? Have a look the definition of do_div in asm-sparc/div64.h
> it explicitly does a mod operation :-)
>
>
--
Ben Greear <[email protected]> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear
do_div(n, base) is defined (in some versions of the div64.h
files) to be:
n = n / base; return rem;
so the first arg is modified.
~Randy
On Fri, 19 Apr 2002, Ben Greear wrote:
| Also, for what it's worth, do_div on x86 seems to corrupt arguments
| given to it, and may do other screwy things. I'm just going to
| go back to casting and let user-space do any precise division.
|
| David S. Miller wrote:
|
| > From: Ben Greear <[email protected]>
| > Date: Fri, 19 Apr 2002 14:58:10 -0700
| >
| > then I get another unresolved symbol:
| > __umodi3
| >
| > Someone needs to add this routine under arch/sparc/lib/
| >
| > I'm guessing that there is some optimization the compiler is doing that
| > is using the mod operator somehow, but I am unsure about how to work around
| > this.
| >
| > "guessing"? Have a look the definition of do_div in asm-sparc/div64.h
| > it explicitly does a mod operation :-)
At Fri, 19 Apr 2002 14:03:46 -0700,
Ben Greear wrote:
> I would like to be able to devide 64bit numbers in a kernel module,
> but I get unresolved symbols when trying to insmod.
>
> Does anyone have any ideas how to get around this little issue
> (without the obvious of casting the hell out of all my __u64s
> when doing division and throwing away precision.)?
Your architecture is i386? *Ad-hoc* solution is linking libgcc,
thus you designate the following parameter during linking time:
`gcc -print-libgcc-file-name`
In addition, some architecture (sh, parisc) links libgcc.a.
Look at arch/{sh,parisc}/Makefile. (I heard such architecture's
gcc need libgcc for the basic calculation.)
-- gotom
On Fri, 19 Apr 2002, Ben Greear wrote:
> Also, for what it's worth, do_div on x86 seems to corrupt arguments
> given to it, and may do other screwy things. I'm just going to
> go back to casting and let user-space do any precise division.
Or consider the code from:
http://nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
Adapted as follows...
Chris
---
#define DIV 0
#define REM 1
// Function copied/adapted/optimized from:
//
// nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
//
// Copyright 1994, University of Cambridge Computer Laboratory
// All Rights Reserved.
//
// TODO: When running on a 64-bit CPU platform, this should no longer be
// TODO: necessary.
//
s64 divremdi3(s64 x,
s64 y,
int type)
{
u64 a = (x < 0) ? -x : x;
u64 b = (y < 0) ? -y : y;
u64 res = 0, d = 1;
if (b > 0) while (b < a) b <<= 1, d <<= 1;
do
{
if ( a >= b ) a -= b, res += d;
b >>= 1;
d >>= 1;
}
while (d);
if (DIV == type)
{
return (((x ^ y) & (1ll<<63)) == 0) ? res : -(s64)res;
}
else
{
return ((x & (1ll<<63)) == 0) ? a : -(s64)a;
}
}
Hi,
I threw that function into a little procfs test module
that I have and it worked nicely. Thanks.
~Randy
On Sat, 20 Apr 2002, Chris Caputo wrote:
| On Fri, 19 Apr 2002, Ben Greear wrote:
| > Also, for what it's worth, do_div on x86 seems to corrupt arguments
| > given to it, and may do other screwy things. I'm just going to
| > go back to casting and let user-space do any precise division.
|
| Or consider the code from:
|
| http://nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
|
| Adapted as follows...
|
| Chris
|
| ---
|
| // Function copied/adapted/optimized from:
| //
| // nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
| //
| // Copyright 1994, University of Cambridge Computer Laboratory
| // All Rights Reserved.
| //
| // TODO: When running on a 64-bit CPU platform, this should no longer be
| // TODO: necessary.
| -
I run a 2.4.17 system with high filesystem load and experience the
following problem:
after running some hours with ext2 I got a lot of these messages:
Apr 24 22:19:00 linux kernel: swap_free: Bad swap offset entry 04000000
if I do a swapoff (swap is at /dev/hda6) they turn to:
Apr 24 22:20:29 linux kernel: swap_free: Unused swap file entry 04000000
..and get back to "Bad swap offset entry" if I do the swapon again
Before that I run the machine with ext3 where even worse things happened.
I got a lot of these messages before the machine hangs some hours later:
Apr 22 04:01:04 linux kernel: Unable to handle kernel paging request at
virtual address e71d6478
Apr 22 04:01:04 linux kernel: printing eip:
Apr 22 04:01:04 linux kernel: c013ede8
Apr 22 04:01:04 linux kernel: *pde = 00000000
Apr 22 04:01:04 linux kernel: Oops: 0002
Apr 22 04:01:04 linux kernel: CPU: 0
Apr 22 04:01:04 linux kernel: EIP: 0010:[prune_dcache+24/296] Not
tainted
Apr 22 04:01:04 linux kernel: EFLAGS: 00210212
Apr 22 04:01:04 linux kernel: eax: c027c93c ebx: c71d63f8 ecx: c71d6040
edx: e71d6478
Apr 22 04:01:04 linux kernel: esi: c71d62e0 edi: 00000000 ebp: 00007e35
esp: c3771e04
Apr 22 04:01:04 linux kernel: ds: 0018 es: 0018 ss: 0018
Apr 22 04:01:04 linux kernel: Process mogrify (pid: 913, stackpage=c3771000)
Apr 22 04:01:04 linux kernel: Stack: 00000004 000001d2 00000020 00000006
c013f14b 0000a4d0 c01290e0 00000006
Apr 22 04:01:05 linux kernel: 000001d2 00000006 000001d2 c027bc48
c027bc48 c027bc48 c012913c 00000020
Apr 22 04:01:05 linux kernel: c3770000 00000100 00000000 c0129942
c027bdc4 00000100 00000010 00000000
Apr 22 04:01:05 linux kernel: Call Trace: [shrink_dcache_memory+27/52]
[shrink_caches+108/140] [try_to_free_pages+60/92] [balance_classzone+78/360]
[__alloc_pages+262/356]
Apr 22 04:01:05 linux kernel: [_alloc_pages+22/24]
[do_anonymous_page+52/228] [do_no_page+51/400] [handle_mm_fault+82/176]
[do_page_fault+352/1176] [do_page_fault+0/1176]
Apr 22 04:01:05 linux kernel: [update_wall_time+11/52] [timer_bh+36/604]
[do_timer+63/108] [timer_interrupt+95/264] [bh_action+26/64]
[tasklet_hi_action+68/100]
Apr 22 04:01:05 linux kernel: [do_softirq+90/164] [error_code+52/60]
Apr 22 04:01:05 linux kernel:
Apr 22 04:01:05 linux kernel: Code: 89 02 89 1b 89 5b 04 8d 73 e8 8b 46 54
a8 08 74 27 24 f7 89
Any ideas/help??
Thanks in advance
Robert
On Thu, 25 Apr 2002, Robert Schelander wrote:
> Apr 24 22:19:00 linux kernel: swap_free: Bad swap offset entry 04000000
> Apr 24 22:20:29 linux kernel: swap_free: Unused swap file entry 04000000
> Apr 22 04:01:04 linux kernel: Unable to handle kernel paging request at
> virtual address e71d6478
> Apr 22 04:01:04 linux kernel: EIP: 0010:[prune_dcache+24/296] Not
> tainted
> Apr 22 04:01:04 linux kernel: eax: c027c93c ebx: c71d63f8 ecx: c71d6040
> edx: e71d6478
> Apr 22 04:01:04 linux kernel: esi: c71d62e0 edi: 00000000 ebp: 00007e35
These look _very_ much like single bit memory errors.
Please run memtest86 overnight, it will probably show your memory is bad.
Hugh