turbostat plugin: Polished RestoreAffinityPolicy option
authorPavel Rochnyack <pavel2000@ngs.ru>
Sat, 27 Oct 2018 13:16:38 +0000 (20:16 +0700)
committerPavel Rochnyack <pavel2000@ngs.ru>
Sat, 27 Oct 2018 13:21:25 +0000 (20:21 +0700)
src/collectd.conf.pod
src/turbostat.c

index d830573..03b163e 100644 (file)
@@ -8865,6 +8865,33 @@ dynamic number assigned by the kernel. Otherwise, C<coreE<lt>nE<gt>> is used
 if there is only one package and C<pkgE<lt>nE<gt>-coreE<lt>mE<gt>> if there is
 more than one, where I<n> is the n-th core of package I<m>.
 
+=item B<RestoreAffinityPolicy> I<AllCPUs>|I<Restore>
+
+Reading data from CPU has side-effect: collectd process's CPU affinity mask
+changes. After reading data is completed, affinity mask needs to be restored.
+This option allows to set restore policy.
+
+B<AllCPUs> (the default): Restore the affinity by setting affinity to any/all
+CPUs.
+
+B<Restore>: Save affinity using sched_getaffinity() before reading data and
+restore it after.
+
+On some systems, sched_getaffinity() will fail due to inconsistency of the CPU
+set size between userspace and kernel. In these cases plugin will detect the
+unsuccessful call and fail with an error, preventing data collection.
+Most of configurations does not need to save affinity as Collectd process is
+allowed to run on any/all available CPUs.
+
+If you need to save and restore affinity and get errors like 'Unable to save
+the CPU affinity', setting 'possible_cpus' kernel boot option may also help.
+
+See following links for details:
+
+L<https://github.com/collectd/collectd/issues/1593>
+L<https://sourceware.org/bugzilla/show_bug.cgi?id=15630>
+L<https://bugzilla.kernel.org/show_bug.cgi?id=151821>
+
 =back
 
 =head2 Plugin C<unixsock>
index ca87219..4a7af4c 100644 (file)
 
 typedef enum affinity_policy_enum {
   policy_restore_affinity, /* restore cpu affinity to whatever it was before */
-  policy_allcpus_affinity, /* do not restore affinity, set to all cpus */
-  policy_invalid
+  policy_allcpus_affinity  /* do not restore affinity, set to all cpus */
 } affinity_policy_t;
 
-/* the default is to preserve cpu affinity */
-static affinity_policy_t affinity_policy = policy_restore_affinity;
+/* the default is to set cpu affinity to all cpus */
+static affinity_policy_t affinity_policy = policy_allcpus_affinity;
 
 /*
  * This tool uses the Model-Specific Registers (MSRs) present on Intel
@@ -1467,8 +1466,8 @@ err:
 int save_affinity(void) {
   if (affinity_policy == policy_restore_affinity) {
     /* Try to save the scheduling affinity, as it will be modified by
-    * get_counters.
-    */
+     * get_counters().
+     */
     if (sched_getaffinity(0, cpu_saved_affinity_setsize,
                           cpu_saved_affinity_set) != 0)
       return -1;
@@ -1508,7 +1507,8 @@ static int turbostat_read(void) {
   }
 
   if (save_affinity() != 0) {
-    ERROR("turbostat plugin: Unable to save the CPU affinity");
+    ERROR("turbostat plugin: Unable to save the CPU affinity. Please read the "
+          "docs about RestoreAffinityPolicy option.");
     return -1;
   }
 
@@ -1617,15 +1617,6 @@ err:
   return ret;
 }
 
-affinity_policy_t parse_affinity_policy(const char *value) {
-  if (strcasecmp("AffinityRestore", value) == 0)
-    return policy_restore_affinity;
-  else if (strcasecmp("AffinityAllCPUs", value) == 0)
-    return policy_allcpus_affinity;
-
-  return policy_invalid;
-}
-
 static int turbostat_config(const char *key, const char *value) {
   long unsigned int tmp_val;
   char *end;
@@ -1673,11 +1664,13 @@ static int turbostat_config(const char *key, const char *value) {
     }
     tcc_activation_temp = (unsigned int)tmp_val;
   } else if (strcasecmp("RestoreAffinityPolicy", key) == 0) {
-    affinity_policy = parse_affinity_policy(value);
-    if (affinity_policy == policy_invalid) {
-      /* set to default policy if requested policy is invalid */
+    if (strcasecmp("Restore", value) == 0)
       affinity_policy = policy_restore_affinity;
+    else if (strcasecmp("AllCPUs", value) == 0)
+      affinity_policy = policy_allcpus_affinity;
+    else {
       ERROR("turbostat plugin: Invalid RestoreAffinityPolicy '%s'", value);
+      return -1;
     }
   } else {
     ERROR("turbostat plugin: Invalid configuration option '%s'", key);