[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