trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zw...@apache.org
Subject [trafficserver] 07/08: Add MIMEHdr Garbage Collection to HPACK Dynamic Table
Date Tue, 10 Dec 2019 23:21:36 GMT
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 6a4edd300732a79161a914bf4a7216e9b22ac2b4
Author: Masaori Koshiba <masaori@apache.org>
AuthorDate: Thu Jul 4 12:03:53 2019 +0900

    Add MIMEHdr Garbage Collection to HPACK Dynamic Table
    
    Prior this change, the size of HdrHeap which is owned by MIMEHdr of HpackDynamicTable
had no limit.
    Because when MIMEFiled is deleted the allocated memory of the HdrHeap was not freed.
    To mitigate this issue, when HdrHeap size exceeds the threshold, HpackDynamicTable start
using new MIMEHdr and HdrHeap.
    The old MIMEHdr and HdrHeap will be freed, when all MIMEFiled is deleted by HPACK Dynamic
Table Entry Eviction.
    
    (cherry picked from commit 2bbcc48195e98b65b681a7e28c9ae1c2ab5d6994)
---
 proxy/hdrs/HdrHeap.cc | 18 +++++++++++++++++
 proxy/hdrs/HdrHeap.h  |  2 ++
 proxy/http2/HPACK.cc  | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
 proxy/http2/HPACK.h   | 16 ++++++---------
 4 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/proxy/hdrs/HdrHeap.cc b/proxy/hdrs/HdrHeap.cc
index c10d6e5..1452a8e 100644
--- a/proxy/hdrs/HdrHeap.cc
+++ b/proxy/hdrs/HdrHeap.cc
@@ -1124,6 +1124,24 @@ HdrHeap::dump_heap(int len)
   fprintf(stderr, "\n-------------- End header heap dump -----------\n");
 }
 
+uint64_t
+HdrHeap::total_used_size() const
+{
+  uint64_t size    = 0;
+  const HdrHeap *h = this;
+
+  while (h) {
+    size += (h->m_free_start - h->m_data_start);
+    h = h->m_next;
+  }
+
+  return size;
+}
+
+//
+// HdrStrHeap
+//
+
 void
 HdrStrHeap::free()
 {
diff --git a/proxy/hdrs/HdrHeap.h b/proxy/hdrs/HdrHeap.h
index e7c075c..1d83c85 100644
--- a/proxy/hdrs/HdrHeap.h
+++ b/proxy/hdrs/HdrHeap.h
@@ -287,6 +287,8 @@ public:
   size_t required_space_for_evacuation();
   bool attach_str_heap(char const *h_start, int h_len, RefCountObj *h_ref_obj, int *index);
 
+  uint64_t total_used_size() const;
+
   /** Struct to prevent garbage collection on heaps.
       This bumps the reference count to the heap containing the pointer
       while the instance of this class exists. When it goes out of scope
diff --git a/proxy/http2/HPACK.cc b/proxy/http2/HPACK.cc
index 7fa62cc..b13e7c6 100644
--- a/proxy/http2/HPACK.cc
+++ b/proxy/http2/HPACK.cc
@@ -166,6 +166,21 @@ static const StaticTable STATIC_TABLE[] = {{"", ""},
                                            {"via", ""},
                                            {"www-authenticate", ""}};
 
+/**
+  Threshold for total HdrHeap size which used by HPAK Dynamic Table.
+  The HdrHeap is filled by MIMEHdrImpl and MIMEFieldBlockImpl like below.
+  This threshold allow to allocate 3 HdrHeap at maximum.
+
+                     +------------------+-----------------------------+
+   HdrHeap 1 (2048): | MIMEHdrImpl(592) | MIMEFieldBlockImpl(528) x 2 |
+                     +------------------+-----------------------------+--...--+
+   HdrHeap 2 (4096): | MIMEFieldBlockImpl(528) x 7                            |
+                     +------------------------------------------------+--...--+--...--+
+   HdrHeap 3 (8192): | MIMEFieldBlockImpl(528) x 15                                   |
+                     +------------------------------------------------+--...--+--...--+
+*/
+static constexpr uint32_t HPACK_HDR_HEAP_THRESHOLD = sizeof(MIMEHdrImpl) + sizeof(MIMEFieldBlockImpl)
* (2 + 7 + 15);
+
 /******************
  * Local functions
  ******************/
@@ -318,6 +333,24 @@ HpackIndexingTable::update_maximum_size(uint32_t new_size)
   return _dynamic_table->update_maximum_size(new_size);
 }
 
+//
+// HpackDynamicTable
+//
+HpackDynamicTable::~HpackDynamicTable()
+{
+  this->_headers.clear();
+
+  this->_mhdr->fields_clear();
+  this->_mhdr->destroy();
+  delete this->_mhdr;
+
+  if (this->_mhdr_old != nullptr) {
+    this->_mhdr_old->fields_clear();
+    this->_mhdr_old->destroy();
+    delete this->_mhdr_old;
+  }
+}
+
 const MIMEField *
 HpackDynamicTable::get_header_field(uint32_t index) const
 {
@@ -413,9 +446,32 @@ HpackDynamicTable::_evict_overflowed_entries()
     return false;
   }
 
+  this->_mime_hdr_gc();
+
   return true;
 }
 
+/**
+   When HdrHeap size of current MIMEHdr exceeds the threshold, allocate new MIMEHdr and HdrHeap.
+   The old MIMEHdr and HdrHeap will be freed, when all MIMEFiled are deleted by HPACK Entry
Eviction.
+ */
+void
+HpackDynamicTable::_mime_hdr_gc()
+{
+  if (this->_mhdr_old == nullptr) {
+    if (this->_mhdr->m_heap->total_used_size() >= HPACK_HDR_HEAP_THRESHOLD) {
+      this->_mhdr_old = this->_mhdr;
+      this->_mhdr     = new MIMEHdr();
+      this->_mhdr->create();
+    }
+  } else {
+    if (this->_mhdr_old->fields_count() == 0) {
+      this->_mhdr_old->destroy();
+      this->_mhdr_old = nullptr;
+    }
+  }
+}
+
 int64_t
 encode_indexed_header_field(uint8_t *buf_start, const uint8_t *buf_end, uint32_t index)
 {
diff --git a/proxy/http2/HPACK.h b/proxy/http2/HPACK.h
index 16c8e01..580792e 100644
--- a/proxy/http2/HPACK.h
+++ b/proxy/http2/HPACK.h
@@ -112,13 +112,7 @@ public:
     _mhdr->create();
   }
 
-  ~HpackDynamicTable()
-  {
-    _headers.clear();
-    _mhdr->fields_clear();
-    _mhdr->destroy();
-    delete _mhdr;
-  }
+  ~HpackDynamicTable();
 
   // noncopyable
   HpackDynamicTable(HpackDynamicTable &) = delete;
@@ -135,11 +129,13 @@ public:
 
 private:
   bool _evict_overflowed_entries();
+  void _mime_hdr_gc();
 
-  uint32_t _current_size;
-  uint32_t _maximum_size;
+  uint32_t _current_size = 0;
+  uint32_t _maximum_size = 0;
 
-  MIMEHdr *_mhdr;
+  MIMEHdr *_mhdr     = nullptr;
+  MIMEHdr *_mhdr_old = nullptr;
   std::vector<MIMEField *> _headers;
 };
 


Mime
View raw message