From: Timmons C. Player <timmons.pla...@spirent.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

percpu: enforce alignment for dynamic percpu allocations

If the dynamic memory buffer used for percpu allocations
wasn't congruent to the requested alignment, then the
returned memory wouldn't actually be aligned correctly.
This change forces the bitmap search to start at the proper
alignment.

Signed-off-by: Timmons C. Player <timmons.pla...@spirent.com>
Message-Id: <1483547132-22868-3-git-send-email-timmons.pla...@spirent.com>

---
diff --git a/core/percpu.cc b/core/percpu.cc
--- a/core/percpu.cc
+++ b/core/percpu.cc
@@ -8,12 +8,13 @@

 #include <osv/percpu.hh>
 #include <bitset>
+#include <osv/align.hh>
 #include <osv/debug.hh>
+#include <osv/ilog2.hh>

 static constexpr size_t dynamic_percpu_max = 65536;

-union dynamic_percpu_buffer {
-    long align;
+struct dynamic_percpu_buffer {
     char buf[dynamic_percpu_max];
 };

@@ -28,8 +29,14 @@ size_t dynamic_percpu_base()

 size_t dynamic_percpu_alloc(size_t size, size_t align)
 {
+    assert(is_power_of_two(align));
     std::lock_guard<mutex> guard(mtx);
-    for (size_t i = 0; i < dynamic_percpu_max; i += align) {
+
+ /* Find the first value in the bitmap that has the necessary alignment */
+    auto percpu_base = dynamic_percpu_base();
+    auto align_base = align_up(percpu_base, align) - percpu_base;
+
+    for (size_t i = align_base; i < dynamic_percpu_max; i += align) {
         size_t j = 0;
         for (; j < size; ++j) {
             if (dynamic_percpu_allocated.test(i + j)) {
@@ -40,7 +47,8 @@ size_t dynamic_percpu_alloc(size_t size, size_t align)
             for (j = 0; j < size; ++j) {
                 dynamic_percpu_allocated.set(i + j, true);
             }
-            return dynamic_percpu_base() + i;
+            assert(align_check(percpu_base + i, align));
+            return percpu_base + i;
         }
     }
     abort("exhausted dynamic percpu pool");
@@ -54,4 +62,3 @@ void dynamic_percpu_free(size_t offset, size_t size)
         dynamic_percpu_allocated.set(offset + j, false);
     }
 }
-

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to