rtla: Automatically move rtla to a house-keeping cpu
authorDaniel Bristot de Oliveira <bristot@kernel.org>
Tue, 6 Jun 2023 16:12:18 +0000 (18:12 +0200)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Tue, 13 Jun 2023 20:30:13 +0000 (16:30 -0400)
When the user sets -c <cpu-list> try to move rtla out of the <cpu-list>,
even without an -H option. This is useful to avoid having rtla
interfering with the workload.

This works by removing <cpu-list> from rtla's current affinity.

If rtla fails to move itself away it is not that of a problem as this
is an automatic measure.

Link: https://lkml.kernel.org/r/c54304d90c777310fb85a3e658d1449173759aab.1686066600.git.bristot@kernel.org
Cc: William White <chwhite@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Tested-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
tools/tracing/rtla/src/osnoise_hist.c
tools/tracing/rtla/src/osnoise_top.c
tools/tracing/rtla/src/timerlat_hist.c
tools/tracing/rtla/src/timerlat_top.c
tools/tracing/rtla/src/utils.c
tools/tracing/rtla/src/utils.h

index b616a72..dfbcb5c 100644 (file)
@@ -753,6 +753,15 @@ osnoise_hist_apply_config(struct osnoise_tool *tool, struct osnoise_hist_params
                        err_msg("Failed to set rtla to the house keeping CPUs\n");
                        goto out_err;
                }
+       } else if (params->cpus) {
+               /*
+                * Even if the user do not set a house-keeping CPU, try to
+                * move rtla to a CPU set different to the one where the user
+                * set the workload to run.
+                *
+                * No need to check results as this is an automatic attempt.
+                */
+               auto_house_keeping(&params->monitored_cpus);
        }
 
        return 0;
index 0e2f3b2..0833537 100644 (file)
@@ -582,6 +582,15 @@ osnoise_top_apply_config(struct osnoise_tool *tool, struct osnoise_top_params *p
                        err_msg("Failed to set rtla to the house keeping CPUs\n");
                        goto out_err;
                }
+       } else if (params->cpus) {
+               /*
+                * Even if the user do not set a house-keeping CPU, try to
+                * move rtla to a CPU set different to the one where the user
+                * set the workload to run.
+                *
+                * No need to check results as this is an automatic attempt.
+                */
+               auto_house_keeping(&params->monitored_cpus);
        }
 
        return 0;
index 00287e9..1675d54 100644 (file)
@@ -776,6 +776,15 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param
                        err_msg("Failed to set rtla to the house keeping CPUs\n");
                        goto out_err;
                }
+       } else if (params->cpus) {
+               /*
+                * Even if the user do not set a house-keeping CPU, try to
+                * move rtla to a CPU set different to the one where the user
+                * set the workload to run.
+                *
+                * No need to check results as this is an automatic attempt.
+                */
+               auto_house_keeping(&params->monitored_cpus);
        }
 
        return 0;
index 920f2f6..f0c6d97 100644 (file)
@@ -619,6 +619,15 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params *
                        err_msg("Failed to set rtla to the house keeping CPUs\n");
                        goto out_err;
                }
+       } else if (params->cpus) {
+               /*
+                * Even if the user do not set a house-keeping CPU, try to
+                * move rtla to a CPU set different to the one where the user
+                * set the workload to run.
+                *
+                * No need to check results as this is an automatic attempt.
+                */
+               auto_house_keeping(&params->monitored_cpus);
        }
 
        return 0;
index 8f9ad8f..3e25f02 100644 (file)
@@ -709,3 +709,53 @@ out_cg:
        close(cg_fd);
        return 0;
 }
+
+/**
+ * auto_house_keeping - Automatically move rtla out of measurement threads
+ *
+ * Try to move rtla away from the tracer, if possible.
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+int auto_house_keeping(cpu_set_t *monitored_cpus)
+{
+       cpu_set_t rtla_cpus, house_keeping_cpus;
+       int retval;
+
+       /* first get the CPUs in which rtla can actually run. */
+       retval = sched_getaffinity(getpid(), sizeof(rtla_cpus), &rtla_cpus);
+       if (retval == -1) {
+               debug_msg("Could not get rtla affinity, rtla might run with the threads!\n");
+               return 0;
+       }
+
+       /* then check if the existing setup is already good. */
+       CPU_AND(&house_keeping_cpus, &rtla_cpus, monitored_cpus);
+       if (!CPU_COUNT(&house_keeping_cpus)) {
+               debug_msg("rtla and the monitored CPUs do not share CPUs.");
+               debug_msg("Skipping auto house-keeping\n");
+               return 1;
+       }
+
+       /* remove the intersection */
+       CPU_XOR(&house_keeping_cpus, &rtla_cpus, monitored_cpus);
+
+       /* get only those that rtla can run */
+       CPU_AND(&house_keeping_cpus, &house_keeping_cpus, &rtla_cpus);
+
+       /* is there any cpu left? */
+       if (!CPU_COUNT(&house_keeping_cpus)) {
+               debug_msg("Could not find any CPU for auto house-keeping\n");
+               return 0;
+       }
+
+       retval = sched_setaffinity(getpid(), sizeof(house_keeping_cpus), &house_keeping_cpus);
+       if (retval == -1) {
+               debug_msg("Could not set affinity for auto house-keeping\n");
+               return 0;
+       }
+
+       debug_msg("rtla automatically moved to an auto house-keeping cpu set\n");
+
+       return 1;
+}
index 9ab2f0d..dec5916 100644 (file)
@@ -60,6 +60,7 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set);
 int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
 int set_comm_cgroup(const char *comm_prefix, const char *cgroup);
 int set_cpu_dma_latency(int32_t latency);
+int auto_house_keeping(cpu_set_t *monitored_cpus);
 
 #define ns_to_usf(x) (((double)x/1000))
 #define ns_to_per(total, part) ((part * 100) / (double)total)