From: Loic Dachary Date: Mon, 1 Dec 2014 23:59:08 +0000 (+0100) Subject: common: add bufferlist::rebuild_aligned_size_and_memory X-Git-Tag: v0.91~166^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9ade88e8dacc9b96c042bb668f4452447139a544;p=ceph.git common: add bufferlist::rebuild_aligned_size_and_memory 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 --- diff --git a/src/common/buffer.cc b/src/common/buffer.cc index f50d103e479..c966b5cf9bc 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -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::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; } diff --git a/src/include/buffer.h b/src/include/buffer.h index 0c917302f6b..2e19a90e59f 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -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 diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index 73b0641801d..c1ff85ed115 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -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;