Browse Source

exclude-cpus and use-cpus options can co-exist

Serj Kalichev 2 years ago
parent
commit
8d2ad21b4d
3 changed files with 19 additions and 18 deletions
  1. 16 15
      birq.c
  2. 2 2
      doc/birq.md
  3. 1 1
      examples/birq.conf

+ 16 - 15
birq.c

@@ -566,7 +566,7 @@ static int parse_config(const char *fname, struct options *opts)
 	int ret = -1; /* Pessimistic retval */
 	lub_ini_t *ini;
 	const char *tmp = NULL;
-	unsigned int mask_opts_num = 0;
+	cpumask_t use_cpus;
 
 	ini = lub_ini_new();
 	if (lub_ini_parse_file(ini, fname)) {
@@ -599,28 +599,29 @@ static int parse_config(const char *fname, struct options *opts)
 			fprintf(stderr, "Error: Can't parse exclude-cpus option \"%s\".\n", tmp);
 			goto err;
 		}
-		mask_opts_num++;
 	}
 
+	cpus_init(use_cpus);
 	if ((tmp = lub_ini_find(ini, "use-cpus"))) {
-		if (cpumask_parse_user(tmp, strlen(tmp), opts->exclude_cpus)) {
+		if (cpumask_parse_user(tmp, strlen(tmp), use_cpus)) {
 			fprintf(stderr, "Error: Can't parse use-cpus option \"%s\".\n", tmp);
 			goto err;
 		}
-		/* The exclude-cpus option was implemented first. So the
-		 * programm is based on it. The use-cpus options really
-		 * says to exclude all the cpus that is not within bitmask.
-		 * So invert use-cpus and we'll get exclude-cpus mask.
-		 */
-		cpus_complement(opts->exclude_cpus, opts->exclude_cpus);
-		mask_opts_num++;
+	} else {
+		cpus_setall(use_cpus);
 	}
 
-	/* Check if cpus mask was defined more than once. It's error. */
-	if (mask_opts_num > 1) {
-		fprintf(stderr, "Error: Can't use use-cpus and exclude-cpus options together.\n");
-		goto err;
-	}
+	/* The exclude-cpus option was implemented first. So the
+	 * programm is based on it. The use-cpus options really
+	 * says to exclude all the cpus that is not within bitmask.
+	 * So invert use-cpus and we'll get exclude-cpus mask.
+	 */
+	cpus_complement(use_cpus, use_cpus);
+	/* Calculate real exclude-cpu mask (consider use-cpus option).
+	 * real-exclude-cpus = exclude-cpus | ~use-cpus
+	 */
+	cpus_or(opts->exclude_cpus, opts->exclude_cpus, use_cpus);
+	cpus_free(use_cpus);
 
 	if ((tmp = lub_ini_find(ini, "ht")))
 		if (opt_parse_y_n(tmp, &opts->ht))

+ 2 - 2
doc/birq.md

@@ -129,8 +129,8 @@ Options:
 * **short-interval=<sec>** - Short iteration interval in seconds. It will be used when the overloaded CPU is found. Default is 2 seconds.
 * **long-interval=<sec>** - Long iteration interval in seconds. It will be used when there is no overloaded CPUs. Default is 5 seconds.
 * **strategy=<strategy>** - Strategy for choosing IRQ to move. The possible values are "min", "max", "rnd". The default is "rnd".
-* **exclude-cpus=<cpumap>** - It allows to exclude some CPUs from the list of CPUs that process IRQs. The 'cpumap' is bit-mask in hex format like in /proc/irq/*/smp_affinity files. It can't be used together with 'use-cpus' option.
-* **use-cpus=<cpumap>** - It allows to specify CPUs to use for IRQs processing. The 'cpumap' is bit-mask in hex format like in /proc/irq/*/smp_affinity files. It can't be used together with 'exclude-cpus' option.
+* **exclude-cpus=<cpumap>** - It allows to exclude some CPUs from the list of CPUs that process IRQs. The 'cpumap' is bit-mask in hex format like in /proc/irq/*/smp_affinity files. Real affinity will be (use-cpus & ~exclude-cpus).
+* **use-cpus=<cpumap>** - It allows to specify CPUs to use for IRQs processing. The 'cpumap' is bit-mask in hex format like in /proc/irq/*/smp_affinity files. Real affinity will be (use-cpus & ~exclude-cpus).
 * **ht=<y/n>** - Consider Hyper Threading as a real CPU. Recommended. Default is "y" since birq-1.5.0.
 * **non-local-cpus=<y/n>** - The prefered CPUs to move IRQ to is local CPUs (local NUMA node). By default BIRQ move IRQs to the local CPUs only. But sometimes in a case of a high load it can be better to move IRQ to non-local CPU than process it on overloaded local CPU. Use "y" if you want to use non-local CPUs.
 

+ 1 - 1
examples/birq.conf

@@ -4,4 +4,4 @@ load-limit=95.0
 short-interval=2
 long-interval=5
 #exclude-cpus=1
-#use-cpus=1
+#use-cpus=3