debugd: Retry writing to CPU control files.

Bug reports indicate that sometimes writing to the CPU control files
returns EBUSY, and thus there needs to be retry logic.

BUG=chromium:1038955,b:143918745
TEST=tast -verbose run ${DUT_IP} debugd.CoreScheduler

Change-Id: Icccab5490d4d31567002f5abbdbb7c074fbf98a0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1988946
Tested-by: Greg Kerr <kerrnel@chromium.org>
Auto-Submit: Greg Kerr <kerrnel@chromium.org>
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Greg Kerr <kerrnel@chromium.org>
(cherry picked from commit b572e9d5a9d198a492a3e04a251f384a346340ef)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1994651
Reviewed-by: Philip Chen <philipchen@chromium.org>
Commit-Queue: Philip Chen <philipchen@chromium.org>
Tested-by: Philip Chen <philipchen@chromium.org>
diff --git a/debugd/src/helpers/scheduler_configuration_utils.cc b/debugd/src/helpers/scheduler_configuration_utils.cc
index 086d380..7ea27fc 100644
--- a/debugd/src/helpers/scheduler_configuration_utils.cc
+++ b/debugd/src/helpers/scheduler_configuration_utils.cc
@@ -17,6 +17,7 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_split.h>
 #include <base/strings/stringprintf.h>
+#include <base/time/time.h>
 
 namespace debugd {
 
@@ -28,6 +29,8 @@
 constexpr char kCPUOnlineSubpath[] = "devices/system/cpu/online";
 constexpr char kDisableCPUFlag[] = "0";
 constexpr char kEnableCPUFlag[] = "1";
+constexpr base::TimeDelta kWriteRetryDelay =
+    base::TimeDelta::FromMilliseconds(100);
 
 }  // namespace
 
@@ -96,7 +99,15 @@
 }
 
 bool SchedulerConfigurationUtils::DisableCPU(const std::string& cpu_number) {
-  return LookupFDAndWriteFlag(cpu_number, kDisableCPUFlag);
+  bool status = LookupFDAndWriteFlag(cpu_number, kDisableCPUFlag);
+  // Sometimes the CPU control file is busy so sleep and retry.
+  int retries = 5;
+  while (!status && errno == EBUSY && retries-- > 0) {
+    usleep(kWriteRetryDelay.InMicroseconds());
+    status = LookupFDAndWriteFlag(cpu_number, kDisableCPUFlag);
+  }
+
+  return status;
 }
 
 // This writes the flag to enable the given CPU by number.