]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: rebuild Buffer buffers with too much waste
authorSage Weil <sage@redhat.com>
Fri, 26 May 2017 20:02:00 +0000 (16:02 -0400)
committerSage Weil <sage@redhat.com>
Tue, 30 May 2017 01:56:18 +0000 (21:56 -0400)
Avoid pinning extra memory by rebuilding Buffer buffers when we waste too
much.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index 647819486f22acccff9dc0ce13c7d0f456fb4784..1552b3248e0a1fdaba8b46f6742072705b0edb64 100644 (file)
@@ -1270,14 +1270,18 @@ int BlueStore::BufferSpace::_discard(Cache* cache, uint32_t offset, uint32_t len
        if (b->data.length()) {
          bufferlist bl;
          bl.substr_of(b->data, b->length - tail, tail);
-         _add_buffer(cache, new Buffer(this, b->state, b->seq, end, bl), 0, b);
+         Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
+         nb->maybe_rebuild();
+         _add_buffer(cache, nb, 0, b);
        } else {
-         _add_buffer(cache, new Buffer(this, b->state, b->seq, end, tail), 0, b);
+         _add_buffer(cache, new Buffer(this, b->state, b->seq, end, tail),
+                     0, b);
        }
        if (!b->is_writing()) {
          cache->_adjust_buffer_size(b, front - (int64_t)b->length);
        }
        b->truncate(front);
+       b->maybe_rebuild();
        cache->_audit("discard end 1");
        break;
       } else {
@@ -1286,6 +1290,7 @@ int BlueStore::BufferSpace::_discard(Cache* cache, uint32_t offset, uint32_t len
          cache->_adjust_buffer_size(b, front - (int64_t)b->length);
        }
        b->truncate(front);
+       b->maybe_rebuild();
        ++i;
        continue;
       }
@@ -1300,7 +1305,9 @@ int BlueStore::BufferSpace::_discard(Cache* cache, uint32_t offset, uint32_t len
     if (b->data.length()) {
       bufferlist bl;
       bl.substr_of(b->data, b->length - keep, keep);
-      _add_buffer(cache, new Buffer(this, b->state, b->seq, end, bl), 0, b);
+      Buffer *nb = new Buffer(this, b->state, b->seq, end, bl);
+      nb->maybe_rebuild();
+      _add_buffer(cache, nb, 0, b);
     } else {
       _add_buffer(cache, new Buffer(this, b->state, b->seq, end, keep), 0, b);
     }
index 5063395f9508607f34840753f90a60da7230fe1b..a9db4e509a5096b02cad72d71fe7a243b917dca5 100644 (file)
@@ -49,6 +49,12 @@ class BlueFS;
 //#define DEBUG_CACHE
 //#define DEBUG_DEFERRED
 
+
+
+// constants for Buffer::optimize()
+#define MAX_BUFFER_SLOP_RATIO_DEN  8  // so actually 1/N
+
+
 enum {
   l_bluestore_first = 732430,
   l_bluestore_kv_flush_lat,
@@ -210,6 +216,13 @@ public:
       }
       length = newlen;
     }
+    void maybe_rebuild() {
+      if (data.length() &&
+         (data.get_num_buffers() > 1 ||
+          data.front().wasted() > data.length() / MAX_BUFFER_SLOP_RATIO_DEN)) {
+       data.rebuild();
+      }
+    }
 
     void dump(Formatter *f) const {
       f->dump_string("state", get_state_name(state));