[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 2/5] xen/ppc: Implement bitops.h


  • To: Shawn Anastasio <sanastasio@xxxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 13 Sep 2023 09:29:34 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HNCw7ohUZz3U+URZOXzVYI6KdH4LIvexbVxm71GAocw=; b=Rm3V5NgtJUDeXltk7mBvHesJM/LHMSiLFgTLtM+MSqC/QUNFCYOGHc1hClqSjsO7vvxz10YYcmBvG5C9CCznstMOct3nprEncjNO3L5Y/585p0SrpdAa+q+sm3oL3Mqsb37jC5IBdc8U+5OP7/R2JoDcWw+8vyxPSGAGuXFZwIoxrgn3FYWBbQCHRutkkJ+8L2q35zDhN7613n+fWCEm6T+IIt/0Znfyyp2mXjVoC9XOxO1uchxk35ewgWfKu3I4ueiHAhGr9xONefeAlzF6lK2qtoMJvJcxT59t6J+2f4y+WxZA1OqQSB+drxwHvT2CyysfrfyiNgu8hnalbWhfFw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R6CN046504YACvM/p+7epTiLfx88P1xkG6g16xY0pVKgAUp0MSWdZD8aoHc71ZSIcwxfB1nrVyVdj9i2xxhTqr2NximQWJ7lqMZOFhZnrUhpFoh2HBOIyouYUU0BdmqhvxpwjQXQ56ePTRMKbBOGEkt9kMFCd72dOmnSIGQTCLLDFEsq9VfdWbHKYt02w4zZ/uBdzyFuJfzV12mIkSgVZXibwfYpG65X1UpgdrEdE6CwlqL0ThEoKQjiBE13Q1bYAfT03AOwNm+lbxE+8cibPSUnBRbSXPV6f5x8qm7T9Gq2yt7VceStCnAntvVP/MuRRetUd9++kd7lQVj48SqZkw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Timothy Pearson <tpearson@xxxxxxxxxxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Wed, 13 Sep 2023 07:29:46 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 12.09.2023 20:35, Shawn Anastasio wrote:
> Implement bitops.h, based on Linux's implementation as of commit
> 5321d1b1afb9a17302c6cec79f0cbf823eb0d3fc. Though it is based off of
> Linux's implementation, this code diverges significantly in a number of
> ways:
>   - Bitmap entries changed to 32-bit words to match X86 and Arm on Xen
>   - PPC32-specific code paths dropped
>   - Formatting completely re-done to more closely line up with Xen.
>     Including 4 space indentation.
>   - Use GCC's __builtin_popcount* for hweight* implementation
> 
> Signed-off-by: Shawn Anastasio <sanastasio@xxxxxxxxxxxxxxxxxxxxx>
> Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> v5:
>   - Switch lingering ulong bitop parameters/return values to uint.
> 
> v4:
>   - Mention __builtin_popcount impelmentation of hweight* in message
>   - Change type of BITOP_MASK expression from unsigned long to unsigned
>     int
>   - Fix remaining underscore-prefixed macro params/vars
>   - Fix line wrapping in test_and_clear_bit{,s}
>   - Change type of test_and_clear_bits' pointer parameter from void *
>     to unsigned int *. This was already done for other functions but
>     missed here.
>   - De-macroize test_and_set_bits.
>   - Fix formatting of ffs{,l} macro's unary operators
>   - Drop extra blank in ffz() macro definition
> 
> v3:
>   - Fix style of inline asm blocks.
>   - Fix underscore-prefixed macro parameters/variables
>   - Use __builtin_popcount for hweight* implementation
>   - Update C functions to use proper Xen coding style
> 
> v2:
>   - Clarify changes from Linux implementation in commit message
>   - Use PPC_ATOMIC_{ENTRY,EXIT}_BARRIER macros from <asm/memory.h> instead
>     of hardcoded "sync" instructions in inline assembly blocks.
>   - Fix macro line-continuing backslash spacing
>   - Fix hard-tab usage in find_*_bit C functions.
> 
>  xen/arch/ppc/include/asm/bitops.h | 332 +++++++++++++++++++++++++++++-
>  1 file changed, 329 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/ppc/include/asm/bitops.h 
> b/xen/arch/ppc/include/asm/bitops.h
> index 548e97b414..0f75ff3f9d 100644
> --- a/xen/arch/ppc/include/asm/bitops.h
> +++ b/xen/arch/ppc/include/asm/bitops.h
> @@ -1,9 +1,335 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Adapted from Linux's arch/powerpc/include/asm/bitops.h.
> + *
> + * Merged version by David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>.
> + * Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don
> + * Reed, Pat McCarthy, Peter Bergner, Anton Blanchard.  They
> + * originally took it from the ppc32 code.
> + */
>  #ifndef _ASM_PPC_BITOPS_H
>  #define _ASM_PPC_BITOPS_H
> 
> +#include <asm/memory.h>
> +
> +#define __set_bit(n, p)         set_bit(n, p)
> +#define __clear_bit(n, p)       clear_bit(n, p)
> +
> +#define BITOP_BITS_PER_WORD     32
> +#define BITOP_MASK(nr)          (1U << ((nr) % BITOP_BITS_PER_WORD))
> +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> +#define BITS_PER_BYTE           8
> +
>  /* PPC bit number conversion */
> -#define PPC_BITLSHIFT(be)    (BITS_PER_LONG - 1 - (be))
> -#define PPC_BIT(bit)         (1UL << PPC_BITLSHIFT(bit))
> -#define PPC_BITMASK(bs, be)  ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
> +#define PPC_BITLSHIFT(be)    (BITS_PER_LONG - 1 - (be))
> +#define PPC_BIT(bit)         (1UL << PPC_BITLSHIFT(bit))
> +#define PPC_BITMASK(bs, be)  ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
> +
> +/* Macro for generating the ***_bits() functions */
> +#define DEFINE_BITOP(fn, op, prefix)                                         
>   \
> +static inline void fn(unsigned int mask,                                     
>  \
> +                      volatile unsigned int *p_)                             
>   \
> +{                                                                            
>   \
> +    unsigned int old;                                                        
>  \
> +    unsigned int *p = (unsigned int *)p_;                                    
>   \

What use is this, when ...

> +    asm volatile ( prefix                                                    
>   \
> +                   "1: lwarx %0,0,%3,0\n"                                    
>   \
> +                   #op "%I2 %0,%0,%2\n"                                      
>   \
> +                   "stwcx. %0,0,%3\n"                                        
>   \
> +                   "bne- 1b\n"                                               
>   \
> +                   : "=&r" (old), "+m" (*p)                                  
>   \

... the "+m" operand isn't used and ...

> +                   : "rK" (mask), "r" (p)                                    
>   \
> +                   : "cc", "memory" );                                       
>   \

... there's a memory clobber anyway?

Also (nit) note that the long -> int change has caused some of the
backslashes to no longer align.

> +}
> +
> +DEFINE_BITOP(set_bits, or, "")
> +DEFINE_BITOP(change_bits, xor, "")

