Bug 29142 - Kernel unaligned access at btrfs_csum_final+0x38/0x3c (SPARC64)
Summary: Kernel unaligned access at btrfs_csum_final+0x38/0x3c (SPARC64)
Status: RESOLVED CODE_FIX
Alias: None
Product: File System
Classification: Unclassified
Component: btrfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_btrfs@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-14 21:35 UTC by Adrien Dessemond
Modified: 2012-08-16 10:55 UTC (History)
2 users (show)

See Also:
Kernel Version: 2.6.38-rc4
Subsystem:
Regression: No
Bisected commit-id:


Attachments
use put_unaligned when arch does not have efficient unaligned access (872 bytes, patch)
2011-03-03 11:49 UTC, David Sterba
Details | Diff

Description Adrien Dessemond 2011-02-14 21:35:09 UTC
Btrfs on SPARC64 reports lots of warning about non aligned address in btrfs_csum_final :


[ 1523.941667] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1523.961335] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1554.143978] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1554.158473] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1589.331232] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1589.338031] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1619.461949] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1619.479549] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1654.815533] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1654.827057] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1685.169193] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
[ 1685.176572] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs]
etc etc etc

No other messages about btrfs are logged except this only one. Kernel has been compiled with "Optimize for size", will try with a less aggressive option.
Comment 1 David Sterba 2011-03-03 11:49:51 UTC
Created attachment 49992 [details]
use put_unaligned when arch does not have efficient unaligned access

Can you please retest with this patch? Thanks.
Comment 2 Adrien Dessemond 2011-03-04 01:38:54 UTC
With the patch applied, I am not able to mount a btrfs partition:

[ 2630.494725] ------------[ cut here ]------------
[ 2630.494897] WARNING: at fs/btrfs/extent_io.c:3706 write_extent_buffer+0xc8/0x128 [btrfs]()
[ 2630.494940] Modules linked in: btrfs lzo_decompress lzo_compress crc32c libcrc32c ipv6 dm_mod sg tg3 libphy
[ 2630.495019] Call Trace:
[ 2630.495132]  [000000001018d83c] write_extent_buffer+0xc8/0x128 [btrfs]
[ 2630.495250]  [0000000010195210] btrfs_read_sys_array+0x3c/0x314 [btrfs]
[ 2630.495360]  [000000001015e3f8] open_ctree+0xf18/0x1864 [btrfs]
[ 2630.495457]  [0000000010135014] btrfs_mount+0x22c/0x430 [btrfs]
[ 2630.495483]  [00000000004ef1bc] vfs_kern_mount+0x50/0x144
[ 2630.495500]  [00000000004ef2f0] do_kern_mount+0x24/0xbc
[ 2630.495524]  [0000000000507b8c] do_mount+0x804/0x86c
[ 2630.495546]  [00000000005261d0] compat_sys_mount+0x1c8/0x20c
[ 2630.495569]  [0000000000406114] linux_sparc_syscall32+0x34/0x40
[ 2630.495582] ---[ end trace 0ebe577f3ebd0623 ]---
[ 2630.502394] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0
[ 2630.508382] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0
[ 2630.512349] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0
[ 2630.512393] btrfs: failed to read chunk root on sdb1
[ 2630.518917] btrfs: open_ctree failed
Comment 3 David Sterba 2011-03-15 15:48:16 UTC
I do not know for sure, but I suspect some type mismatch inside

put_unaligned(~cpu_to_le32(crc), result);

where the ~(...) expression could be upcasted to long and then wrongly converted back to u32. The value 1C000000 has one byte equal to the expected checksum.

Please test this patch. Thanks.

@@ -198,7 +198,12 @@ u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len)

 void btrfs_csum_final(u32 crc, char *result)
 {
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
        *(__le32 *)result = ~cpu_to_le32(crc);
+#else
+       crc = ~cpu_to_le32(crc);
+       put_unaligned(crc, result);
+#endif
 }

 /*
Comment 4 Adrien Dessemond 2011-03-16 03:20:28 UTC
We are approaching! If I have that code:

void btrfs_csum_final(u32 crc, char *result)
{
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
        *(__le32 *)result = ~cpu_to_le32(crc);
#else
        __le32 r = ~cpu_to_le32(crc);
        printk("btrfs_csum_data(): ~crc=%x / crc=%x\n", r, crc);
        put_unaligned(r, result);
#endif
}

I have this in the system log:

[ 3376.441367] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c
[ 3376.441388] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0
[ 3376.446227] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c
[ 3376.446249] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0
[ 3376.451327] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c
[ 3376.451349] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0
[ 3376.451394] btrfs: failed to read chunk root on sdb1
[ 3376.457137] btrfs: open_ctree failed

so my 'r' variable holds the correct value, the troubles seems to come from 'result' the 96 in 0x96000000 seems to be the 96 of 0xD3DA8696. SPARC64 are big endian CPU, I suspect something related to byte order and/or alignment of the resulting 32 bit integer.
Comment 5 David Sterba 2011-03-16 09:42:24 UTC
The crc argument comes in CPU order and finally should be stored in LE order. The bitwise not does not affect endianity.

Under these assumptions, I think this should work:

put_unaligned_le32(~crc, result)

(ie. without the cpu_to_le32 conversion).

Please test, thanks!
Comment 6 Adrien Dessemond 2011-03-16 11:05:59 UTC
Problem solved! Altought I still have still have the warning (linux-2.6.38 final) :

[  945.426694] ------------[ cut here ]------------
[  945.426857] WARNING: at fs/btrfs/extent_io.c:3787 write_extent_buffer+0xc8/0x128 [btrfs]()
[  945.426872] Modules linked in: btrfs lzo_decompress lzo_compress crc32c libcrc32c ipv6 dm_mod tg3 sg libphy
[  945.426917] Call Trace:
[  945.427062]  [0000000010217ad0] write_extent_buffer+0xc8/0x128 [btrfs]
[  945.427229]  [000000001021f5c4] btrfs_read_sys_array+0x3c/0x314 [btrfs]
[  945.427338]  [00000000101e84b8] open_ctree+0xf18/0x1864 [btrfs]
[  945.427438]  [00000000101bf018] btrfs_mount+0x22c/0x430 [btrfs]
[  945.427466]  [00000000004ef2cc] vfs_kern_mount+0x50/0x144
[  945.427484]  [00000000004ef400] do_kern_mount+0x24/0xbc
[  945.427509]  [0000000000507d4c] do_mount+0x804/0x86c
[  945.427533]  [00000000005264e8] compat_sys_mount+0x1c8/0x20c
[  945.427558]  [0000000000406114] linux_sparc_syscall32+0x34/0x40
[  945.427572] ---[ end trace ccd403344b12822e ]---
Comment 7 Adrien Dessemond 2011-03-16 11:27:20 UTC
Warning reported as a separate issue (bug #31172), David thank you for your efforts.

Note You need to log in before you can comment on or make changes to this bug.