|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5] xen: simplify bitmap_to_xenctl_bitmap for little endian
On Tue, 1 Apr 2025, Jan Beulich wrote:
> From: Stefano Stabellini <stefano.stabellini@xxxxxxx>
>
> The little endian implementation of bitmap_to_xenctl_bitmap leads to
> unnecessary xmallocs and xfrees. Given that Xen only supports little
> endian architectures, it is worth optimizing.
>
> This patch removes the need for the xmalloc on little endian
> architectures.
>
> Remove clamp_last_byte as it is only called once and only needs to
> modify one byte. Inline it.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> v5: Fix IS_ENABLED() use. Keep more code common. Move comment.
> Convert LE bitmap_long_to_byte() to just a declaration.
Thanks Jan, I looked at your version carefully and it looks correct to
me. I could give my reviewed-by but it looks weird given that I am also
the first author.
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> --- a/xen/common/bitmap.c
> +++ b/xen/common/bitmap.c
> @@ -40,21 +40,6 @@
> * for the best explanations of this ordering.
> */
>
> -/*
> - * If a bitmap has a number of bits which is not a multiple of 8 then
> - * the last few bits of the last byte of the bitmap can be
> - * unexpectedly set which can confuse consumers (e.g. in the tools)
> - * who also round up their loops to 8 bits. Ensure we clear those left
> - * over bits so as to prevent surprises.
> - */
> -static void clamp_last_byte(uint8_t *bp, unsigned int nbits)
> -{
> - unsigned int remainder = nbits % 8;
> -
> - if (remainder)
> - bp[nbits/8] &= (1U << remainder) - 1;
> -}
> -
> int __bitmap_empty(const unsigned long *bitmap, unsigned int bits)
> {
> int k, lim = bits/BITS_PER_LONG;
> @@ -338,7 +323,6 @@ static void bitmap_long_to_byte(uint8_t
> nbits -= 8;
> }
> }
> - clamp_last_byte(bp, nbits);
> }
>
> static void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp,
> @@ -359,12 +343,11 @@ static void bitmap_byte_to_long(unsigned
>
> #elif defined(__LITTLE_ENDIAN)
>
> -static void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp,
> - unsigned int nbits)
> -{
> - memcpy(bp, lp, DIV_ROUND_UP(nbits, BITS_PER_BYTE));
> - clamp_last_byte(bp, nbits);
> -}
> +#define LITTLE_ENDIAN 1 /* For IS_ENABLED(). */
> +
> +/* Unused function, but a declaration is needed. */
> +void bitmap_long_to_byte(uint8_t *bp, const unsigned long *lp,
> + unsigned int nbits);
>
> static void bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp,
> unsigned int nbits)
> @@ -384,22 +367,46 @@ int bitmap_to_xenctl_bitmap(struct xenct
> uint8_t zero = 0;
> int err = 0;
> unsigned int xen_bytes = DIV_ROUND_UP(nbits, BITS_PER_BYTE);
> - uint8_t *bytemap = xmalloc_array(uint8_t, xen_bytes);
> + const uint8_t *bytemap;
> + uint8_t last, *buf = NULL;
>
> - if ( !bytemap )
> - return -ENOMEM;
> + if ( !IS_ENABLED(LITTLE_ENDIAN) )
> + {
> + buf = xmalloc_array(uint8_t, xen_bytes);
> + if ( !buf )
> + return -ENOMEM;
> +
> + bitmap_long_to_byte(buf, bitmap, nbits);
> +
> + bytemap = buf;
> + }
> + else
> + bytemap = (const uint8_t *)bitmap;
>
> guest_bytes = DIV_ROUND_UP(xenctl_bitmap->nr_bits, BITS_PER_BYTE);
> copy_bytes = min(guest_bytes, xen_bytes);
>
> - bitmap_long_to_byte(bytemap, bitmap, nbits);
> + if ( copy_bytes > 1 &&
> + copy_to_guest(xenctl_bitmap->bitmap, bytemap, copy_bytes - 1) )
> + err = -EFAULT;
> +
> + /*
> + * If a bitmap has a number of bits which is not a multiple of 8 then the
> + * last few bits of the last byte of the bitmap can be unexpectedly set,
> + * which can confuse consumers (e.g. in the tools), who also may round up
> + * their loops to 8 bits. Ensure we clear those left over bits so as to
> + * prevent surprises.
> + */
> + last = bytemap[nbits / 8];
> + if ( nbits % 8 )
> + last &= (1U << (nbits % 8)) - 1;
> +
> + xfree(buf);
>
> if ( copy_bytes &&
> - copy_to_guest(xenctl_bitmap->bitmap, bytemap, copy_bytes) )
> + copy_to_guest_offset(xenctl_bitmap->bitmap, copy_bytes - 1, &last,
> 1) )
> err = -EFAULT;
>
> - xfree(bytemap);
> -
> for ( i = copy_bytes; !err && i < guest_bytes; i++ )
> if ( copy_to_guest_offset(xenctl_bitmap->bitmap, i, &zero, 1) )
> err = -EFAULT;
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |