[Libreoffice-commits] online.git: common/Util.cpp common/Util.hpp wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Thu Jan 11 07:12:28 UTC 2018


 common/Util.cpp    |    2 -
 common/Util.hpp    |    2 -
 wsd/Admin.cpp      |   76 ++++++++++++++++++++++++-----------------------------
 wsd/Admin.hpp      |    6 ++--
 wsd/AdminModel.cpp |   23 +++++++++-------
 wsd/AdminModel.hpp |   25 +++++++++--------
 6 files changed, 66 insertions(+), 68 deletions(-)

New commits:
commit 59398af621d801e23817a4bad813c636b6164f58
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Wed Jan 10 23:53:47 2018 -0500

    wsd: simpler and more efficient OOM killing
    
    Change-Id: I118abdffba4e7ab57fe6a29a3a9fc420d871bdc0
    Reviewed-on: https://gerrit.libreoffice.org/47738
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/common/Util.cpp b/common/Util.cpp
index 480354da..72c150a4 100644
--- a/common/Util.cpp
+++ b/common/Util.cpp
@@ -170,7 +170,7 @@ namespace Util
         return nullptr;
     }
 
-    size_t getTotalSystemMemory()
+    size_t getTotalSystemMemoryKb()
     {
         size_t totalMemKb = 0;
         FILE* file = fopen("/proc/meminfo", "r");
diff --git a/common/Util.hpp b/common/Util.hpp
index 01b0018b..eef52464 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -98,7 +98,7 @@ namespace Util
     }
 
     /// Returns the total physical memory (in kB) available in the system
-    size_t getTotalSystemMemory();
+    size_t getTotalSystemMemoryKb();
 
     /// Returns the process PSS in KB (works only when we have perms for /proc/pid/smaps).
     size_t getMemoryUsagePSS(const Poco::Process::PID pid);
diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp
index 6fa67198..2c4dbc72 100644
--- a/wsd/Admin.cpp
+++ b/wsd/Admin.cpp
@@ -339,18 +339,18 @@ Admin::Admin() :
 {
     LOG_INF("Admin ctor.");
 
-    _totalSysMem = Util::getTotalSystemMemory();
-    LOG_TRC("Total system memory : " << _totalSysMem);
+    _totalSysMemKb = Util::getTotalSystemMemoryKb();
+    LOG_TRC("Total system memory:  " << _totalSysMemKb << " KB.");
 
     const auto memLimit = LOOLWSD::getConfigValue<double>("memproportion", 0.0);
-    _totalAvailMem = _totalSysMem;
+    _totalAvailMemKb = _totalSysMemKb;
     if (memLimit != 0.0)
-        _totalAvailMem = _totalSysMem * memLimit/100.;
+        _totalAvailMemKb = _totalSysMemKb * memLimit / 100.;
 
-    LOG_TRC("Total available memory: " << _totalAvailMem << " (memproportion: " << memLimit << ").");
+    LOG_TRC("Total available memory: " << _totalAvailMemKb << " KB (memproportion: " << memLimit << "%).");
 
     const auto totalMem = getTotalMemoryUsage();
-    LOG_TRC("Total memory used: " << totalMem);
+    LOG_TRC("Total memory used: " << totalMem << " KB.");
     _model.addMemStats(totalMem);
 }
 
@@ -392,7 +392,7 @@ void Admin::pollingThread()
             const auto totalMem = getTotalMemoryUsage();
             if (totalMem != _lastTotalMemory)
             {
-                LOG_TRC("Total memory used: " << totalMem);
+                LOG_TRC("Total memory used: " << totalMem << " KB.");
                 _lastTotalMemory = totalMem;
             }
 
@@ -550,54 +550,48 @@ void Admin::triggerMemoryCleanup(size_t totalMem)
 {
     // Trigger mem cleanup when we are consuming too much memory (as configured by sysadmin)
     const auto memLimit = LOOLWSD::getConfigValue<double>("memproportion", 0.0);
-    if (memLimit == 0.0 || _totalSysMem == 0)
+    if (memLimit == 0.0 || _totalSysMemKb == 0)
     {
-        LOG_TRC("Total memory we are consuming (in kB): " << totalMem <<
-                ". Not configured to do memory cleanup. Skipping memory cleanup.");
+        LOG_TRC("Total memory consumed: " << totalMem <<
+                " KB. Not configured to do memory cleanup. Skipping memory cleanup.");
         return;
     }
 
-    LOG_TRC("Total memory we are consuming (in kB): " << totalMem <<
-            ". Mem proportion for LOOL configured : " << memLimit);
+    LOG_TRC("Total memory consumed: " << totalMem << " KB. Configured LOOL memory proportion: " <<
+            memLimit << "% (" << static_cast<size_t>(_totalSysMemKb * memLimit / 100.) << " KB).");
 
-    float memToFreePercentage = 0;
-    if ( (memToFreePercentage = (totalMem/static_cast<double>(_totalSysMem)) - memLimit/100.) > 0.0 )
+    const double memToFreePercentage = (totalMem / static_cast<double>(_totalSysMemKb)) - memLimit / 100.;
+    int memToFreeKb = static_cast<int>(memToFreePercentage > 0.0 ? memToFreePercentage * _totalSysMemKb : 0);
+    // Don't kill documents to save a KB or two.
+    if (memToFreeKb > 1024)
     {
-        int memToFree = memToFreePercentage * _totalSysMem;
-        LOG_TRC("Memory to be freed (in kB) : " << memToFree);
         // prepare document list sorted by most idle times
-        std::list<DocBasicInfo> docList = _model.getDocumentsSortedByIdle();
+        const std::vector<DocBasicInfo> docList = _model.getDocumentsSortedByIdle();
 
-        LOG_TRC("Checking saved documents in document list, length: " << docList.size());
-        // Kill the saved documents first
-        std::list<DocBasicInfo>::iterator docIt = docList.begin();
-        while (docIt != docList.end() && memToFree > 0)
+        LOG_TRC("OOM: Memory to free: " << memToFreePercentage << "% (" <<
+                memToFreeKb << " KB) from " << docList.size() << " docs.");
+
+        for (const auto& doc : docList)
         {
-            LOG_TRC("Document: DocKey[" << docIt->_docKey << "], Idletime[" << docIt->_idleTime << "],"
-                    << " Saved: [" << docIt->_saved << "], Mem: [" << docIt->_mem << "].");
-            if (docIt->_saved)
+            LOG_TRC("OOM Document: DocKey: [" << doc.DocKey << "], Idletime: [" << doc.IdleTime << "]," <<
+                    " Saved: [" << doc.Saved << "], Mem: [" << doc.Mem << "].");
+            if (doc.Saved)
             {
-                // Kill and remove from list
-                LOG_DBG("OOM: Killing saved document with DocKey " << docIt->_docKey);
-                LOOLWSD::closeDocument(docIt->_docKey, "oom");
-                memToFree -= docIt->_mem;
-                docIt = docList.erase(docIt);
+                // Kill the saved documents first.
+                LOG_DBG("OOM: Killing saved document with DocKey [" << doc.DocKey << "] with " << doc.Mem << " KB.");
+                LOOLWSD::closeDocument(doc.DocKey, "oom");
+                memToFreeKb -= doc.Mem;
+                if (memToFreeKb <= 1024)
+                    break;
             }
             else
-                ++docIt;
-        }
-
-        // Save unsaved documents
-        docIt = docList.begin();
-        while (docIt != docList.end() && memToFree > 0)
-        {
-            LOG_TRC("Saving document: DocKey[" << docIt->_docKey << "].");
-            LOOLWSD::autoSave(docIt->_docKey);
-            ++docIt;
+            {
+                // Save unsaved documents.
+                LOG_TRC("Saving document: DocKey [" << doc.DocKey << "].");
+                LOOLWSD::autoSave(doc.DocKey);
+            }
         }
     }
-
-    LOG_TRC("OOM: Memory to free percentage : " << memToFreePercentage);
 }
 
 void Admin::dumpState(std::ostream& os)
diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp
index f8a20d11..724cbaec 100644
--- a/wsd/Admin.hpp
+++ b/wsd/Admin.hpp
@@ -72,7 +72,7 @@ public:
     size_t getTotalMemoryUsage();
     /// Takes into account the 'memproportion' property in config file to find the amount of memory
     /// available to us.
-    size_t getTotalAvailableMemory() { return _totalAvailMem; }
+    size_t getTotalAvailableMemory() { return _totalAvailMemKb; }
     size_t getTotalCpuUsage();
 
     void modificationAlert(const std::string& dockey, Poco::Process::PID pid, bool value);
@@ -136,8 +136,8 @@ private:
     size_t _lastJiffies;
     uint64_t _lastSentCount;
     uint64_t _lastRecvCount;
-    size_t _totalSysMem;
-    size_t _totalAvailMem;
+    size_t _totalSysMemKb;
+    size_t _totalAvailMemKb;
 
     std::atomic<int> _memStatsTaskIntervalMs;
     std::atomic<int> _cpuStatsTaskIntervalMs;
diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp
index d23c39ae..9b2f6770 100644
--- a/wsd/AdminModel.cpp
+++ b/wsd/AdminModel.cpp
@@ -627,23 +627,26 @@ unsigned AdminModel::getTotalActiveViews()
     return numTotalViews;
 }
 
-std::list<DocBasicInfo> AdminModel::getDocumentsSortedByIdle() const
+std::vector<DocBasicInfo> AdminModel::getDocumentsSortedByIdle() const
 {
-    std::list<DocBasicInfo> docList;
+    std::vector<DocBasicInfo> docs;
+    docs.reserve(_documents.size());
     for (const auto& it: _documents)
     {
-        docList.emplace_back(it.second.getDocKey(),
-                             it.second.getIdleTime(),
-                             !it.second.getModifiedStatus(),
-                             it.second.getMemoryDirty());
+        docs.emplace_back(it.second.getDocKey(),
+                          it.second.getIdleTime(),
+                          it.second.getMemoryDirty(),
+                          !it.second.getModifiedStatus());
     }
 
     // Sort the list by idle times;
-    docList.sort([](const DocBasicInfo& a, const DocBasicInfo& b) {
-            return a._idleTime > b._idleTime;
-        });
+    std::sort(std::begin(docs), std::end(docs),
+              [](const DocBasicInfo& a, const DocBasicInfo& b)
+              {
+                return a.IdleTime >= b.IdleTime;
+              });
 
-    return docList;
+    return docs;
 }
 
 std::string AdminModel::getDocuments() const
diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp
index adad7f56..69a9f455 100644
--- a/wsd/AdminModel.hpp
+++ b/wsd/AdminModel.hpp
@@ -58,17 +58,18 @@ struct DocProcSettings
 /// Containing basic information about document
 struct DocBasicInfo
 {
-    const std::string _docKey;
-    const std::time_t _idleTime;
-    const bool _saved;
-    const int _mem;
-
-    DocBasicInfo(const std::string& docKey, std::time_t idleTime, bool saved, int mem)
-        : _docKey(docKey),
-          _idleTime(idleTime),
-          _saved(saved),
-          _mem(mem)
-        { }
+    std::string DocKey;
+    std::time_t IdleTime;
+    int Mem;
+    bool Saved;
+
+    DocBasicInfo(const std::string& docKey, std::time_t idleTime, int mem, bool saved) :
+        DocKey(docKey),
+        IdleTime(idleTime),
+        Mem(mem),
+        Saved(saved)
+    {
+    }
 };
 
 /// A document in Admin controller.
@@ -266,7 +267,7 @@ public:
     uint64_t getRecvBytesTotal() { return _recvBytesTotal; }
 
     /// Document basic info list sorted by most idle time
-    std::list<DocBasicInfo> getDocumentsSortedByIdle() const;
+    std::vector<DocBasicInfo> getDocumentsSortedByIdle() const;
 
 private:
     std::string getMemStats();


More information about the Libreoffice-commits mailing list