Are there further plans to add uses of DEFINE_BITOP() with the last argument
not an empty string? If not, how about simplifying things by dropping the
macro parameter?

> +#define DEFINE_CLROP(fn, prefix)                                             
>   \
> +static inline void fn(unsigned int mask, volatile unsigned int *p_)          
>  \
> +{                                                                            
>   \
> +    unsigned int old;                                                        
>  \
> +    unsigned int *p = (unsigned int *)p_;                                    
>   \
> +    asm volatile ( prefix                                                    
>   \
> +                   "1: lwarx %0,0,%3,0\n"                                    
>   \
> +                   "andc %0,%0,%2\n"                                         
>   \
> +                   "stwcx. %0,0,%3\n"                                        
>   \
> +                   "bne- 1b\n"                                               
>   \
> +                   : "=&r" (old), "+m" (*p)                                  
>   \
> +                   : "r" (mask), "r" (p)                                     
>   \
> +                   : "cc", "memory" );                                       
>   \
> +}
> +
> +DEFINE_CLROP(clear_bits, "")

Same question here.

> +static inline void set_bit(int nr, volatile void *addr)
> +{
> +    set_bits(BITOP_MASK(nr), (volatile unsigned int *)addr + BITOP_WORD(nr));
> +}
> +static inline void clear_bit(int nr, volatile void *addr)
> +{
> +    clear_bits(BITOP_MASK(nr), (volatile unsigned int *)addr + 
> BITOP_WORD(nr));
> +}
> +
> +/**
> + * test_bit - Determine whether a bit is set
> + * @nr: bit number to test
> + * @addr: Address to start counting from
> + */
> +static inline int test_bit(int nr, const volatile void *addr)
> +{
> +    const volatile unsigned int *p = addr;
> +    return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD - 1)));
> +}
> +
> +static inline unsigned int test_and_clear_bits(
> +    unsigned int mask,
> +    volatile unsigned int *p)
> +{
> +    unsigned int old, t;
> +
> +    asm volatile ( PPC_ATOMIC_ENTRY_BARRIER
> +                   "1: lwarx %0,0,%3,0\n"
> +                   "andc %1,%0,%2\n"
> +                   "stwcx. %1,0,%3\n"
> +                   "bne- 1b\n"
> +                   PPC_ATOMIC_EXIT_BARRIER
> +                   : "=&r" (old), "=&r" (t)
> +                   : "r" (mask), "r" (p)
> +                   : "cc", "memory" );
> +
> +    return (old & mask);
> +}
> +
> +static inline int test_and_clear_bit(unsigned int nr,
> +                                     volatile void *addr)
> +{
> +    return test_and_clear_bits(BITOP_MASK(nr), (volatile unsigned int *)addr 
> +
> +                               BITOP_WORD(nr)) != 0;

Didn't you indicate you'd adjust the odd wrapping?

> +}
> +
> +static inline unsigned int test_and_set_bits(
> +    unsigned int mask,
> +    volatile unsigned int *p)
> +{
> +    unsigned int old, t;
> +
> +    asm volatile ( PPC_ATOMIC_ENTRY_BARRIER
> +                   "1: lwarx %0,0,%3,0\n"
> +                   "or%I2 %1,%0,%2\n"
> +                   "stwcx. %1,0,%3\n"
> +                   "bne- 1b\n"
> +                   PPC_ATOMIC_EXIT_BARRIER
> +                   : "=&r" (old), "=&r" (t)
> +                   : "rK" (mask), "r" (p)
> +                   : "cc", "memory" );
> +
> +    return (old & mask);
> +}
> +
> +static inline int test_and_set_bit(unsigned int nr, volatile void *addr)
> +{
> +    return test_and_set_bits(BITOP_MASK(nr), (volatile unsigned int *)addr +
> +                                             BITOP_WORD(nr)) != 0;

Same here then.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.