[PATCH] LOG2: Implement a general integer log2 facility in the kernel
David Howells [Fri, 8 Dec 2006 10:37:49 +0000 (02:37 -0800)]
This facility provides three entry points:

ilog2() Log base 2 of unsigned long
ilog2_u32() Log base 2 of u32
ilog2_u64() Log base 2 of u64

These facilities can either be used inside functions on dynamic data:

int do_something(long q)
{
...;
y = ilog2(x)
...;
}

Or can be used to statically initialise global variables with constant values:

unsigned n = ilog2(27);

When performing static initialisation, the compiler will report "error:
initializer element is not constant" if asked to take a log of zero or of
something not reducible to a constant.  They treat negative numbers as
unsigned.

When not dealing with a constant, they fall back to using fls() which permits
them to use arch-specific log calculation instructions - such as BSR on
x86/x86_64 or SCAN on FRV - if available.

[akpm@osdl.org: MMC fix]
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: David Howells <dhowells@redhat.com>
Cc: Wojtek Kaniewski <wojtekka@toxygen.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

36 files changed:
arch/alpha/Kconfig
arch/arm/Kconfig
arch/arm26/Kconfig
arch/avr32/Kconfig
arch/cris/Kconfig
arch/frv/Kconfig
arch/h8300/Kconfig
arch/i386/Kconfig.cpu
arch/ia64/Kconfig
arch/m32r/Kconfig
arch/m68k/Kconfig
arch/m68knommu/Kconfig
arch/mips/Kconfig
arch/parisc/Kconfig
arch/powerpc/Kconfig
arch/ppc/Kconfig
arch/s390/Kconfig
arch/sh/Kconfig
arch/sh64/Kconfig
arch/sparc/Kconfig
arch/sparc64/Kconfig
arch/v850/Kconfig
arch/x86_64/Kconfig
arch/xtensa/Kconfig
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/md/dm-crypt.c
drivers/mmc/tifm_sd.c
fs/ext2/super.c
fs/ext3/super.c
include/asm-frv/bitops.h
include/linux/kernel.h
include/linux/log2.h [new file with mode: 0644]
mm/page_alloc.c

index 7e55ea6..84caf50 100644 (file)
@@ -25,6 +25,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index 8c05d43..aa1d400 100644 (file)
@@ -74,6 +74,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index c14fe91..74eba8b 100644 (file)
@@ -41,6 +41,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index 5f1694e..bb059a4 100644 (file)
@@ -45,6 +45,14 @@ config GENERIC_TIME
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_BUST_SPINLOCK
        bool
 
index 6a1238a..3474309 100644 (file)
@@ -16,6 +16,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index cf1c446..7561d7b 100644 (file)
@@ -41,6 +41,14 @@ config TIME_LOW_RES
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default y
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default y
+
 mainmenu "Fujitsu FR-V Kernel Configuration"
 
 source "init/Kconfig"
index cabf0bf..34a84bc 100644 (file)
@@ -29,6 +29,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default n
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index 821fd26..2aecfba 100644 (file)
@@ -248,6 +248,14 @@ config RWSEM_XCHGADD_ALGORITHM
        depends on !M386
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_CALIBRATE_DELAY
        bool
        default y
index 75d8397..fcacfe2 100644 (file)
@@ -34,6 +34,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index 41fd490..f383dab 100644 (file)
@@ -214,6 +214,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default n
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index 7bc1446..70a577c 100644 (file)
@@ -17,6 +17,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index aa70dde..25993c2 100644 (file)
@@ -25,6 +25,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default n
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index d8af858..57af8d8 100644 (file)
@@ -819,6 +819,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index d210123..0f9ff61 100644 (file)
@@ -25,6 +25,14 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_FIND_NEXT_BIT
        bool
        default y
index 291c95a..97c7a21 100644 (file)
@@ -41,6 +41,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index f76a146..692b5ba 100644 (file)
@@ -19,6 +19,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default y
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index 583d9ff..45e47bf 100644 (file)
@@ -22,6 +22,14 @@ config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config GENERIC_HWEIGHT
        bool
        default y
index d83d64a..8e24c40 100644 (file)
@@ -59,6 +59,14 @@ config LOCKDEP_SUPPORT
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 source "init/Kconfig"
 
 menu "System type"
index 58c678e..7bc0744 100644 (file)
@@ -39,6 +39,14 @@ config RWSEM_XCHGADD_ALGORITHM
 config GENERIC_ISA_DMA
        bool
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 source init/Kconfig
 
 menu "System type"
index 92a7c8a..d0dec1e 100644 (file)
@@ -166,6 +166,14 @@ config ARCH_MAY_HAVE_PC_FDC
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config SUN_PM
        bool
        default y
