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.nakash...@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 <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@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(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits