/* * Copyright © 2012-2013 Canonical Ltd. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Thomas Voß */ #ifndef CORE_POSIX_LINUX_PROC_PROCESS_OOM_SCORE_ADJ_H_ #define CORE_POSIX_LINUX_PROC_PROCESS_OOM_SCORE_ADJ_H_ #include namespace core { namespace posix { class Process; namespace linux { namespace proc { namespace process { /** * This file can be used to adjust the badness heuristic used to select which * process gets killed in out-of-memory conditions. * * The badness heuristic assigns a value to each candidate task ranging from 0 * (never kill) to 1000 (always kill) to determine which process is targeted. * The units are roughly a proportion along that range of allowed memory the * process may allocate from, based on an estimation of its current memory and * swap use. For example, if a task is using all allowed memory, its badness * score will be 1000. If it is using half of its allowed memory, its score * will be 500. * * There is an additional factor included in the badness score: root processes are * given 3% extra memory over other tasks. * * The amount of "allowed" memory depends on the context in which the * OOM-killer was called. If it is due to the memory assigned to the allocating * task's cpuset being exhausted, the allowed memory represents the set of mems * assigned to that cpuset (see cpuset(7)). If it is due to a mempolicy's node(s) * being exhausted, the allowed memory represents the set of mempolicy nodes. If * it is due to a memory limit (or swap limit) being reached, the allowed memory * is that configured limit. Finally, if it is due to the entire system being out * of memory, the allowed memory represents all allocatable resources. * * The value of oom_score_adj is added to the badness score before it is used * to determine which task to kill. Acceptable values range from -1000 * (OOM_SCORE_ADJ_MIN) to +1000 (OOM_SCORE_ADJ_MAX). This allows user space to * control the preference for OOM-killing, ranging from always preferring a * certain task or completely disabling it from OOM- killing. The lowest possible * value, -1000, is equivalent to disabling OOM-killing entirely for that task, * since it will always report a badness score of 0. * * Consequently, it is very simple for user space to define the amount of * memory to consider for each task. Setting a oom_score_adj value of +500, for * example, is roughly equivalent to allowing the remainder of tasks sharing * the same system, cpuset, mempolicy, or memory controller resources to use at * least 50% more memory. A value of -500, on the other hand, would be roughly * equivalent to discounting 50% of the task's allowed memory from being * considered as scoring against the task. * * For backward compatibility with previous kernels, /proc/[pid]/oom_adj can * still be used to tune the badness score. Its value is scaled linearly with * oom_score_adj. * * Writing to /proc/[pid]/oom_score_adj or /proc/[pid]/oom_adj will change the * other with its scaled value. */ struct CORE_POSIX_DLL_PUBLIC OomScoreAdj { /** * @brief Returns the minimum valid value. * @return The minimum valid value that the Oom Score Adj can be set to. */ static int min_value(); /** * @brief Returns the maximum valid value. * @return The maximum valid value that the Oom Score Adj can be set to. */ static int max_value(); /** * @brief is_valid checks whether the contained value is within the predefined bounds. * @return true iff min_value() <= value <= max_value(). */ inline bool is_valid() const { return (min_value() <= value) && (value <= max_value()); } /** * @brief Current value. */ int value; }; /** * @brief Read the OomScoreAdj value for a process instance. * @throw std::runtime_error in case of errors. * @param [in] process The process to read the score for. * @param [out] score_adj The destination to store the value in. */ CORE_POSIX_DLL_PUBLIC const posix::Process& operator>>(const posix::Process& process, OomScoreAdj& score_adj); /** * @brief Write the OomScoreAdj value for a process instance. * @throw std::runtime_error in case of errors and std::logic_error if score_adj.is_valid() returns false. * @param [in] process The process to write the score for. * @param [in] score_adj The new value to store. */ CORE_POSIX_DLL_PUBLIC const posix::Process& operator<<(const posix::Process& process, const OomScoreAdj& score_adj); } } } } } #endif // CORE_POSIX_LINUX_PROC_PROCESS_OOM_SCORE_ADJ_H_