index b627f8d..d391d11 100644 (file)
@@ -34,6 +34,14 @@ config ARCH_MAY_HAVE_PC_FDC
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 config AUDIT_ARCH
        bool
        default y
index 37ec644..bcf8258 100644 (file)
@@ -38,6 +38,14 @@ config TIME_LOW_RES
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 # Turn off some random 386 crap that can affect device config
 config ISA
        bool
index 3254a61..3ac581d 100644 (file)
@@ -101,6 +101,14 @@ config GENERIC_BUG
        default y
        depends on BUG
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 source "init/Kconfig"
 
 
index c1e69a1..9eccfbd 100644 (file)
@@ -34,6 +34,14 @@ config GENERIC_HARDIRQS
        bool
        default y
 
+config ARCH_HAS_ILOG2_U32
+       bool
+       default n
+
+config ARCH_HAS_ILOG2_U64
+       bool
+       default n
+
 source "init/Kconfig"
 
 menu "Processor type and features"
index 21422a3..7ec7c4b 100644 (file)
@@ -124,7 +124,7 @@ static int mthca_query_device(struct ib_device *ibdev,
                props->max_map_per_fmr = 255;
        else
                props->max_map_per_fmr =
-                       (1 << (32 - long_log2(mdev->limits.num_mpts))) - 1;
+                       (1 << (32 - ilog2(mdev->limits.num_mpts))) - 1;
 
        err = 0;
  out:
@@ -816,7 +816,7 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda
                lkey = ucmd.lkey;
        }
 
-       ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, long_log2(entries), &status);
+       ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, ilog2(entries), &status);
        if (status)
                ret = -EINVAL;
 
index 33e3ba7..d844a25 100644 (file)
@@ -636,11 +636,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
 
        if (mthca_is_memfree(dev)) {
                if (qp->rq.max)
-                       qp_context->rq_size_stride = long_log2(qp->rq.max) << 3;
+                       qp_context->rq_size_stride = ilog2(qp->rq.max) << 3;
                qp_context->rq_size_stride |= qp->rq.wqe_shift - 4;
 
                if (qp->sq.max)
-                       qp_context->sq_size_stride = long_log2(qp->sq.max) << 3;
+                       qp_context->sq_size_stride = ilog2(qp->sq.max) << 3;
                qp_context->sq_size_stride |= qp->sq.wqe_shift - 4;
        }
 
index 34d2c47..10684da 100644 (file)
@@ -120,7 +120,7 @@ static void mthca_arbel_init_srq_context(struct mthca_dev *dev,
 
        memset(context, 0, sizeof *context);
 
-       logsize = long_log2(srq->max);
+       logsize = ilog2(srq->max);
        context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn);
        context->lkey = cpu_to_be32(srq->mr.ibmr.lkey);
        context->db_index = cpu_to_be32(srq->db_index);
@@ -213,7 +213,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
        if (!mthca_is_memfree(dev) && (ds > dev->limits.max_desc_sz))
                return -EINVAL;
 
-       srq->wqe_shift = long_log2(ds);
+       srq->wqe_shift = ilog2(ds);
 
        srq->srqn = mthca_alloc(&dev->srq_table.alloc);
        if (srq->srqn == -1)
index 5e12250..3aedd59 100644 (file)
@@ -114,7 +114,7 @@ int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task  *iser_ctask,
 
        if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
                mem = (void *)__get_free_pages(GFP_NOIO,
-                     long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+                     ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
        else
                mem = kmalloc(cmd_data_len, GFP_NOIO);
 
@@ -211,7 +211,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
        if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
                free_pages((unsigned long)mem_copy->copy_buf,
-                          long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+                          ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
        else
                kfree(mem_copy->copy_buf);
 
index a1086ee..9615286 100644 (file)
@@ -220,7 +220,7 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
                              const char *opts)
 {
        unsigned int bs = crypto_blkcipher_blocksize(cc->tfm);
-       int log = long_log2(bs);
+       int log = ilog2(bs);
 
        /* we need to calculate how far we must shift the sector count
         * to get the cipher block count, we use this shift in _gen */
index e846499..f18ad99 100644 (file)
@@ -387,7 +387,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
 
        writel(TIFM_FIFO_INT_SETALL,
                sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
-       writel(long_log2(cmd->data->blksz) - 2,
+       writel(ilog2(cmd->data->blksz) - 2,
                        sock->addr + SOCK_FIFO_PAGE_SIZE);
        writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
        writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
index 255cef5..6347c2d 100644 (file)
@@ -597,8 +597,6 @@ static int ext2_check_descriptors (struct super_block * sb)
        return 1;
 }
 
-#define log2(n) ffz(~(n))
 /*
  * Maximal file size.  There is a direct, and {,double-,triple-}indirect
  * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
@@ -834,9 +832,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_sbh = bh;
        sbi->s_mount_state = le16_to_cpu(es->s_state);
        sbi->s_addr_per_block_bits =
-               log2 (EXT2_ADDR_PER_BLOCK(sb));
+               ilog2 (EXT2_ADDR_PER_BLOCK(sb));
        sbi->s_desc_per_block_bits =
-               log2 (EXT2_DESC_PER_BLOCK(sb));
+               ilog2 (EXT2_DESC_PER_BLOCK(sb));
 
        if (sb->s_magic != EXT2_SUPER_MAGIC)
                goto cantfind_ext2;
index 580b8a6..b348867 100644 (file)
@@ -1347,8 +1347,6 @@ static void ext3_orphan_cleanup (struct super_block * sb,
        sb->s_flags = s_flags; /* Restore MS_RDONLY status */
 }
 
-#define log2(n) ffz(~(n))
-
 /*
  * Maximal file size.  There is a direct, and {,double-,triple-}indirect
  * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
@@ -1597,8 +1595,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
        sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);
        sbi->s_sbh = bh;
        sbi->s_mount_state = le16_to_cpu(es->s_state);
-       sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb));
-       sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb));
+       sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb));
+       sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb));
        for (i=0; i < 4; i++)
                sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
        sbi->s_def_hash_version = es->s_def_hash_version;
index 1f70d47..f8560ed 100644 (file)
@@ -256,6 +256,50 @@ int __ffs(unsigned long x)
        return 31 - bit;
 }
 
+/*
+ * special slimline version of fls() for calculating ilog2_u32()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+       int bit;
+       asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n));
+       return 31 - bit;
+}
+
+/*
+ * special slimline version of fls64() for calculating ilog2_u64()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+       union {
+               u64 ll;
+               struct { u32 h, l; };
+       } _;
+       int bit, x, y;
+
+       _.ll = n;
+
+       asm("   subcc           %3,gr0,gr0,icc0         \n"
+           "   ckeq            icc0,cc4                \n"
+           "   cscan.p         %3,gr0,%0       ,cc4,0  \n"
+           "   setlos          #63,%1                  \n"
+           "   cscan.p         %4,gr0,%0       ,cc4,1  \n"
+           "   setlos          #31,%2                  \n"
+           "   csub.p          %1,%0,%0        ,cc4,0  \n"
+           "   csub            %2,%0,%0        ,cc4,1  \n"
+           : "=&r"(bit), "=r"(x), "=r"(y)
+           : "0r"(_.h), "r"(_.l)
+           : "icc0", "cc4"
+           );
+       return bit;
+}
+
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
 
index 6738283..3710cce 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/bitops.h>
+#include <linux/log2.h>
 #include <asm/byteorder.h>
 #include <asm/bug.h>
 
@@ -157,14 +158,6 @@ static inline int printk(const char *s, ...) { return 0; }
 
 unsigned long int_sqrt(unsigned long);
 
-static inline int __attribute_pure__ long_log2(unsigned long x)
-{
-       int r = 0;
-       for (x >>= 1; x > 0; x >>= 1)
-               r++;
-       return r;
-}
-
 static inline unsigned long
 __attribute_const__ roundup_pow_of_two(unsigned long x)
 {
diff --git a/include/linux/log2.h b/include/linux/log2.h
new file mode 100644 (file)
index 0000000..3979c60
--- /dev/null
@@ -0,0 +1,131 @@
+/* Integer base 2 logarithm calculation
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_LOG2_H
+#define _LINUX_LOG2_H
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+/*
+ * deal with unrepresentable constant logarithms
+ */
+extern __attribute__((const, noreturn))
+int ____ilog2_NaN(void);
+
+/*
+ * non-constant log of base 2 calculators
+ * - the arch may override these in asm/bitops.h if they can be implemented
+ *   more efficiently than using fls() and fls64()
+ * - the arch is not required to handle n==0 if implementing the fallback
+ */
+#ifndef CONFIG_ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+       return fls(n) - 1;
+}
+#endif
+
+#ifndef CONFIG_ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+       return fls64(n) - 1;
+}
+#endif
+
+/**
+ * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
+ * @n - parameter
+ *
+ * constant-capable log of base 2 calculation
+ * - this can be used to initialise global variables from constant data, hence
+ *   the massive ternary operator construction
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2(n)                               \
+(                                              \
+       __builtin_constant_p(n) ? (             \
+               (n) < 1 ? ____ilog2_NaN() :     \
+               (n) & (1ULL << 63) ? 63 :       \
+               (n) & (1ULL << 62) ? 62 :       \
+               (n) & (1ULL << 61) ? 61 :       \
+               (n) & (1ULL << 60) ? 60 :       \
+               (n) & (1ULL << 59) ? 59 :       \
+               (n) & (1ULL << 58) ? 58 :       \
+               (n) & (1ULL << 57) ? 57 :       \
+               (n) & (1ULL << 56) ? 56 :       \
+               (n) & (1ULL << 55) ? 55 :       \
+               (n) & (1ULL << 54) ? 54 :       \
+               (n) & (1ULL << 53) ? 53 :       \
+               (n) & (1ULL << 52) ? 52 :       \
+               (n) & (1ULL << 51) ? 51 :       \
+               (n) & (1ULL << 50) ? 50 :       \
+               (n) & (1ULL << 49) ? 49 :       \
+               (n) & (1ULL << 48) ? 48 :       \
+               (n) & (1ULL << 47) ? 47 :       \
+               (n) & (1ULL << 46) ? 46 :       \
+               (n) & (1ULL << 45) ? 45 :       \
+               (n) & (1ULL << 44) ? 44 :       \
+               (n) & (1ULL << 43) ? 43 :       \
+               (n) & (1ULL << 42) ? 42 :       \
+               (n) & (1ULL << 41) ? 41 :       \
+               (n) & (1ULL << 40) ? 40 :       \
+               (n) & (1ULL << 39) ? 39 :       \
+               (n) & (1ULL << 38) ? 38 :       \
+               (n) & (1ULL << 37) ? 37 :       \
+               (n) & (1ULL << 36) ? 36 :       \
+               (n) & (1ULL << 35) ? 35 :       \
+               (n) & (1ULL << 34) ? 34 :       \
+               (n) & (1ULL << 33) ? 33 :       \
+               (n) & (1ULL << 32) ? 32 :       \
+               (n) & (1ULL << 31) ? 31 :       \
+               (n) & (1ULL << 30) ? 30 :       \
+               (n) & (1ULL << 29) ? 29 :       \
+               (n) & (1ULL << 28) ? 28 :       \
+               (n) & (1ULL << 27) ? 27 :       \
+               (n) & (1ULL << 26) ? 26 :       \
+               (n) & (1ULL << 25) ? 25 :       \
+               (n) & (1ULL << 24) ? 24 :       \
+               (n) & (1ULL << 23) ? 23 :       \
+               (n) & (1ULL << 22) ? 22 :       \
+               (n) & (1ULL << 21) ? 21 :       \
+               (n) & (1ULL << 20) ? 20 :       \
+               (n) & (1ULL << 19) ? 19 :       \
+               (n) & (1ULL << 18) ? 18 :       \
+               (n) & (1ULL << 17) ? 17 :       \
+               (n) & (1ULL << 16) ? 16 :       \
+               (n) & (1ULL << 15) ? 15 :       \
+               (n) & (1ULL << 14) ? 14 :       \
+               (n) & (1ULL << 13) ? 13 :       \
+               (n) & (1ULL << 12) ? 12 :       \
+               (n) & (1ULL << 11) ? 11 :       \
+               (n) & (1ULL << 10) ? 10 :       \
+               (n) & (1ULL <<  9) ?  9 :       \
+               (n) & (1ULL <<  8) ?  8 :       \
+               (n) & (1ULL <<  7) ?  7 :       \
+               (n) & (1ULL <<  6) ?  6 :       \
+               (n) & (1ULL <<  5) ?  5 :       \
+               (n) & (1ULL <<  4) ?  4 :       \
+               (n) & (1ULL <<  3) ?  3 :       \
+               (n) & (1ULL <<  2) ?  2 :       \
+               (n) & (1ULL <<  1) ?  1 :       \
+               (n) & (1ULL <<  0) ?  0 :       \
+               ____ilog2_NaN()                 \
+                                  ) :          \
+       (sizeof(n) <= 4) ?                      \
+       __ilog2_u32(n) :                        \
+       __ilog2_u64(n)                          \
+ )
+
+#endif /* _LINUX_LOG2_H */
index cace22b..18f0e04 100644 (file)
@@ -3244,7 +3244,7 @@ void *__init alloc_large_system_hash(const char *tablename,
        if (numentries > max)
                numentries = max;
 
-       log2qty = long_log2(numentries);
+       log2qty = ilog2(numentries);
 
        do {
                size = bucketsize << log2qty;
@@ -3266,7 +3266,7 @@ void *__init alloc_large_system_hash(const char *tablename,
        printk("%s hash table entries: %d (order: %d, %lu bytes)\n",
               tablename,
               (1U << log2qty),
-              long_log2(size) - PAGE_SHIFT,
+              ilog2(size) - PAGE_SHIFT,
               size);
 
        if (_hash_shift)