lowmem-monitor: Modify PSI monitor to do one action per monitor 11/296711/1 accepted/tizen/unified/20230809.071852 accepted/tizen/unified/riscv/20230809.013259
authorSangYoun Kwak <sy.kwak@samsung.com>
Thu, 3 Aug 2023 08:24:44 +0000 (17:24 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Thu, 3 Aug 2023 08:24:44 +0000 (17:24 +0900)
Multiple events can be occured at one epoll_wait return.
In this case, lowmem_trigger_memory_state_action can be called multiple
times which is unnecessary.
With this patch, lowmem_trigger_memory_state_action will be called only
once per epoll_wait's return.

Change-Id: I6ef5cc7aeee4c9baa273517333c1cd2655752d58
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
src/resource-limiter/memory/lowmem-monitor-psi.c

index eec1440..a18fb6e 100644 (file)
@@ -68,6 +68,7 @@ struct epoll_event_data {
 static int g_psi_monitor_epoll_fd = -1;
 static pthread_t g_psi_monitor_thread;
 static int g_psi_monitor_thread_destroy_event_fd = -1;
+static enum psi_mem_level g_current_psi_mem_level = PSI_MEM_LEVEL_UNKNOWN;
 
 static void assert_psi_mem_level(int psi_mem_level)
 {
@@ -84,19 +85,10 @@ static void assert_psi_mem_level(int psi_mem_level)
 
 static void *psi_memory_monitor_handler(struct psi_memory_monitor_info *info)
 {
-       static unsigned int prev_available_mb;
-       unsigned int available_mb;
-       int mem_level;
-
        assert_psi_mem_level(info->psi_mem_level);
 
-       available_mb = proc_get_mem_available();
-       if (prev_available_mb == available_mb)
-               return NULL;
-
-       mem_level = lowmem_check_mem_state(available_mb);
-       lowmem_trigger_memory_state_action(mem_level);
-       prev_available_mb = available_mb;
+       if (g_current_psi_mem_level < info->psi_mem_level)
+               g_current_psi_mem_level = info->psi_mem_level;
 
        return NULL;
 }
@@ -203,6 +195,30 @@ static void unregister_psi_event_epoll(struct epoll_event_data *event_data)
        info->fd = -1;
 }
 
+static void raise_lowmem_event(void)
+{
+       static unsigned int prev_available_mb;
+       unsigned int available_mb;
+       int mem_level;
+
+       switch (g_current_psi_mem_level) {
+       case PSI_MEM_LEVEL_LOW:
+       case PSI_MEM_LEVEL_MEDIUM:
+       case PSI_MEM_LEVEL_HIGH:
+               break;
+       default:
+               return;
+       }
+
+       available_mb = proc_get_mem_available();
+       if (prev_available_mb == available_mb)
+               return;
+
+       mem_level = lowmem_check_mem_state(available_mb);
+       lowmem_trigger_memory_state_action(mem_level);
+       prev_available_mb = available_mb;
+}
+
 static void *psi_monitor_thread_worker(void *data)
 {
        struct epoll_event events[EPOLL_LISTENER_MAX_EVENTS];
@@ -211,6 +227,7 @@ static void *psi_monitor_thread_worker(void *data)
        while (1) {
                events_num = epoll_wait(g_psi_monitor_epoll_fd, events, EPOLL_LISTENER_MAX_EVENTS, -1);
 
+               g_current_psi_mem_level = PSI_MEM_LEVEL_UNKNOWN;
                for (int i = 0; i < events_num; ++i) {
                        if (events[i].events & (EPOLLERR | EPOLLHUP))
                                continue;
@@ -218,6 +235,8 @@ static void *psi_monitor_thread_worker(void *data)
                        struct epoll_event_data *event_data = events[i].data.ptr;
                        event_data->handler(event_data->data);
                }
+
+               raise_lowmem_event();
        }
 
        pthread_exit(NULL);