]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: add bufferlist::rebuild_aligned_size_and_memory
authorLoic Dachary <ldachary@redhat.com>
Mon, 1 Dec 2014 23:59:08 +0000 (00:59 +0100)
committerLoic Dachary <ldachary@redhat.com>
Tue, 2 Dec 2014 20:15:21 +0000 (21:15 +0100)
The function bufferlist::rebuild_aligned checks memory and size
alignment with the same variable. It is however useful to separate
memory alignment constraints from size alignment constraints. For
instance rebuild_aligned could be called to allocate an erasure coded
buffer where each 2048 bytes chunk needs to start on a memory address
aligned on 32 bytes.

Signed-off-by: Loic Dachary <loic@dachary.org>
src/common/buffer.cc
src/include/buffer.h
src/test/bufferlist.cc

index f50d103e479d0c4f85e1a491928fccbb283fc612..c966b5cf9bcfab22e0aeea5b2d6f461d77f89dd7 100644 (file)
@@ -1118,11 +1118,17 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   }
 
 void buffer::list::rebuild_aligned(unsigned align)
+{
+  rebuild_aligned_size_and_memory(align, align);
+}
+
+void buffer::list::rebuild_aligned_size_and_memory(unsigned align_size,
+                                                  unsigned align_memory)
 {
   std::list<ptr>::iterator p = _buffers.begin();
   while (p != _buffers.end()) {
     // keep anything that's already align and sized aligned
-    if (p->is_aligned(align) && p->is_n_align_sized(align)) {
+    if (p->is_aligned(align_memory) && p->is_n_align_sized(align_size)) {
       /*cout << " segment " << (void*)p->c_str()
             << " offset " << ((unsigned long)p->c_str() & (align - 1))
             << " length " << p->length()
@@ -1146,11 +1152,11 @@ void buffer::list::rebuild_aligned(unsigned align)
       unaligned.push_back(*p);
       _buffers.erase(p++);
     } while (p != _buffers.end() &&
-            (!p->is_aligned(align) ||
-             !p->is_n_align_sized(align) ||
-             (offset & (align-1))));
-    if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align))) {
-      ptr nb(buffer::create_aligned(unaligned._len, align));
+            (!p->is_aligned(align_memory) ||
+             !p->is_n_align_sized(align_size) ||
+             (offset % align_size)));
+    if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align_memory))) {
+      ptr nb(buffer::create_aligned(unaligned._len, align_memory));
       unaligned.rebuild(nb);
       _memcopy_count += unaligned._len;
     }
index 0c917302f6b552724180a4753666f902c0ab5508..2e19a90e59f24eaeb96fcead2dff81733b1e2bb4 100644 (file)
@@ -394,6 +394,8 @@ public:
     void rebuild();
     void rebuild(ptr& nb);
     void rebuild_aligned(unsigned align);
+    void rebuild_aligned_size_and_memory(unsigned align_size,
+                                        unsigned align_memory);
     void rebuild_page_aligned();
 
     // sort-of-like-assignment-op
index 73b0641801d17302579cd2f9e7dffc05ab8fd60a..c1ff85ed115e0a1fa465f9f0bd71d9c23ca5746c 100644 (file)
@@ -1229,6 +1229,52 @@ TEST(BufferList, is_n_page_sized) {
   }
 }
 
+TEST(BufferList, rebuild_aligned_size_and_memory) {
+  const unsigned SIMD_ALIGN = 32;
+  const unsigned BUFFER_SIZE = 67;
+
+  bufferlist bl;
+  // These two must be concatenated into one memory + size aligned
+  // bufferptr
+  {
+    bufferptr ptr(buffer::create_aligned(2, SIMD_ALIGN));
+    ptr.set_offset(1);
+    ptr.set_length(1);
+    bl.append(ptr);
+  }
+  {
+    bufferptr ptr(buffer::create_aligned(BUFFER_SIZE - 1, SIMD_ALIGN));
+    bl.append(ptr);
+  }
+  // This one must be left alone
+  {
+    bufferptr ptr(buffer::create_aligned(BUFFER_SIZE, SIMD_ALIGN));
+    bl.append(ptr);
+  }
+  // These two must be concatenated into one memory + size aligned
+  // bufferptr
+  {
+    bufferptr ptr(buffer::create_aligned(2, SIMD_ALIGN));
+    ptr.set_offset(1);
+    ptr.set_length(1);
+    bl.append(ptr);
+  }
+  {
+    bufferptr ptr(buffer::create_aligned(BUFFER_SIZE - 1, SIMD_ALIGN));
+    bl.append(ptr);
+  }
+  EXPECT_FALSE(bl.is_aligned(SIMD_ALIGN));
+  EXPECT_FALSE(bl.is_n_align_sized(BUFFER_SIZE));
+  EXPECT_EQ(BUFFER_SIZE * 3, bl.length());
+  EXPECT_FALSE(bl.buffers().front().is_aligned(SIMD_ALIGN));
+  EXPECT_FALSE(bl.buffers().front().is_n_align_sized(BUFFER_SIZE));
+  EXPECT_EQ(5U, bl.buffers().size());
+  bl.rebuild_aligned_size_and_memory(BUFFER_SIZE, SIMD_ALIGN);
+  EXPECT_TRUE(bl.is_aligned(SIMD_ALIGN));
+  EXPECT_TRUE(bl.is_n_align_sized(BUFFER_SIZE));
+  EXPECT_EQ(3U, bl.buffers().size());
+}
+
 TEST(BufferList, is_zero) {
   {
     bufferlist bl;