etmem/0014-stat-pages-info-early-only-replace-cold-mem-in-hot-nodes.patch
YangXin ce6533c4bd Update etmem.
Signed-off-by: YangXin <245051644@qq.com>
2021-09-30 22:57:41 +08:00

301 lines
10 KiB
Diff

From 2a63484709098a551cbf6996c5362f25f6539ca5 Mon Sep 17 00:00:00 2001
From: Kemeng Shi <shikemeng@huawei.com>
Date: Thu, 29 Apr 2021 11:32:07 +0800
Subject: [PATCH 14/50] stat pages info early only replace cold mem in hot node
in order to reduce pages to move
Signed-off-by: Kemeng Shi <shikemeng@huawei.com>
---
src/etmemd_src/etmemd_cslide.c | 134 ++++++++++++++++++++-------------
1 file changed, 81 insertions(+), 53 deletions(-)
diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c
index 43d8108..7c30508 100644
--- a/src/etmemd_src/etmemd_cslide.c
+++ b/src/etmemd_src/etmemd_cslide.c
@@ -36,6 +36,7 @@
#define HUGE_1G_SIZE (1 << 30)
#define BYTE_TO_KB(s) ((s) >> 10)
#define KB_TO_BYTE(s) ((s) << 10)
+#define HUGE_2M_TO_KB(s) ((s) << 11)
#define TO_PCT 100
#define MAX_WM 100
@@ -154,6 +155,7 @@ struct cslide_eng_params {
int sleep;
};
struct cslide_params_factory factory;
+ struct node_pages_info *host_pages_info;
bool finish;
};
@@ -166,12 +168,13 @@ struct node_ctrl {
struct ctrl_cap hot_move_cap;
struct ctrl_cap hot_prefetch_cap;
struct ctrl_cap cold_move_cap;
- long long cold_replaced;
- long long cold_free;
- long long free;
- long long total;
- long long quota;
- long long reserve;
+ long long cold_replaced; // cold mem in hot node replace by hot mem in cold node
+ long long cold_free; // free mem in cold node
+ long long free; // free mem in hot node
+ long long cold; // cold mem in hot node
+ long long total; // total mem in hot node
+ long long quota; // move quota
+ long long reserve; // reserve space can't used by cold mem
};
struct flow_ctrl {
@@ -854,17 +857,21 @@ static bool node_cal_hot_can_move(struct node_ctrl *node_ctrl)
{
long long can_move;
+ // can_move limited by quota
if (node_ctrl->quota < node_ctrl->free) {
can_move = node_ctrl->quota;
} else {
+ // can_move limited by hot node free
can_move = node_ctrl->free + (node_ctrl->quota - node_ctrl->free) / 2;
+ // can_move limited by cold node free
if (can_move > node_ctrl->free + node_ctrl->cold_free) {
can_move = node_ctrl->free + node_ctrl->cold_free;
}
}
- if (can_move > node_ctrl->total) {
- can_move = node_ctrl->total;
+ // can_move limited by free and cold mem in hot node
+ if (can_move > node_ctrl->cold + node_ctrl->free) {
+ can_move = node_ctrl->cold + node_ctrl->free;
}
node_ctrl->hot_move_cap.cap = can_move;
return can_move > 0;
@@ -963,9 +970,13 @@ static inline bool node_move_cold(struct node_ctrl *node_ctrl, long long *target
return cap_cost(&node_ctrl->cold_move_cap, target);
}
-static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struct node_map *node_map,
- long long quota, long long reserve)
+static int init_flow_ctrl(struct flow_ctrl *ctrl, struct cslide_eng_params *eng_params)
{
+
+ long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE;
+ long long reserve = (long long)eng_params->hot_reserve * HUGE_1M_SIZE;
+ struct sys_mem *sys_mem = &eng_params->mem;
+ struct node_map *node_map = &eng_params->node_map;
struct node_pair *pair = NULL;
struct node_ctrl *tmp = NULL;
int i;
@@ -985,6 +996,7 @@ static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struc
tmp = &ctrl->node_ctrl[i];
tmp->cold_free = sys_mem->node_mem[pair->cold_node].huge_free;
tmp->free = sys_mem->node_mem[pair->hot_node].huge_free;
+ tmp->cold = KB_TO_BYTE((unsigned long long)eng_params->host_pages_info[pair->hot_node].cold);
tmp->total = sys_mem->node_mem[pair->hot_node].huge_total;
tmp->quota = quota;
tmp->reserve = reserve;
@@ -1187,10 +1199,8 @@ static void move_cold_pages(struct cslide_eng_params *eng_params, struct flow_ct
static int cslide_filter_pfs(struct cslide_eng_params *eng_params)
{
struct flow_ctrl ctrl;
- long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE;
- long long reserve = (long long)eng_params->hot_reserve * HUGE_1M_SIZE;
- if (init_flow_ctrl(&ctrl, &eng_params->mem, &eng_params->node_map, quota, reserve) != 0) {
+ if (init_flow_ctrl(&ctrl, eng_params) != 0) {
etmemd_log(ETMEMD_LOG_ERR, "init_flow_ctrl fail\n");
return -1;
}
@@ -1203,22 +1213,6 @@ static int cslide_filter_pfs(struct cslide_eng_params *eng_params)
return 0;
}
-static int cslide_policy(struct cslide_eng_params *eng_params)
-{
- struct cslide_pid_params *pid_params = NULL;
- int ret;
-
- factory_foreach_working_pid_params(pid_params, &eng_params->factory) {
- ret = cslide_count_node_pfs(pid_params);
- if (ret != 0) {
- etmemd_log(ETMEMD_LOG_ERR, "count node page refs fail\n");
- return ret;
- }
- }
-
- return cslide_filter_pfs(eng_params);
-}
-
static int cslide_get_vmas(struct cslide_pid_params *pid_params)
{
struct cslide_task_params *task_params = pid_params->task_params;
@@ -1510,26 +1504,41 @@ static bool need_migrate(struct cslide_eng_params *eng_params)
return false;
}
-static void get_node_pages_info(struct cslide_pid_params *pid_params)
+static void init_host_pages_info(struct cslide_eng_params *eng_params)
+{
+ int n;
+ int node_num = eng_params->mem.node_num;
+ struct node_pages_info *host_pages = eng_params->host_pages_info;
+
+ for (n = 0; n < node_num; n++) {
+ host_pages[n].cold = 0;
+ host_pages[n].hot = 0;
+ }
+}
+
+static void update_pages_info(struct cslide_eng_params *eng_params, struct cslide_pid_params *pid_params)
{
- struct cslide_eng_params *eng_params = pid_params->eng_params;
int n, c;
int t = eng_params->hot_threshold;
int count = pid_params->count;
int actual_t = t > count ? count + 1 : t;
int node_num = pid_params->count_page_refs->node_num;
- struct node_pages_info *info = pid_params->node_pages_info;
+ struct node_pages_info *task_pages = pid_params->node_pages_info;
+ struct node_pages_info *host_pages = eng_params->host_pages_info;
for (n = 0; n < node_num; n++) {
- info[n].cold = 0;
- info[n].hot = 0;
+ task_pages[n].cold = 0;
+ task_pages[n].hot = 0;
for (c = 0; c < actual_t; c++) {
- info[n].cold += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024;
+ task_pages[n].cold += HUGE_2M_TO_KB(pid_params->count_page_refs[c].node_pfs[n].num);
}
for (; c <= count; c++) {
- info[n].hot += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024;
+ task_pages[n].hot += HUGE_2M_TO_KB(pid_params->count_page_refs[c].node_pfs[n].num);
}
+
+ host_pages[n].cold += task_pages[n].cold;
+ host_pages[n].hot += task_pages[n].hot;
}
}
@@ -1538,13 +1547,33 @@ static void cslide_stat(struct cslide_eng_params *eng_params)
struct cslide_pid_params *iter = NULL;
pthread_mutex_lock(&eng_params->stat_mtx);
+ init_host_pages_info(eng_params);
factory_foreach_working_pid_params(iter, &eng_params->factory) {
- get_node_pages_info(iter);
+ update_pages_info(eng_params, iter);
}
eng_params->stat_time = time(NULL);
pthread_mutex_unlock(&eng_params->stat_mtx);
}
+static int cslide_policy(struct cslide_eng_params *eng_params)
+{
+ struct cslide_pid_params *pid_params = NULL;
+ int ret;
+
+ factory_foreach_working_pid_params(pid_params, &eng_params->factory) {
+ ret = cslide_count_node_pfs(pid_params);
+ if (ret != 0) {
+ etmemd_log(ETMEMD_LOG_ERR, "count node page refs fail\n");
+ return ret;
+ }
+ }
+
+ // update pages info now, so cslide_filter_pfs can use this info
+ cslide_stat(eng_params);
+
+ return cslide_filter_pfs(eng_params);
+}
+
static void cslide_clean_params(struct cslide_eng_params *eng_params)
{
struct cslide_pid_params *iter = NULL;
@@ -1559,6 +1588,8 @@ static void cslide_clean_params(struct cslide_eng_params *eng_params)
static void destroy_cslide_eng_params(struct cslide_eng_params *params)
{
+ free(params->host_pages_info);
+ params->host_pages_info = NULL;
destroy_factory(&params->factory);
pthread_mutex_destroy(&params->stat_mtx);
destroy_node_map(&params->node_map);
@@ -1567,6 +1598,8 @@ static void destroy_cslide_eng_params(struct cslide_eng_params *params)
static int init_cslide_eng_params(struct cslide_eng_params *params)
{
+ int node_num;
+
if (init_sys_mem(&params->mem) != 0) {
etmemd_log(ETMEMD_LOG_ERR, "init system memory fail\n");
return -1;
@@ -1587,8 +1620,18 @@ static int init_cslide_eng_params(struct cslide_eng_params *params)
goto destroy_stat_mtx;
}
+ node_num = params->mem.node_num;
+ params->host_pages_info = calloc(node_num, sizeof(struct node_pages_info));
+ if (params->host_pages_info == NULL) {
+ etmemd_log(ETMEMD_LOG_ERR, "alloc host_pages_info fail\n");
+ goto destroy_factory;
+ }
+
return 0;
+destroy_factory:
+ destroy_factory(&params->factory);
+
destroy_stat_mtx:
pthread_mutex_destroy(&params->stat_mtx);
@@ -1642,7 +1685,6 @@ static void *cslide_main(void *arg)
}
next:
- cslide_stat(eng_params);
sleep(eng_params->interval);
cslide_clean_params(eng_params);
}
@@ -1745,24 +1787,11 @@ static struct cslide_cmd_item g_task_cmd_items[] = {
static int show_host_pages(void *params, int fd)
{
struct cslide_eng_params *eng_params = (struct cslide_eng_params *)params;
- struct cslide_pid_params *iter = NULL;
char *time_str = NULL;
int node_num = eng_params->mem.node_num;
int n;
uint32_t total;
- struct node_pages_info *info = calloc(node_num, sizeof(struct node_pages_info));
-
- if (info == NULL) {
- etmemd_log(ETMEMD_LOG_ERR, "alloc memory for node_page_info fail\n");
- return -1;
- }
-
- factory_foreach_working_pid_params(iter, &eng_params->factory) {
- for (n = 0; n < node_num; n++) {
- info[n].hot += iter->node_pages_info[n].hot;
- info[n].cold += iter->node_pages_info[n].cold;
- }
- }
+ struct node_pages_info *info = eng_params->host_pages_info;
time_str = get_time_stamp(&eng_params->stat_time);
if (time_str != NULL) {
@@ -1776,7 +1805,6 @@ static int show_host_pages(void *params, int fd)
n, total, info[n].hot + info[n].cold, info[n].hot, info[n].cold);
}
- free(info);
return 0;
}
--
2.27.0