Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Add __divmoddi4 and __udivmoddi4 for 32-bit arch #636

Merged
merged 1 commit into from
Aug 3, 2017

Conversation

tuxoko
Copy link
Contributor

@tuxoko tuxoko commented Aug 1, 2017

gcc-7 seems to use __udivmoddi4 for 64-bit division on 32-bit arch. This
patch implement them so we don't get undefined reference error.

Signed-off-by: Chunwei Chen [email protected]

gcc-7 seems to use __udivmoddi4 for 64-bit division on 32-bit arch. This
patch implement them so we don't get undefined reference error.

Signed-off-by: Chunwei Chen <[email protected]>
tuxoko pushed a commit to tuxoko/zfs that referenced this pull request Aug 1, 2017
Signed-off-by: Chunwei Chen <[email protected]>
Requires-spl:refs/pull/636/head
@tuxoko
Copy link
Contributor Author

tuxoko commented Aug 1, 2017

openzfs/zfs#6417

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks right to my eye but we should run the splat generic:Unsigned Div-64 Test and generic:Signed Div-64 Test test cases in this environment. While there were written for __divdi3 to verify the math is correct, they should work for __udivmoddi4 too.

@tuxoko
Copy link
Contributor Author

tuxoko commented Aug 2, 2017

I don't have a 32bit with gcc-7 VM around, so I haven't really tested it yet.

@behlendorf
Copy link
Contributor

I don't have a 32bit with gcc-7 VM around, so I haven't really tested it yet.

Me either. I was secretly hoping you'd already set one up. Let me see about spinning one up, I suppose a 32-bit Fedora 26 install is the easiest way to go.

@loli10K
Copy link
Contributor

loli10K commented Aug 2, 2017

I've reproduced openzfs/zfs#6417 on archlinux a couple of days ago, will test this fix in a bit.

EDIT: i also tried to reproduce on a i686 debian (unstable) box with gcc7 without success, i wonder if this has anything to do with the gcc7 version:
Debian:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/7/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 7.1.0-10' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=i686-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 7.1.0 (Debian 7.1.0-10) 

Archlinux:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-linux-gnu/7.1.1/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --disable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 7.1.1 20170630 (GCC) 

Maybe even i386 fedora could have the same problem reproducing?

@loli10K
Copy link
Contributor

loli10K commented Aug 2, 2017

So far so good, got both SPL and ZFS compiled and loaded correctly:

[arch@linux ~]$ nm /lib/modules/4.12.3-1-ARCH/extra/zfs/zfs/zfs.ko | grep div
         U __divdi3
         U __udivdi3
         U __udivmoddi4
[arch@linux ~]$ nm /lib/modules/4.12.3-1-ARCH/extra/spl/spl/spl.ko | grep div
7f98db70 A __crc___divdi3
f0a830e7 A __crc___divmoddi4
30fddf17 A __crc___udivdi3
7c15aa47 A __crc___udivmoddi4
00006970 T __divdi3
00006ac0 T __divmoddi4
0000045b r __kstrtab___divdi3
00000438 r __kstrtab___divmoddi4
00000464 r __kstrtab___udivdi3
00000444 r __kstrtab___udivmoddi4
00000048 r __ksymtab___divdi3
00000050 r __ksymtab___divmoddi4
00000088 r __ksymtab___udivdi3
00000090 r __ksymtab___udivmoddi4
00006740 T __udivdi3
00006a50 T __udivmoddi4
[arch@linux ~]$ lsmod | egrep '(zfs|spl)'
zfs                  2306048  0
zunicode              331776  1 zfs
zavl                   16384  1 zfs
icp                   258048  1 zfs
zcommon                57344  1 zfs
znvpair                53248  2 zcommon,zfs
spl                    73728  4 znvpair,zcommon,zfs,icp

Tests:

[root@linux ~]# splat -t generic:all
------------------------------ Running SPLAT Tests ------------------------------
             generic:ddi_strtoul          Pass  
             generic:ddi_strtol           Pass  
             generic:ddi_strtoull         Pass  
             generic:ddi_strtoll          Pass  
             generic:udivdi3              Pass  
             generic:divdi3               Pass  
[root@linux ~]# objdump -xD /lib/modules/4.12.3-1-ARCH/extra/splat/splat/splat.ko | egrep '(^[0-9a-f ]+[<]|__udivmoddi4|__divmoddi4)'
[...]
00011e60 <splat_generic_test_divdi3>:
			11fee: R_386_PC32	__divmoddi4
00012380 <splat_generic_test_udivdi3>:
			124d7: R_386_PC32	__udivmoddi4
[...]

@behlendorf
Copy link
Contributor

Looks good, thanks for doing this testing and verifying the test case was using the new functions. If you still have the test environment setup the only additional thing I'd suggest would be to run the ZFS Test Suite to verify basic functionality.

@loli10K
Copy link
Contributor

loli10K commented Aug 2, 2017

@behlendorf this is going to take a little more time, my storage is severely underpowered to handle the IO needed to run the full ZTS: i'll report back as soon as it finishes.

@behlendorf
Copy link
Contributor

