]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: allow cpu-map to take commas in lists of ranges
authorWilly Tarreau <w@1wt.eu>
Fri, 5 May 2023 14:10:05 +0000 (16:10 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 5 May 2023 16:41:52 +0000 (18:41 +0200)
The function that cpu-map uses to parse CPU sets, parse_cpu_set(), was
etended in 2.4 with commit a80823543 ("MINOR: cfgparse: support the
comma separator on parse_cpu_set") to support commas between ranges.
But since it was quite late in the development cycle, by then it was
decided not to add a last-minute surprise and not to magically support
commas in cpu-map, hence the "comma_allowed" argument.

Since then we know that it was not the best choice, because the comma
is silently ignored in the cpu-map syntax, causing all sorts of
surprises in field with threads running on a single node for example.
In addition it's quite common to copy-paste a taskset line and put it
directly into the haproxy configuration.

This commit relaxes this rule an finally allows cpu-map to support
commas between ranges. It simply consists in removing the comma_allowed
argument in the parse_cpu_set() function. The doc was updated to
reflect this.

doc/configuration.txt
include/haproxy/cfgparse.h
src/cfgparse-global.c
src/cfgparse.c

index 7926b72efac6acfc7e1eceb881e7e612cb9763fe..1998dab6c995e2f97b10df2d25826f8466cc9cf4 100644 (file)
@@ -1332,7 +1332,7 @@ cluster-secret <secret>
   startup. This allows to use features which rely on it, albeit with some
   limitations.
 
-cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>...
+cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>[,...] [...]
   On some operating systems, it is possible to bind a thread group or a thread
   to a specific CPU set. This means that the designated threads will never run
   on other CPUs. The "cpu-map" directive specifies CPU sets for individual
@@ -1349,12 +1349,12 @@ cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>...
   using "all", only odd numbers using "odd" or even numbers using "even", just
   like with the "thread" bind directive. The second and forthcoming arguments
   are CPU sets. Each CPU set is either a unique number starting at 0 for the
-  first CPU or a range with two such numbers delimited by a dash ('-'). Outside
-  of Linux and BSDs, there may be a limitation on the maximum CPU index to
-  either 31 or 63. Multiple CPU numbers or ranges may be specified, and the
-  processes or threads will be allowed to bind to all of them. Obviously,
-  multiple "cpu-map" directives may be specified. Each "cpu-map" directive will
-  replace the previous ones when they overlap.
+  first CPU or a range with two such numbers delimited by a dash ('-'). These
+  CPU numbers and ranges may be repeated by delimiting them with commas or by
+  passing more ranges as new arguments on the same line. Outside of Linux and
+  BSD operating systems, there may be a limitation on the maximum CPU index to
+  either 31 or 63. Multiple "cpu-map" directives may be specified, but each
+  "cpu-map" directive will replace the previous ones when they overlap.
 
   Ranges can be partially defined. The higher bound can be omitted. In such
   case, it is replaced by the corresponding maximum value, 32 or 64 depending
@@ -1387,6 +1387,7 @@ cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>...
       cpu-map auto:1/1-4   0-3
       cpu-map auto:1/1-4   0-1 2-3
       cpu-map auto:1/1-4   3 2 1 0
+      cpu-map auto:1/1-4   3,2,1,0
 
       # bind each thread to exactly one CPU using all/odd/even keyword
       cpu-map auto:1/all   0-63
@@ -1406,10 +1407,10 @@ cpu-map [auto:]<thread-group>[/<thread-set>] <cpu-set>...
       # Map 80 threads to one physical socket and 80 others to another socket
       # without forcing assignment. These are split into 4 groups since no
       # group may have more than 64 threads.
-      cpu-map 1/1-40   0-39 80-119    # node0, siblings 0 & 1
-      cpu-map 2/1-40   0-39 80-119
-      cpu-map 3/1-40   40-79 120-159  # node1, siblings 0 & 1
-      cpu-map 4/1-40   40-79 120-159
+      cpu-map 1/1-40   0-39,80-119    # node0, siblings 0 & 1
+      cpu-map 2/1-40   0-39,80-119
+      cpu-map 3/1-40   40-79,120-159  # node1, siblings 0 & 1
+      cpu-map 4/1-40   40-79,120-159
 
 
 crt-base <dir>
index 29937ff9bd0524e62134d38d0104cc827c881ddb..7bd4725f9e81e4d16e8d8e2ae154d6e2e254f8a2 100644 (file)
@@ -124,7 +124,7 @@ int too_many_args(int maxarg, char **args, char **msg, int *err_code);
 int alertif_too_many_args_idx(int maxarg, int index, const char *file, int linenum, char **args, int *err_code);
 int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args, int *err_code);
 int parse_process_number(const char *arg, unsigned long *proc, int max, int *autoinc, char **err);
-unsigned long parse_cpu_set(const char **args, struct hap_cpuset *cpu_set, int comma_allowed, char **err);
+unsigned long parse_cpu_set(const char **args, struct hap_cpuset *cpu_set, char **err);
 void free_email_alert(struct proxy *p);
 const char *cfg_find_best_match(const char *word, const struct list *list, int section, const char **extra);
 int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint);
