cpu-boosting: Support CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag 97/319297/2
authorUnsung Lee <unsung.lee@samsung.com>
Mon, 3 Feb 2025 11:59:34 +0000 (20:59 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Mon, 10 Feb 2025 03:07:34 +0000 (12:07 +0900)
Save CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on CPU boosting set command.
Also, check CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag on CPU boosting clcear command
to decide whether to perform a CPU boosting reset.
Previously, CPU_BOOSTING_LEVEL_NONE cannot entered as an argument for the CPU boosting set command.
However, it modifies so that CPU_BOOSTING_LEVEL_NONE is acceptable to support CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag.

Change-Id: I5bf101961b644d3ac70096dad71e4997ec064e70
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
src/resource-optimizer/cpu/cpu-boosting.c

index 06dae68c97565563358fa9396ecd3cb573ad3d8c..feca06de39b850ca337cfe6c37e5ddd41d73c866 100644 (file)
@@ -898,8 +898,8 @@ static bool is_valid_cpu_boosting_level(cpu_boosting_level_e cpu_boosting_level)
        case CPU_BOOSTING_LEVEL_STRONG:
        case CPU_BOOSTING_LEVEL_MEDIUM:
        case CPU_BOOSTING_LEVEL_WEAK:
-               return true;
        case CPU_BOOSTING_LEVEL_NONE:
+               return true;
        default:
                return false;
        }
@@ -976,12 +976,39 @@ static void cpu_boosting_find_and_insert_info(pid_t tid,
        uint32_t cpu_boosting_info_set_flag = 0;
 
        if (!is_valid_cpu_boosting_level(cpu_boosting_level)) {
-               _E("[CPU-BOOSTING] Cannot boosting unknown or none level");
+               _E("[CPU-BOOSTING] Unknown boosting level");
                return;
        }
 
        find_cpu_boosting_info_in_tables(&cpu_boosting_info, &tid);
 
+       switch (cpu_boosting_level) {
+       case CPU_BOOSTING_LEVEL_NONE:
+               if (cpu_boosting_info == NULL)
+                       return;
+
+               if ((cpu_boosting_flags & CPU_BOOSTING_FORCE_RESET_ON_CLEAR) == 0)
+                       return;
+
+               /**
+                * Set only CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag
+                * when CPU boosting level is CPU_BOOSTING_LEVEL_NONE.
+                * This is because, except for the flag, no other information is correct.
+                */
+               cpu_boosting_info_set_flag = CPU_BOOSTING_INFO_SET_CPU_BOOSTING_FLAGS;
+               set_cpu_boosting_info(cpu_boosting_info_set_flag, cpu_boosting_info,
+                               0, 0, cpu_boosting_info->cpu_boosting_flags | CPU_BOOSTING_FORCE_RESET_ON_CLEAR,
+                               NULL, CPU_BOOSTING_LEVEL_NONE);
+               return;
+       case CPU_BOOSTING_LEVEL_STRONG:
+       case CPU_BOOSTING_LEVEL_MEDIUM:
+       case CPU_BOOSTING_LEVEL_WEAK:
+               break;
+       default:
+               _E("Invalid CPU boosting level");
+               return;
+       }
+
        cpu_boosting_info_set_flag =
                CPU_BOOSTING_INFO_SET_TID | CPU_BOOSTING_INFO_SET_REF_CNT |
                CPU_BOOSTING_INFO_SET_CPU_BOOSTING_FLAGS | CPU_BOOSTING_INFO_SET_GSOURCE_ID |
@@ -1076,15 +1103,37 @@ cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
        int timeout_msec = input->client_input.timeout_msec;
        cpu_boosting_level_e cpu_boosting_level = input->client_input.level;
        cpu_boosting_flag_e cpu_boosting_flags = input->client_input.flags;
+       bool update_cpu_boosting_info = false;
 
        if (!is_valid_cpu_boosting_level(cpu_boosting_level)) {
                _E("[CPU-BOOSTING] Unknown boosting level");
                return;
        }
 
-       update_cpu_sched_of_thread_list(tid_count, tid_list,
-                       cpu_boosting_flags, cpu_boosting_level,
-                       &fail_cnt, &success_cnt);
+       /**
+        * CPU sched of thread is updated when CPU boosting level is
+        * CPU_BOOSTING_LEVEL_STRONG or CPU_BOOSTING_LEVEL_MEDIUM or CPU_BOOSTING_LEVEL_WEAK.
+        * On the other hand, CPU sched of thread should not be updated
+        * when CPU boosting level is CPU_BOOSTING_LEVEL_NONE.
+        * In addition, syscommon_resourced_cpu_boosting_info structure can be updated regardless of CPU boosting level.
+        */
+       switch (cpu_boosting_level) {
+       case CPU_BOOSTING_LEVEL_NONE:
+               update_cpu_boosting_info = true;
+               break;
+       case CPU_BOOSTING_LEVEL_STRONG:
+       case CPU_BOOSTING_LEVEL_MEDIUM:
+       case CPU_BOOSTING_LEVEL_WEAK:
+               update_cpu_sched_of_thread_list(tid_count, tid_list,
+                               cpu_boosting_flags, cpu_boosting_level,
+                               &fail_cnt, &success_cnt);
+               if (success_cnt > 0)
+                       update_cpu_boosting_info = true;
+               break;
+       default:
+               _E("Invalid CPU boosting level");
+               return;
+       }
 
        if (fail_cnt > 0)
                _W("[CPU-BOOSTING] Boosting success ratio = %d/%d", success_cnt, fail_cnt + success_cnt);
@@ -1110,7 +1159,9 @@ cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
 
                        id = *(input->gsource_id);
                }
+       }
 
+       if (update_cpu_boosting_info) {
                for (int i = 0; i < tid_count; i++) {
                        if (tid_list[i] <= 0)
                                continue;
@@ -1124,6 +1175,27 @@ cpu_boosting_set(struct syscommon_resourced_cpu_boosting_input *input)
                cpu_boosting_destroy_request(input);
 }
 
+static bool should_reset_cpu_boosting(int *tid)
+{
+       struct syscommon_resourced_cpu_boosting_info *cpu_boosting_info = NULL;
+
+       find_cpu_boosting_info_in_tables(&cpu_boosting_info, tid);
+       if (cpu_boosting_info == NULL)
+               return false;
+
+       if (cpu_boosting_info->cpu_boosting_flags & CPU_BOOSTING_FORCE_RESET_ON_CLEAR)
+               return true;
+
+       /**
+        * TODO: check count when the CPU_BOOSTING_FORCE_RESET_ON_CLEAR is disabled.
+        *
+        * Currently CPU_BOOSTING_COMMAND_CLEAR resets CPU boosting forcely
+        * regardless of CPU_BOOSTING_FORCE_RESET_ON_CLEAR flag.
+        * It may cause unintended early termination of CPU boosting.
+        */
+       return true;
+}
+
 static void cpu_boosting_clear(struct syscommon_resourced_cpu_boosting_input *input)
 {
        int ret;
@@ -1139,6 +1211,9 @@ static void cpu_boosting_clear(struct syscommon_resourced_cpu_boosting_input *in
                        continue;
                }
 
+               if (!should_reset_cpu_boosting(&tid_list[i]))
+                       continue;
+
                remove_cpu_boosting_info_in_tables(&tid_list[i]);
 
                ret = sched_setattr(tid_list[i],