]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: add bufferlist::rebuild_aligned_size_and_memory 3083/head
authorLoic Dachary <ldachary@redhat.com>
Mon, 1 Dec 2014 23:59:08 +0000 (00:59 +0100)
committerLoic Dachary <ldachary@redhat.com>
Thu, 4 Dec 2014 18:05:22 +0000 (19:05 +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>
(cherry picked from commit 9ade88e8dacc9b96c042bb668f4452447139a544)

src/common/buffer.cc
src/include/buffer.h
src/test/bufferlist.cc

index 9ee2bfedf34113e7e819b48ff7d63b3e127c98dd..653bd9b748e36d975a1c4d7393cc92d9d0b1905b 100644 (file)
@@ -1116,11 +1116,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()
@@ -1144,11 +1150,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);
     }
     _buffers.insert(p, unaligned._buffers.front());
index 0ce133a29641637eaff13018f0c280cde7e5d0f4..da19cf95a5194fe006459a92ef728b66b9df1b92 100644 (file)
@@ -393,6 +393,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 da4d33ff2b4d91dd15ad4a92eb3d99a8649035d5..170bf7b465a02922c1006c75dc454333deffd424 100644 (file)
@@ -1212,6 +1212,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;