index 76d1769043c935d23c1260b99bc90b4f400a0ab3..cc643f46ea03f0be030c442c13608334e59c37fa 100644 (file)
@@ -1102,7 +1102,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
                        *slash = '/';
                }
 
-               if (parse_cpu_set((const char **)args+2, &cpus, 0, &errmsg)) {
+               if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
                        ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
index 8e6295db192ac7538e60a13d20d825c17b46d282..328836af5d72b66feab6766465daaf0031ba3815 100644 (file)
@@ -516,13 +516,12 @@ int parse_process_number(const char *arg, unsigned long *proc, int max, int *aut
 #ifdef USE_CPU_AFFINITY
 /* Parse cpu sets. Each CPU set is either a unique number between 0 and
  * ha_cpuset_size() - 1 or a range with two such numbers delimited by a dash
- * ('-'). If <comma_allowed> is set, each CPU set can be a list of unique
- * numbers or ranges separated by a comma. It is also possible to specify
- * multiple cpu numbers or ranges in distinct argument in <args>. On success,
- * it returns 0, otherwise it returns 1 with an error message in <err>.
+ * ('-'). Each CPU set can be a list of unique numbers or ranges separated by
+ * a comma. It is also possible to specify multiple cpu numbers or ranges in
+ * distinct argument in <args>. On success, it returns 0, otherwise it returns
+ * 1 with an error message in <err>.
  */
-unsigned long parse_cpu_set(const char **args, struct hap_cpuset *cpu_set,
-                            int comma_allowed, char **err)
+unsigned long parse_cpu_set(const char **args, struct hap_cpuset *cpu_set, char **err)
 {
        int cur_arg = 0;
        const char *arg;
@@ -541,7 +540,7 @@ unsigned long parse_cpu_set(const char **args, struct hap_cpuset *cpu_set,
 
                low = high = str2uic(arg);
 
-               comma = comma_allowed ? strchr(arg, ',') : NULL;
+               comma = strchr(arg, ',');
                dash = strchr(arg, '-');
 
                if (dash && (!comma || dash < comma))
@@ -2637,7 +2636,7 @@ static int numa_detect_topology()
 
        parse_cpu_set_args[0] = trash.area;
        parse_cpu_set_args[1] = "\0";
-       if (parse_cpu_set(parse_cpu_set_args, &active_cpus, 1, &err)) {
+       if (parse_cpu_set(parse_cpu_set_args, &active_cpus, &err)) {
                ha_notice("Cannot read online CPUs list: '%s'. Will not try to refine binding\n", err);
                free(err);
                goto free_scandir_entries;