fru-device: Fix bus lock timeout
When we have a bus that can't get scanned, it locks up
on us for a couple minutes, which is much too long. There
was a thread added, but std::future's destructor blocks,
causing the timeout to still happen. Move the close into
the same scope as the std::future to force stop the blocking
i2c transaction so that we can continue. Also create a bus
blacklist that once a bus locks up on us we stop scanning it
so next scan we avoid the bad bus altogether.
Tested: Added bad bus (i2c9) to wfp and startup time was
near normal.
Change-Id: I22e224a69236a6dfe0a1549ed0e4239e22cdf5d2
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0605dd9..6bc5362 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,7 +78,6 @@
add_definitions (-DBOOST_ALL_NO_LIB)
add_definitions (-DBOOST_NO_RTTI)
add_definitions (-DBOOST_NO_TYPEID)
-add_definitions (-DBOOST_ASIO_DISABLE_THREADS)
include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories (${Boost_INCLUDE_DIRS})
@@ -121,7 +120,8 @@
)
set (PACKAGE_DIR /usr/share/entity-manager/)
-target_compile_definitions (entity-manager PRIVATE PACKAGE_DIR="${PACKAGE_DIR}")
+target_compile_definitions (entity-manager PRIVATE PACKAGE_DIR="${PACKAGE_DIR}"
+ -DBOOST_ASIO_DISABLE_THREADS)
install (TARGETS fru-device entity-manager DESTINATION bin)
install (DIRECTORY configurations DESTINATION ${PACKAGE_DIR})
install (DIRECTORY overlay_templates DESTINATION ${PACKAGE_DIR})
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index b98615d..9d0beff 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -56,6 +56,7 @@
using DeviceMap = boost::container::flat_map<int, std::vector<char>>;
using BusMap = boost::container::flat_map<int, std::shared_ptr<DeviceMap>>;
+static std::set<size_t> busBlacklist;
struct FindDevicesWithCallback;
static bool isMuxBus(size_t bus)
@@ -260,9 +261,12 @@
if (status == std::future_status::timeout)
{
std::cerr << "Error reading bus " << bus << "\n";
+ busBlacklist.insert(bus);
+ close(file);
return -1;
}
+ close(file);
return future.get();
}
@@ -280,6 +284,10 @@
busnum.erase(0, lastDash + 1);
}
auto bus = std::stoi(busnum);
+ if (busBlacklist.find(bus) != busBlacklist.end())
+ {
+ continue; // skip previously failed busses
+ }
auto file = open(i2cBus.c_str(), O_RDWR);
if (file < 0)
@@ -307,23 +315,31 @@
auto& device = busMap[bus];
device = std::make_shared<DeviceMap>();
+ auto callback = [file, device, bus, context]() {
+ // i2cdetect by default uses the range 0x03 to 0x77, as
+ // this is what we have tested with, use this range. Could be
+ // changed in future.
+ if (DEBUG)
+ {
+ std::cerr << "Scanning bus " << bus << "\n";
+ }
+
+ // fd is closed in this function in case the bus locks up
+ get_bus_frus(file, 0x03, 0x77, bus, device);
+
+ if (DEBUG)
+ {
+ std::cerr << "Done scanning bus " << bus << "\n";
+ }
+ };
// don't scan muxed buses async as don't want to confuse the mux
if (isMuxBus(bus))
{
- get_bus_frus(file, 0x03, 0x77, bus, device);
- close(file);
+ callback();
}
else
{
- io.post([file, device, bus, context] {
- // i2cdetect by default uses the range 0x03 to 0x77, as
- // this is
- // what we
- // have tested with, use this range. Could be changed in
- // future.
- get_bus_frus(file, 0x03, 0x77, bus, device);
- close(file);
- });
+ io.post(callback);
}
}
}