From: Chandan Rajendra Date: Tue, 11 Aug 2015 09:41:26 +0000 (+0530) Subject: arch-ppc.h: Add ilog2 implementation for ppc64 X-Git-Tag: fio-2.2.10~25 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=92060d6c59f1848e86cd9ddd7550907c79bda3d5;ds=sidebyside arch-ppc.h: Add ilog2 implementation for ppc64 On a ppc64 machine, when fio is invoked with the following configuration file (generated by fstests' generic/300 test), it loops indefinitely. [global] directory=/mnt/btrfs-xfstest-scratch filesize=536870912 size=999G continue_on_error=write ignore_error=,ENOSPC error_dump=0 create_on_open=1 fallocate=none exitall=1 [direct_aio_raicer] ioengine=libaio iodepth=128*1 bs=128k direct=1 numjobs=4 rw=randwrite runtime=100*1 time_based filename=racer [falloc_raicer] ioengine=falloc runtime=100*1 iodepth=1 bssplit=128k/80:512k/10:32k/10 rw=randwrite numjobs=1 filename=racer [punch_hole_raicer] ioengine=falloc runtime=100*1 bs=4k time_based=10 rw=randtrim numjobs=2 filename=racer time_based [aio-dio-verifier] ioengine=libaio iodepth=128*1 numjobs=1 verify=crc32c-intel verify_fatal=1 verify_dump=1 verify_backlog=1024 verify_async=4 verifysort=1 direct=1 bs=4k rw=randwrite filename=aio-dio-verifier This is because arch_ffz() ends up invoking the 32-bit version of __ilog2() which always returns a bit number in the range 0 - 31. This can cause "overlap" variable in axmap_set_fn() to never becomes zero. To fix this the commit adds a 64-bit version of __ilog2() (obtained from the Linux kernel's arch/powerpc/include/asm/bitops.h). Signed-off-by: Chandan Rajendra Signed-off-by: Jens Axboe --- diff --git a/arch/arch-ppc.h b/arch/arch-ppc.h index d4a080c4..aed41f9b 100644 --- a/arch/arch-ppc.h +++ b/arch/arch-ppc.h @@ -33,18 +33,24 @@ #define write_barrier() __asm__ __volatile__ ("sync" : : : "memory") +#ifdef __powerpc64__ +#define PPC_CNTLZL "cntlzd" +#else +#define PPC_CNTLZL "cntlzw" +#endif + static inline int __ilog2(unsigned long bitmask) { int lz; - asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bitmask)); - return 31 - lz; + asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (bitmask)); + return BITS_PER_LONG - 1 - lz; } static inline int arch_ffz(unsigned long bitmask) { if ((bitmask = ~bitmask) == 0) - return 32; + return BITS_PER_LONG; return __ilog2(bitmask & -bitmask); }