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

[xen master] xen: simplify bitmap_to_xenctl_bitmap for little endian



commit 288c4641c80d63169d65687a7723a0003327c8e9
Author:     Stefano Stabellini <stefano.stabellini@xxxxxxx>
AuthorDate: Wed Apr 2 12:14:40 2025 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Apr 2 12:14:40 2025 +0200

    xen: simplify bitmap_to_xenctl_bitmap for little endian
    
    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>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/common/bitmap.c | 65 +++++++++++++++++++++++++++++------------------------
 1 file changed, 36 insertions(+), 29 deletions(-)

diff --git a/xen/common/bitmap.c b/xen/common/bitmap.c
index 3da63a32a6..6c4af09c18 100644
--- 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 *bp, const unsigned 
long *lp,
                        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 long *lp, const 
uint8_t *bp,
 
 #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 xenctl_bitmap 
*xenctl_bitmap,
     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;
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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