[PATCH] LOG2: Implement a general integer log2 facility in the kernel
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>
This commit is contained in:
parent
b3d7ae5f47
commit
f0d1b0b30d
36 changed files with 384 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
131
include/linux/log2.h
Normal file
131
include/linux/log2.h
Normal file
|
@ -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 */
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue