From fba63cebba215b36ce850f47bd8e706edaa8023e Mon Sep 17 00:00:00 2001 From: Jianpeng Ma Date: Fri, 10 Nov 2017 22:47:41 +0800 Subject: [PATCH] common/buffers: add function parameter to limit buffers size. Fixes: http://tracker.ceph.com/issues/21932 Signed-off-by: Jianpeng Ma --- src/common/buffer.cc | 8 +++++++- src/include/buffer.h | 5 ++++- src/os/bluestore/KernelDevice.cc | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index f7d8b17fcdcf8..e2f140a00558c 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1756,9 +1756,15 @@ public: } bool buffer::list::rebuild_aligned_size_and_memory(unsigned align_size, - unsigned align_memory) + unsigned align_memory, + unsigned max_buffers) { unsigned old_memcopy_count = _memcopy_count; + + if (max_buffers && _buffers.size() > max_buffers + && _len > (max_buffers * align_size)) { + align_size = ROUND_UP_TO(ROUND_UP_TO(_len, max_buffers) / max_buffers, align_size); + } std::list::iterator p = _buffers.begin(); while (p != _buffers.end()) { // keep anything that's already align and sized aligned diff --git a/src/include/buffer.h b/src/include/buffer.h index fa8689cc6b7d3..0d4bc0adf5f62 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -780,8 +780,11 @@ namespace buffer CEPH_BUFFER_API { void rebuild(); void rebuild(ptr& nb); bool rebuild_aligned(unsigned align); + // max_buffers = 0 mean don't care _buffers.size(), other + // must make _buffers.size() <= max_buffers after rebuilding. bool rebuild_aligned_size_and_memory(unsigned align_size, - unsigned align_memory); + unsigned align_memory, + unsigned max_buffers = 0); bool rebuild_page_aligned(); void reserve(size_t prealloc); diff --git a/src/os/bluestore/KernelDevice.cc b/src/os/bluestore/KernelDevice.cc index cfa626d493e8c..58814ee78bf8c 100644 --- a/src/os/bluestore/KernelDevice.cc +++ b/src/os/bluestore/KernelDevice.cc @@ -593,7 +593,7 @@ int KernelDevice::write( assert(is_valid_io(off, len)); if ((!buffered || bl.get_num_buffers() >= IOV_MAX) && - bl.rebuild_aligned_size_and_memory(block_size, block_size)) { + bl.rebuild_aligned_size_and_memory(block_size, block_size, IOV_MAX)) { dout(20) << __func__ << " rebuilding buffer to be aligned" << dendl; } dout(40) << "data: "; @@ -620,7 +620,7 @@ int KernelDevice::aio_write( assert(off + len <= size); if ((!buffered || bl.get_num_buffers() >= IOV_MAX) && - bl.rebuild_aligned_size_and_memory(block_size, block_size)) { + bl.rebuild_aligned_size_and_memory(block_size, block_size, IOV_MAX)) { dout(20) << __func__ << " rebuilding buffer to be aligned" << dendl; } dout(40) << "data: "; -- 2.39.5