Re: FR1-2.15b and unknown symbol __udivdi3

"Peter T. Breuer" <[email protected]> Fri, 17 Feb 2006 08:43:45 +0100 (MET)
Newsgroups gmane.linux.enbd.general
Message-ID <[email protected]>
"Also sprach Graham Clinch:"
> I've tried to use the FR1-2.15b patch against 2.6.8, and the patch  
> applies happily, and indeed, compiles happily.  However, when I try  
> to modprobe md:

What architecture? And compiler?

> dtfsa301:~# modprobe md
> FATAL: Error inserting md (/lib/modules/2.6.8/kernel/drivers/md/ 
> md.ko): Unknown symbol in module, or unknown parameter (see dmesg)
> 
> dmesg then shows:
> 
> md: Unknown symbol __udivdi3

That's a long long division :).

> This looks similar to the issue from a month or so ago
> (Subj: [ENBD] [gmane.network.aoe.aoetools.general] enbd and 4TB)
> so I set out hunting for divisions used within the patch, but I can't  
> find anything obvious.

It's hard. It can be a modulus operation. It can be a functon that has
been inlined.

> dtfsa301:~# nm /lib/modules/2.6.8/kernel/drivers/md/md.ko | grep udiv
>           U __udivdi3
> dtfsa301:~#
> 
> So it's definitely somewhere within md, rather than a dependency.
> 
> Actually, might it be the line
> 
> disk_events <<= 32;

Shifts are not optimised to division, and this one would be a
multiplicaton.

> (Line 1786 of the patch), as guess the compiler (gcc version 3.3.5  
> (Debian 1:3.3.5-13)) may be optimizing it to a lot of divide-by- 
> twos.  My C is rusty, so even if it is this line, I'm not sure what  
> would make a good fixup..
> 
> I've tried using md (raid1) without the FR1 patch applied, and  
> everything seems happy, the module loads and I can control arrays, so  
> I'm guessing it's got to be somewhere in the patch
> 
> Any hints welcome!

Well, I'd just be grepping for a "/" or a "%". You should be able to
decompile the object module with objdump -disassemble and find out which
function the udivdi3 is in. You can locate roughly where in the code it
is by loking for calls to external routines in the disassembly and the
source code. Then one can locate the line precisely by commmenting out
bits of source and recmpiling.

I'll just have a read of the md.c part of that patch ...

I see nothing. 

Oh, it MUST be this line:

   realspeed = (j - mddev->resync_mark_cnt - atomic_read(&md_throttle[mddev->md_minor]))/2/((jiffies-mddev->resync_mark)/HZ +1) +1;

I see that I changed it in 2.17  to

    realspeed = ((unsigned long)(j - mddev->resync_mark_cnt - atomic_read(&md_throttle[mddev->md_minor])))/2/((jiffies-mddev->resync_mark)/HZ +1) +1;

Even though I don't see a long long, why else would I have done that
recasting?

Peter