mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1082290 - Add memory cgroup support to FxOS process control. r=gsvelto
This commit is contained in:
parent
bcaf7910f2
commit
f49858767d
@ -728,22 +728,30 @@ pref("hal.processPriorityManager.gonk.BACKGROUND.KillUnderKB", 20480);
|
||||
pref("hal.processPriorityManager.gonk.BACKGROUND.cgroup", "apps/bg_non_interactive");
|
||||
|
||||
// Control group definitions (i.e., CPU priority groups) for B2G processes.
|
||||
//
|
||||
// memory_swappiness - 0 - The kernel will swap only to avoid an out of memory condition
|
||||
// memory_swappiness - 60 - The default value.
|
||||
// memory_swappiness - 100 - The kernel will swap aggressively.
|
||||
|
||||
// Foreground apps
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_shares", 1024);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_notify_on_migrate", 0);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps.memory_swappiness", 10);
|
||||
|
||||
// Foreground apps with high priority, 16x more CPU than foreground ones
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_shares", 16384);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_notify_on_migrate", 0);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.memory_swappiness", 0);
|
||||
|
||||
// Background perceivable apps, ~10x less CPU than foreground ones
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_shares", 103);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_notify_on_migrate", 0);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.memory_swappiness", 60);
|
||||
|
||||
// Background apps, ~20x less CPU than foreground ones and ~2x less than perceivable ones
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_shares", 52);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_notify_on_migrate", 0);
|
||||
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.memory_swappiness", 100);
|
||||
|
||||
// By default the compositor thread on gonk runs without real-time priority. RT
|
||||
// priority can be enabled by setting this pref to a value between 1 and 99.
|
||||
|
@ -1351,7 +1351,8 @@ private:
|
||||
ProcessPriority mPriority;
|
||||
int32_t mOomScoreAdj;
|
||||
int32_t mKillUnderKB;
|
||||
int mCGroupProcsFd;
|
||||
int mCpuCGroupProcsFd;
|
||||
int mMemCGroupProcsFd;
|
||||
nsCString mGroup;
|
||||
|
||||
/**
|
||||
@ -1368,7 +1369,7 @@ private:
|
||||
/**
|
||||
* Get the full path of the cgroup.procs file associated with the group.
|
||||
*/
|
||||
nsCString CGroupProcsFilename()
|
||||
nsCString CpuCGroupProcsFilename()
|
||||
{
|
||||
nsCString cgroupName = mGroup;
|
||||
|
||||
@ -1384,9 +1385,30 @@ private:
|
||||
NS_LITERAL_CSTRING("cgroup.procs");
|
||||
}
|
||||
|
||||
int OpenCGroupProcs()
|
||||
nsCString MemCGroupProcsFilename()
|
||||
{
|
||||
return open(CGroupProcsFilename().get(), O_WRONLY);
|
||||
nsCString cgroupName = mGroup;
|
||||
|
||||
/* If mGroup is empty, our cgroup.procs file is the root procs file,
|
||||
* located at /sys/fs/cgroup/memory/cgroup.procs. Otherwise our procs
|
||||
* file is /sys/fs/cgroup/memory/NAME/cgroup.procs. */
|
||||
|
||||
if (!mGroup.IsEmpty()) {
|
||||
cgroupName.AppendLiteral("/");
|
||||
}
|
||||
|
||||
return NS_LITERAL_CSTRING("/sys/fs/cgroup/memory/") + cgroupName +
|
||||
NS_LITERAL_CSTRING("cgroup.procs");
|
||||
}
|
||||
|
||||
int OpenCpuCGroupProcs()
|
||||
{
|
||||
return open(CpuCGroupProcsFilename().get(), O_WRONLY);
|
||||
}
|
||||
|
||||
int OpenMemCGroupProcs()
|
||||
{
|
||||
return open(MemCGroupProcsFilename().get(), O_WRONLY);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1401,11 +1423,14 @@ private:
|
||||
* exists. Otherwise, return false.
|
||||
*/
|
||||
static bool
|
||||
EnsureCGroupExists(const nsACString &aGroup)
|
||||
EnsureCpuCGroupExists(const nsACString &aGroup)
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(kDevCpuCtl, "/dev/cpuctl/");
|
||||
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
|
||||
|
||||
nsAutoCString groupName(aGroup);
|
||||
HAL_LOG("EnsureCpuCGroupExists for group '%s'", groupName.get());
|
||||
|
||||
nsAutoCString prefPrefix("hal.processPriorityManager.gonk.cgroups.");
|
||||
|
||||
/* If cgroup is not empty, append the cgroup name and a dot to obtain the
|
||||
@ -1436,6 +1461,7 @@ EnsureCGroupExists(const nsACString &aGroup)
|
||||
|
||||
offset++;
|
||||
}
|
||||
HAL_LOG("EnsureCpuCGroupExists created group '%s'", groupName.get());
|
||||
|
||||
nsAutoCString pathPrefix(kDevCpuCtl + aGroup + kSlash);
|
||||
nsAutoCString cpuSharesPath(pathPrefix + NS_LITERAL_CSTRING("cpu.shares"));
|
||||
@ -1457,11 +1483,61 @@ EnsureCGroupExists(const nsACString &aGroup)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EnsureMemCGroupExists(const nsACString &aGroup)
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(kMemCtl, "/sys/fs/cgroup/memory/");
|
||||
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
|
||||
|
||||
nsAutoCString groupName(aGroup);
|
||||
HAL_LOG("EnsureMemCGroupExists for group '%s'", groupName.get());
|
||||
|
||||
nsAutoCString prefPrefix("hal.processPriorityManager.gonk.cgroups.");
|
||||
|
||||
/* If cgroup is not empty, append the cgroup name and a dot to obtain the
|
||||
* group specific preferences. */
|
||||
if (!aGroup.IsEmpty()) {
|
||||
prefPrefix += aGroup + NS_LITERAL_CSTRING(".");
|
||||
}
|
||||
|
||||
nsAutoCString memSwappinessPref(prefPrefix + NS_LITERAL_CSTRING("memory_swappiness"));
|
||||
int memSwappiness = Preferences::GetInt(memSwappinessPref.get());
|
||||
|
||||
// Create mCGroup and its parent directories, as necessary.
|
||||
nsCString cgroupIter = aGroup + kSlash;
|
||||
|
||||
int32_t offset = 0;
|
||||
while ((offset = cgroupIter.FindChar('/', offset)) != -1) {
|
||||
nsAutoCString path = kMemCtl + Substring(cgroupIter, 0, offset);
|
||||
int rv = mkdir(path.get(), 0744);
|
||||
|
||||
if (rv == -1 && errno != EEXIST) {
|
||||
HAL_LOG("Could not create the %s control group.", path.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
offset++;
|
||||
}
|
||||
HAL_LOG("EnsureMemCGroupExists created group '%s'", groupName.get());
|
||||
|
||||
nsAutoCString pathPrefix(kMemCtl + aGroup + kSlash);
|
||||
nsAutoCString memSwappinessPath(pathPrefix + NS_LITERAL_CSTRING("memory.swappiness"));
|
||||
if (!WriteToFile(memSwappinessPath.get(),
|
||||
nsPrintfCString("%d", memSwappiness).get())) {
|
||||
HAL_LOG("Could not set the memory.swappiness for group %s", memSwappinessPath.get());
|
||||
return false;
|
||||
}
|
||||
HAL_LOG("Set memory.swappiness for group %s to %d", memSwappinessPath.get(), memSwappiness);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PriorityClass::PriorityClass(ProcessPriority aPriority)
|
||||
: mPriority(aPriority)
|
||||
, mOomScoreAdj(0)
|
||||
, mKillUnderKB(0)
|
||||
, mCGroupProcsFd(-1)
|
||||
, mCpuCGroupProcsFd(-1)
|
||||
, mMemCGroupProcsFd(-1)
|
||||
{
|
||||
DebugOnly<nsresult> rv;
|
||||
|
||||
@ -1475,14 +1551,18 @@ PriorityClass::PriorityClass(ProcessPriority aPriority)
|
||||
rv = Preferences::GetCString(PriorityPrefName("cgroup").get(), &mGroup);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Missing control group preference");
|
||||
|
||||
if (EnsureCGroupExists(mGroup)) {
|
||||
mCGroupProcsFd = OpenCGroupProcs();
|
||||
if (EnsureCpuCGroupExists(mGroup)) {
|
||||
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
|
||||
}
|
||||
if (EnsureMemCGroupExists(mGroup)) {
|
||||
mMemCGroupProcsFd = OpenMemCGroupProcs();
|
||||
}
|
||||
}
|
||||
|
||||
PriorityClass::~PriorityClass()
|
||||
{
|
||||
close(mCGroupProcsFd);
|
||||
close(mCpuCGroupProcsFd);
|
||||
close(mMemCGroupProcsFd);
|
||||
}
|
||||
|
||||
PriorityClass::PriorityClass(const PriorityClass& aOther)
|
||||
@ -1491,7 +1571,8 @@ PriorityClass::PriorityClass(const PriorityClass& aOther)
|
||||
, mKillUnderKB(aOther.mKillUnderKB)
|
||||
, mGroup(aOther.mGroup)
|
||||
{
|
||||
mCGroupProcsFd = OpenCGroupProcs();
|
||||
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
|
||||
mMemCGroupProcsFd = OpenMemCGroupProcs();
|
||||
}
|
||||
|
||||
PriorityClass& PriorityClass::operator=(const PriorityClass& aOther)
|
||||
@ -1500,20 +1581,26 @@ PriorityClass& PriorityClass::operator=(const PriorityClass& aOther)
|
||||
mOomScoreAdj = aOther.mOomScoreAdj;
|
||||
mKillUnderKB = aOther.mKillUnderKB;
|
||||
mGroup = aOther.mGroup;
|
||||
mCGroupProcsFd = OpenCGroupProcs();
|
||||
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
|
||||
mMemCGroupProcsFd = OpenMemCGroupProcs();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PriorityClass::AddProcess(int aPid)
|
||||
{
|
||||
if (mCGroupProcsFd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCpuCGroupProcsFd >= 0) {
|
||||
nsPrintfCString str("%d", aPid);
|
||||
|
||||
if (write(mCGroupProcsFd, str.get(), strlen(str.get())) < 0) {
|
||||
HAL_ERR("Couldn't add PID %d to the %s control group", aPid, mGroup.get());
|
||||
if (write(mCpuCGroupProcsFd, str.get(), strlen(str.get())) < 0) {
|
||||
HAL_ERR("Couldn't add PID %d to the %s cpu control group", aPid, mGroup.get());
|
||||
}
|
||||
}
|
||||
if (mMemCGroupProcsFd >= 0) {
|
||||
nsPrintfCString str("%d", aPid);
|
||||
|
||||
if (write(mMemCGroupProcsFd, str.get(), strlen(str.get())) < 0) {
|
||||
HAL_ERR("Couldn't add PID %d to the %s memory control group", aPid, mGroup.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user