#define SWAP_EARLYRECLAIM_TIME_DEFAULT 60
#define SWAP_EARLYRECLAIM_INTERVAL 1
#define SWAP_EARLYRECLAIM_MAXTRY 2
-#define SWAP_EARLYRECLAIM_THRESHOLD_DEFAULT MBYTE_TO_BYTE(1024)
+#define SWAP_EARLYRECLAIM_THRESHOLD_DEFAULT MBYTE_TO_BYTE(20)
#define EARLYRECLAIM_WITH_AN_EXPLANATION_FOR_LAYMEN "early memory reclaim (done to retrieve resources used by daemons during system start-up)"
static bool arg_swap_enable = false;
static bool arg_swap_at_boot = false;
-static int arg_timer_swap_at_boot = SWAP_EARLYRECLAIM_TIME_DEFAULT;
+static int arg_timer_swap_at_boot_sec = SWAP_EARLYRECLAIM_TIME_DEFAULT;
static enum swap_type arg_swap_type = SWAP_TYPE_ZRAM;
static int current_swappiness = SWAP_MEMCG_SWAPPINESS;
static GSList *swap_module; /* module list */
static GSource *swap_activating_timer = NULL;
-static unsigned long arg_swap_at_boot_threshold = SWAP_EARLYRECLAIM_THRESHOLD_DEFAULT;
+static unsigned long long arg_swap_at_boot_threshold_bytes = SWAP_EARLYRECLAIM_THRESHOLD_DEFAULT;
static int arg_swap_at_boot_maxtry = SWAP_EARLYRECLAIM_MAXTRY;
-static int arg_swap_at_boot_interval = SWAP_EARLYRECLAIM_INTERVAL;
+static int arg_swap_at_boot_interval_sec = SWAP_EARLYRECLAIM_INTERVAL;
static int swap_sort_func(const struct swap_module_ops *a,
const struct swap_module_ops *b)
void swap_add(const struct swap_module_ops *ops)
{
- _I("Swap module name: %s", ops->name);
swap_module = g_slist_insert_sorted(swap_module,
(gpointer)ops,
(GCompareFunc) swap_sort_func);
return "";
}
-static unsigned int swap_calculate_hard_limit_in_bytes(unsigned int mem_subcg_usage)
+static inline unsigned long long swap_calculate_hard_limit_in_bytes(unsigned long long mem_subcg_usage_bytes)
{
- return (unsigned int)((float)mem_subcg_usage * swap_hard_limit_fraction);
+ return (unsigned long long)((double)mem_subcg_usage_bytes * swap_hard_limit_fraction);
}
static inline void swap_add_bundle(struct swap_thread_bundle *bundle)
return error;
}
-
static int swap_use_hard_limit(char *memcg)
{
int ret;
- unsigned int usage, memcg_limit;
+ unsigned long long usage_bytes, memcg_limit_bytes;
- ret = cgroup_read_node_uint32(memcg, MEMCG_USAGE, &usage);
+ ret = cgroup_read_node_ulonglong(memcg, MEMCG_USAGE, &usage_bytes);
if (ret != RESOURCED_ERROR_NONE)
- usage = 0;
+ usage_bytes = 0;
- memcg_limit = swap_calculate_hard_limit_in_bytes(usage);
- _D("Swap request: %s cgroup usage is %u, hard limit set to %u (hard limit fraction %f)",
- memcg, usage, memcg_limit, swap_hard_limit_fraction);
- if (memcg_limit != 0)
- ret = check_oom_and_set_limit(memcg, memcg_limit);
+ memcg_limit_bytes = swap_calculate_hard_limit_in_bytes(usage_bytes);
+ _D("[SWAP] Swap request: %s cgroup usage is %llu bytes, hard limit set to %llu bytes (hard limit fraction %f)",
+ memcg, usage_bytes, memcg_limit_bytes, swap_hard_limit_fraction);
+ if (memcg_limit_bytes != 0)
+ ret = check_oom_and_set_limit(memcg, memcg_limit_bytes);
else {
/* If the group is empty don't set the limit to enable adding processes. */
ret = cgroup_write_node_int32(memcg, MEMCG_SWAP_LIMIT_BYTE, -1);
static int swap_use_force_reclaim(char *memcg)
{
int ret, len;
+ unsigned long long usage_bytes;
int try = SWAP_FORCE_RECLAIM_NUM_MAX;
- unsigned int usage, nr_to_reclaim;
- unsigned int total_reclaim = 0;
+ unsigned int nr_to_reclaim;
+ unsigned int total_reclaim_pages = 0;
bool root_memcg = false;
/*
* anoynymous memory usage.
*/
if (root_memcg)
- ret = cgroup_read_node_uint32(memcg, MEMCG_USAGE, &usage);
+ ret = cgroup_read_node_ulonglong(memcg, MEMCG_USAGE, &usage_bytes);
else
- ret = memcg_get_anon_usage(memcg, &usage);
+ ret = memcg_get_anon_usage(memcg, &usage_bytes);
+
if (ret != RESOURCED_ERROR_NONE)
- usage = 0;
+ usage_bytes = 0;
- nr_to_reclaim = BYTE_TO_PAGE(usage);
+ nr_to_reclaim = BYTE_TO_PAGE(usage_bytes);
if (nr_to_reclaim <= SWAP_RECLAIM_PAGES_MIN)
break; /* don't reclaim if little gain */
if (nr_to_reclaim > SWAP_RECLAIM_PAGES_MAX)
nr_to_reclaim = SWAP_RECLAIM_PAGES_MAX;
- total_reclaim += nr_to_reclaim;
+ total_reclaim_pages += nr_to_reclaim;
ret = cgroup_write_node_uint32(memcg, MEMCG_FORCE_RECLAIM,
nr_to_reclaim);
if (ret != RESOURCED_ERROR_NONE)
try -= 1;
} while (try > 0);
- _D("FORCE_RECLAIM tried %u pages from %s", total_reclaim, memcg);
+ _D("[SWAP] FORCE_RECLAIM tried %u pages from %s", total_reclaim_pages, memcg);
return ret;
}
return fail ? fail : 0;
}
-//static int swap_reclaim_memcg(struct swap_status_msg msg)
static int swap_reclaim_memcg(char *path)
{
int r;
*/
if (!early_reclaim) {
int try = arg_swap_at_boot_maxtry;
- unsigned int usage, prev_usage = 0;
+ unsigned long long usage_bytes, prev_usage_bytes = 0;
- r = cgroup_read_node_uint32(MEMCG_PATH,
- MEMCG_SWAP_USAGE, &prev_usage);
+ r = cgroup_read_node_ulonglong(MEMCG_PATH,
+ MEMCG_SWAP_USAGE, &prev_usage_bytes);
if (r)
- prev_usage = UINT_MAX;
+ prev_usage_bytes = ULONG_MAX;
for (;;) {
try--;
swap_start_reclaim(MEMCG_PATH);
- r = cgroup_read_node_uint32(MEMCG_PATH,
- MEMCG_SWAP_USAGE, &usage);
+ r = cgroup_read_node_ulonglong(MEMCG_PATH,
+ MEMCG_SWAP_USAGE, &usage_bytes);
if (r) {
_E("Early reclaimed is aborted");
break;
* The default threshold is very large, so it may
* reclaim once.
*/
- if (!try || prev_usage - usage < arg_swap_at_boot_threshold)
+ if (!try || prev_usage_bytes - usage_bytes < arg_swap_at_boot_threshold_bytes)
break;
- prev_usage = usage;
+ prev_usage_bytes = usage_bytes;
/*
* To prevent continuous reclaim to harm entire system,
* having relaxation on each reclaim
*/
- sleep(arg_swap_at_boot_interval);
+ sleep(arg_swap_at_boot_interval_sec);
}
early_reclaim = true;
}
* partially to keep things simple but primarily because it can
* introduce an artificial delay since the timer is ran async
* in another thread. */
- if (arg_timer_swap_at_boot == 0) {
+ if (arg_timer_swap_at_boot_sec == 0) {
swap_activate_timer_cb(NULL);
return RESOURCED_ERROR_NONE;
}
- _D("booting done; starting up a timer to perform an " EARLYRECLAIM_WITH_AN_EXPLANATION_FOR_LAYMEN " %ds from now", arg_timer_swap_at_boot);
- swap_activating_timer = g_timeout_source_new_seconds((guint) arg_timer_swap_at_boot);
+ _D("booting done; starting up a timer to perform an " EARLYRECLAIM_WITH_AN_EXPLANATION_FOR_LAYMEN " %ds from now", arg_timer_swap_at_boot_sec);
+ swap_activating_timer = g_timeout_source_new_seconds((guint) arg_timer_swap_at_boot_sec);
g_source_set_callback(swap_activating_timer, swap_activate_timer_cb, NULL, NULL);
g_source_attach(swap_activating_timer, NULL);
if (swap_node == SWAP_NODE_FORCE_RECLAIM)
return RESOURCED_ERROR_NONE;
- ret = check_oom_and_set_limit(mi->name, mi->limit);
+ ret = check_oom_and_set_limit(mi->name, mi->limit_bytes);
if (ret != RESOURCED_ERROR_NONE)
_E("Failed to change hard limit of %s cgroup to -1", mi->name);
else
{
pid_t pid;
struct cgroup *cgroup_swap;
-// struct swap_status_msg ss_msg;
do_expr_unless_g_variant_get_typechecked(return, params, "(i)", &pid);
if (pid <= 0) {
if (!cgroup_swap)
return;
swap_move_to_cgroup_by_pid(CGROUP_LOW, pid);
-/* ss_msg.pid = pid;
- ss_msg.type = CGROUP_LOW;
- ss_msg.memcg_info = cgroup_swap->memcg_info;*/
swap_start_handler(cgroup_swap->memcg_info->name);
_I("swap cgroup entered : pid : %d", (int)pid);
}
static int resourced_swap_check_runtime_support(void *data)
{
int r;
- uint32_t usage;
+ unsigned long long usage_bytes;
/*
* Check whether CONFIG_SWAP is enabled in kernel.
/*
* Check whether kernel is supporting MEMCG_SWAP.
*/
- r = cgroup_read_node_uint32(MEMCG_PATH,
- MEMCG_SWAP_USAGE, &usage);
+ r = cgroup_read_node_ulonglong(MEMCG_PATH,
+ MEMCG_SWAP_USAGE, &usage_bytes);
if (r)
return -ENOENT;