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

[xen staging] xen/mm: Remove loops in get_order_from_{pages,bytes}()



commit 9d7c9d171bc85b786bf7bae4360473b4df136391
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Oct 28 11:30:24 2026 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Wed Nov 4 18:11:35 2026 +0000

    xen/mm: Remove loops in get_order_from_{pages,bytes}()
    
    These two functions are just fls() expressions in disguise.  Furthermore,
    GCC-12 at least won't const-propagate get_order_from_pages() with an input 
of
    3 or above, which covers most of the cases it gets used for.
    
    Rewrite them, and provide some self testing.
    
    Interesting, unless they are always_inline, GCC has a habit of out-of-lining
    them even when inlining would have been a win.  I expect this is to do with
    the fls() functions being superficially more complex.
    
    No functional change.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/common/bitops.c  | 27 +++++++++++++++++++++++++++
 xen/include/xen/mm.h | 18 ++++--------------
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/xen/common/bitops.c b/xen/common/bitops.c
index 859a4ca5c1..1291cbbf09 100644
--- a/xen/common/bitops.c
+++ b/xen/common/bitops.c
@@ -259,3 +259,30 @@ static void __init __constructor test_muldiv64(void)
     if ( res != 0xffffffffffffffffULL )
         panic("muldiv64(), expecting -1ULL, got %#"PRIx64"\n", res);
 }
+
+#include <xen/mm.h>
+
+/* Not really bitops, but here in lieu of any better location */
+static void __init test_order_from_pages(void)
+{
+    CHECK(get_order_from_pages, 1, 0);
+    CHECK(get_order_from_pages, 2, 1);
+    CHECK(get_order_from_pages, 3, 2);
+    CHECK(get_order_from_pages, 4, 2);
+    CHECK(get_order_from_pages, 5, 3);
+    CHECK(get_order_from_pages, 8, 3);
+    CHECK(get_order_from_pages, 9, 4);
+}
+
+static void __init test_order_from_bytes(void)
+{
+    CHECK(get_order_from_bytes, PAGE_SIZE - 1, 0);
+    CHECK(get_order_from_bytes, PAGE_SIZE,     0);
+    CHECK(get_order_from_bytes, PAGE_SIZE + 1, 1);
+}
+
+static void __init __constructor test_orders(void)
+{
+    test_order_from_pages();
+    test_order_from_bytes();
+}
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 153c57f5dd..8f4bba9491 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -530,26 +530,16 @@ page_list_splice(struct page_list_head *list, struct 
page_list_head *head)
     list_for_each_entry_safe_reverse(pos, tmp, head, list)
 #endif
 
-static inline unsigned int get_order_from_bytes(paddr_t size)
+static always_inline unsigned int get_order_from_bytes(paddr_t size)
 {
-    unsigned int order;
-
     size = (size - 1) >> PAGE_SHIFT;
-    for ( order = 0; size; order++ )
-        size >>= 1;
 
-    return order;
+    return fls64(size);
 }
 
-static inline unsigned int get_order_from_pages(unsigned long nr_pages)
+static always_inline unsigned int get_order_from_pages(unsigned long nr_pages)
 {
-    unsigned int order;
-
-    nr_pages--;
-    for ( order = 0; nr_pages; order++ )
-        nr_pages >>= 1;
-
-    return order;
+    return flsl(nr_pages - 1);
 }
 
 #ifndef arch_free_heap_page
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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