• YOSHIFUJI Hideaki / 吉藤英明's avatar
    ipv6 fib: Use "Sweezle" to optimize addr_bit_test(). · 02cdce53
    YOSHIFUJI Hideaki / 吉藤英明 authored
    addr_bit_test() is used in various places in IPv6 routing table
    subsystem.  It checks if the given fn_bit is set,
    where fn_bit counts bits from MSB in words in network-order.
    
     fn_bit        :   0 .... 31 32 .... 64 65 .... 95 96 ....127
    
    fn_bit >> 5 gives offset of word, and (~fn_bit & 0x1f) gives
    count from LSB in the network-endian word in question.
    
     fn_bit >> 5   :       0          1          2          3
     ~fn_bit & 0x1f:  31 ....  0 31 ....  0 31 ....  0 31 ....  0
    
    Thus, the mask was generated as htonl(1 << (~fn_bit & 0x1f)).
    This can be optimized by "sweezle" (See include/asm-generic/bitops/le.h).
    
    In little-endian,
      htonl(1 << bit) = 1 << (bit ^ BITOP_BE32_SWIZZLE)
    where
      BITOP_BE32_SWIZZLE is (0x1f & ~7)
    So,
      htonl(1 << (~fn_bit & 0x1f)) = 1 << ((~fn_bit & 0x1f) ^ (0x1f & ~7))
                                   = 1 << ((~fn_bit ^ ~7) & 0x1f)
                                   = 1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)
    
    In big-endian, BITOP_BE32_SWIZZLE is equal to 0.
      1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)
                                   = 1 << ((~fn_bit) & 0x1f)
                                   = htonl(1 << (~fn_bit & 0x1f))
    Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    02cdce53
ip6_fib.c 32.7 KB