@loli10K from a practical point of view we should really only need to run a handful of tests from the test suite to verify this is correct (along with the splat test case). Division is used pretty extensively in the ZFS source so if it was fundamentally broken I'd expect things to fall apart almost immediately.

@loli10K
Copy link
Contributor

loli10K commented Aug 2, 2017

@behlendorf it seems __udivmoddi4() is only emitted twice in vdev_raidz_map_alloc(). I've not found any trace of __divmoddi4().

noinline raidz_map_t *
vdev_raidz_map_alloc(zio_t *zio, uint64_t ashift, uint64_t dcols,
    uint64_t nparity)
{
        raidz_map_t *rm;
        /* The starting RAIDZ (parent) vdev sector of the block. */
        uint64_t b = zio->io_offset >> ashift;
        /* The zio's size in units of the vdev's minimum sector size. */
        uint64_t s = zio->io_size >> ashift;
        /* The first column for this stripe. */
        uint64_t f = b % dcols;
        /* The starting byte offset on each child vdev. */
        uint64_t o = (b / dcols) << ashift; /* <=== __udivmoddi4() */
        uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot;
        uint64_t off = 0;

        /*
         * "Quotient": The number of data sectors for this stripe on all but
         * the "big column" child vdevs that also contain "remainder" data.
         */
        q = s / (dcols - nparity);  /* <=== __udivmoddi4() */

The ZTS is running smoothly so far:

--- Configuration ---
Runfile:         /usr/share/zfs/runfiles/linux.run
STF_TOOLS:       /usr/share/zfs/test-runner
STF_SUITE:       /usr/share/zfs/zfs-tests
STF_PATH:        /var/tmp/constrained_path.AtjL
FILEDIR:         /tmp
FILES:           /tmp/file-vdev0 /tmp/file-vdev1 /tmp/file-vdev2
LOOPBACKS:       
DISKS:           vdb vdc vdd vde
NUM_DISKS:       4
FILESIZE:        4G
Keep pool(s):    rpool
Missing util(s): pax setenforce umask wait 

/usr/share/zfs/test-runner/bin/test-runner.py  -c /usr/share/zfs/runfiles/linux.run -i /usr/share/zfs/zfs-tests
Test: /usr/share/zfs/zfs-tests/tests/functional/acl/posix/setup (run as root) [00:03] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/acl/posix/posix_003_pos (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/acl/posix/cleanup (run as root) [00:01] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/atime/setup (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/atime/atime_001_pos (run as root) [00:10] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/atime/atime_002_neg (run as root) [00:06] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/atime/atime_003_pos (run as root) [00:10] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/atime/cleanup (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/setup (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_001_pos (run as root) [00:22] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_002_neg (run as root) [00:39] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_003_pos (run as root) [00:34] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_004_neg (run as root) [00:26] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_005_neg (run as root) [01:35] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_006_pos (run as root) [01:55] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_007_pos (run as root) [00:01] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/bootfs_008_pos (run as root) [00:30] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/bootfs/cleanup (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/setup (run as root) [01:51] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_001_pos (run as root) [00:44] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_002_pos (run as root) [00:19] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_003_pos (run as root) [00:22] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_004_neg (run as root) [00:46] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_005_neg (run as root) [00:32] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_006_pos (run as root) [01:16] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_007_neg (run as root) [00:00] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_008_neg (run as root) [00:34] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_009_pos (run as root) [00:27] [PASS]
Test: /usr/share/zfs/zfs-tests/tests/functional/cache/cache_010_neg (run as root) [00:00] [SKIP]

@behlendorf
Copy link
Contributor

That's interesting. Perhaps the other cases still end up using __udivdi3.

@behlendorf
Copy link
Contributor

@loli10K how does the testing look?

@loli10K
Copy link
Contributor

loli10K commented Aug 3, 2017

@behlendorf i'll be back in ~1h to check, i left it running at home this morning.

@loli10K
Copy link
Contributor

loli10K commented Aug 3, 2017

You probably won't believe it because i don't do it myself, but the test suite is still running, output here: https://gist.github.com/loli10K/4ad76bd8f5c4f4cf943d953a6ec90fa1.

Most of these failures must be unrelated, it's just my home lab being slow.

I'm sorry i've kept you waiting, LGTM.

@behlendorf
Copy link
Contributor

No problem! Thanks for volunteering a system to put this patch through its paces. The test results are about what I'd expect so LGTM. I'll get it merged right away.

@behlendorf behlendorf merged commit 6ecfd2b into openzfs:master Aug 3, 2017
tonyhutter pushed a commit that referenced this pull request Aug 3, 2017
gcc-7 seems to use __udivmoddi4 for 64-bit division on 32-bit arch. This
patch implement them so we don't get undefined reference error.

Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: loli10K <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes openzfs/zfs#6417
Closes #636
Fabian-Gruenbichler pushed a commit to Fabian-Gruenbichler/spl that referenced this pull request Sep 6, 2017
gcc-7 seems to use __udivmoddi4 for 64-bit division on 32-bit arch. This
patch implement them so we don't get undefined reference error.

Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: loli10K <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes openzfs/zfs#6417
Closes openzfs#636
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants