Skip to contentSkip to conversation

fs/ext4/ext4fs.c, fs/fs.c: Use lldiv and multiplication / subtraction on 64bit ops

PATCH New Tom Rini 2 participants 4 messages Nov 24, 2014 – Nov 26, 2014

Subsystems (2)
lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 1/1 fs/ext4/ext4fs.c, fs/fs.c: Use lldiv and multiplication / subtraction on 64bit ops

In some cases we need to do math on 64bit quantities. We need to be using lldiv in these cases rather than letting the compiler do it. In addition we need to avoid doing % operations on these same quantities. These changes fix compilation on MIPS/MIPSEL.

Cc Daniel Schwierzeck <[email protected]>
Cc Suriyan Ramasami <[email protected]>
Cc Simon Glass <[email protected]>
---
 fs/ext4/ext4fs.c |   11 ++++++-----
 fs/fs.c          |    3 ++-
 2 files changed, 8 insertions(+), 6 deletions(-)
fs/ext4/ext4fs.c +6 -5
index 943b5bc..258b9379 100644
@@ -25,6 +25,7 @@
 #include <ext_common.h>
 #include <ext4fs.h>
 #include "ext4_common.h"
+#include <div64.h>
 
 int ext4fs_symlinknest;
 struct ext_filesystem ext_fs;
@@ -67,11 +68,11 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
 	if (len > filesize)
 		len = filesize;
 
-	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
+	blockcnt = lldiv(((len + pos) + blocksize - 1), blocksize);
 
-	for (i = pos / blocksize; i < blockcnt; i++) {
+	for (i = lldiv(pos, blocksize); i < blockcnt; i++) {
 		lbaint_t blknr;
-		int blockoff = pos % blocksize;
+		int blockoff = pos - (blocksize * i);
 		int blockend = blocksize;
 		int skipfirst = 0;
 		blknr = read_allocated_block(&(node->inode), i);
@@ -82,7 +83,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
 
 		/* Last block.  */
 		if (i == blockcnt - 1) {
-			blockend = (len + pos) % blocksize;
+			blockend = (len + pos) - (blocksize * i);
 
 			/* The last portion is exactly blocksize. */
 			if (!blockend)
@@ -90,7 +91,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
 		}
 
 		/* First block. */
-		if (i == pos / blocksize) {
+		if (i == lldiv(pos, blocksize)) {
 			skipfirst = blockoff;
 			blockend -= skipfirst;
 		}
fs/fs.c +2 -1
index 3da7860..760f4a6 100644
@@ -17,6 +17,7 @@
 #include <config.h>
 #include <errno.h>
 #include <common.h>
+#include <div64.h>
 #include <part.h>
 #include <ext4fs.h>
 #include <fat.h>
@@ -399,7 +400,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 	printf("%llu bytes read in %lu ms", len_read, time);
 	if (time > 0) {
 		puts(" (");
-		print_size(len_read / time * 1000, "/s");
+		print_size(lldiv(len_read, time * 1000), "/s");
 		puts(")");
 	}
 	puts("\n");
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/1 fs/ext4/ext4fs.c, fs/fs.c: Use lldiv and multiplication / subtraction on 64bit ops

Quoted 9 lines · Tom Rini

In some cases we need to do math on 64bit quantities. We need to be using lldiv in these cases rather than letting the compiler do it. In addition we need to avoid doing % operations on these same quantities. These changes fix compilation on MIPS/MIPSEL.

Cc Daniel Schwierzeck <[email protected]>
Cc Suriyan Ramasami <[email protected]>
Cc Simon Glass <[email protected]>
Quoted 74 lines
---
 fs/ext4/ext4fs.c |   11 ++++++-----
 fs/fs.c          |    3 ++-
 2 files changed, 8 insertions(+), 6 deletions(-)
fs/ext4/ext4fs.c +6 -5
index 943b5bc..258b9379 100644
@@ -25,6 +25,7 @@
 #include <ext_common.h>
 #include <ext4fs.h>
 #include "ext4_common.h"
+#include <div64.h>
 
 int ext4fs_symlinknest;
 struct ext_filesystem ext_fs;
@@ -67,11 +68,11 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
        if (len > filesize)
                len = filesize;
 
-       blockcnt = ((len + pos) + blocksize - 1) / blocksize;
+       blockcnt = lldiv(((len + pos) + blocksize - 1), blocksize);
 
-       for (i = pos / blocksize; i < blockcnt; i++) {
+       for (i = lldiv(pos, blocksize); i < blockcnt; i++) {
                lbaint_t blknr;
-               int blockoff = pos % blocksize;
+               int blockoff = pos - (blocksize * i);
                int blockend = blocksize;
                int skipfirst = 0;
                blknr = read_allocated_block(&(node->inode), i);
@@ -82,7 +83,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
 
                /* Last block.  */
                if (i == blockcnt - 1) {
-                       blockend = (len + pos) % blocksize;
+                       blockend = (len + pos) - (blocksize * i);
 
                        /* The last portion is exactly blocksize. */
                        if (!blockend)
@@ -90,7 +91,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
                }
 
                /* First block. */
-               if (i == pos / blocksize) {
+               if (i == lldiv(pos, blocksize)) {
                        skipfirst = blockoff;
                        blockend -= skipfirst;
                }
fs/fs.c +2 -2
index 3da7860..760f4a6 100644
@@ -17,6 +17,7 @@
 #include <config.h>
 #include <errno.h>
 #include <common.h>
+#include <div64.h>
 #include <part.h>
 #include <ext4fs.h>
 #include <fat.h>
@@ -399,7 +400,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
        printf("%llu bytes read in %lu ms", len_read, time);
        if (time > 0) {
                puts(" (");
-               print_size(len_read / time * 1000, "/s");
+               print_size(lldiv(len_read, time * 1000), "/s");
                puts(")");
        }
        puts("\n");
--

1.7.9.5

#2 lore raw

PATCH 1/1 fs/ext4/ext4fs.c, fs/fs.c: Use lldiv and multiplication / subtraction on 64bit ops

Hi Tom,

Quoted 6 lines · Simon Glass
Quoted 5 lines · Tom Rini

In some cases we need to do math on 64bit quantities. We need to be using lldiv in these cases rather than letting the compiler do it. In addition we need to avoid doing % operations on these same quantities. These changes fix compilation on MIPS/MIPSEL.

Quoted 6 lines
Quoted 4 lines
Cc Daniel Schwierzeck <[email protected]>
Cc Suriyan Ramasami <[email protected]>
Cc Simon Glass <[email protected]>

I'm not sure this goes far enough. I am still seeing problems even with this patch, e.g. for pm9g45:

/opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
error: /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(bpabi.o) uses VFP register arguments, u-boot does not /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
failed to merge target specific data of file /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(bpabi.o) /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
error: /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(_divdi3.o) uses VFP register arguments, u-boot does not /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
failed to merge target specific data of file /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(_divdi3.o) /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
error: /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(_udivdi3.o) uses VFP register arguments, u-boot does not /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/arm-linux-gnueabihf-ld.bfd:
failed to merge target specific data of file /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.8.2/libgcc.a(_udivdi3.o) make[1]: *** [u-boot] Error 1
make: *** [sub-make] Error 2

Regards,
Simon

author
#3 lore raw

PATCH 1/1 fs/ext4/ext4fs.c, fs/fs.c: Use lldiv and multiplication / subtraction on 64bit ops

Quoted 14 lines · Simon Glass

Hi Tom,

Quoted 11 lines · Simon Glass
Quoted 9 lines · Tom Rini

In some cases we need to do math on 64bit quantities. We need to be using lldiv in these cases rather than letting the compiler do it. In addition we need to avoid doing % operations on these same quantities. These changes fix compilation on MIPS/MIPSEL.

Cc Daniel Schwierzeck <[email protected]>
Cc Suriyan Ramasami <[email protected]>
Cc Simon Glass <[email protected]>
Quoted 4 lines
Quoted 1 line

I'm not sure this goes far enough. I am still seeing problems even with this patch, e.g. for pm9g45:

Indeed it's not. I'll post a V2 soon, I've figured out the places I missed but need to step out now.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141126/f0ed4614/attachment.pgp>