Skip to content

Commit 6df2fc0

Browse files
committed
mctp: MCTPReactor: Replace deferred queue with a state machine
This change isn't significant in its own right. Rather it lays the ground-work to expand the state machine in a subsequent change to prevent disruption from late propagation of inventory changes relative to an endpoint being recovered. Change-Id: I9bb81de48252ca66465489caad8c63c8e2cdea17 Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
1 parent 3531e0f commit 6df2fc0

File tree

4 files changed

+35
-10
lines changed

4 files changed

+35
-10
lines changed

src/mctp/MCTPDeviceRepository.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,14 @@ class MCTPDeviceRepository
8282
}
8383
return entry->second;
8484
}
85+
86+
auto begin()
87+
{
88+
return devices.begin();
89+
}
90+
91+
auto end()
92+
{
93+
return devices.end();
94+
}
8595
};

src/mctp/MCTPReactor.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void MCTPReactor::deferSetup(const std::shared_ptr<MCTPDevice>& dev)
2121
debug("Deferring setup for MCTP device at [ {MCTP_DEVICE} ]", "MCTP_DEVICE",
2222
dev->describe());
2323

24-
deferred.emplace(dev);
24+
states[dev->id()] = MCTPDeviceState::Unassigned;
2525
}
2626

2727
void MCTPReactor::untrackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
@@ -34,6 +34,7 @@ void MCTPReactor::trackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
3434
info("Added MCTP endpoint to device: [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
3535
ep->describe());
3636

37+
states[ep->device()->id()] = MCTPDeviceState::Assigned;
3738
ep->subscribe(
3839
// Degraded
3940
[](const std::shared_ptr<MCTPEndpoint>& ep) {
@@ -57,6 +58,10 @@ void MCTPReactor::trackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
5758
{
5859
self->deferSetup(ep->device());
5960
}
61+
else
62+
{
63+
self->states.erase(ep->device()->id());
64+
}
6065
}
6166
else
6267
{
@@ -136,10 +141,12 @@ void MCTPReactor::setupEndpoint(const std::shared_ptr<MCTPDevice>& dev)
136141

137142
void MCTPReactor::tick()
138143
{
139-
auto toSetup = std::exchange(deferred, {});
140-
for (const auto& entry : toSetup)
144+
for (const auto& entry : devices)
141145
{
142-
setupEndpoint(entry);
146+
if (states[entry.second->id()] == MCTPDeviceState::Unassigned)
147+
{
148+
setupEndpoint(entry.second);
149+
}
143150
}
144151
}
145152

@@ -153,6 +160,7 @@ void MCTPReactor::manageMCTPDevice(const std::string& path,
153160

154161
try
155162
{
163+
states[device->id()] = MCTPDeviceState::Unmanaged;
156164
devices.add(path, device);
157165
debug("MCTP device inventory added at '{INVENTORY_PATH}'",
158166
"INVENTORY_PATH", path);
@@ -202,8 +210,6 @@ void MCTPReactor::unmanageMCTPDevice(const std::string& path)
202210
debug("MCTP device inventory removed at '{INVENTORY_PATH}'",
203211
"INVENTORY_PATH", path);
204212

205-
deferred.erase(device);
206-
207213
// Remove the device from the repository before notifying the device itself
208214
// of removal so we don't defer its setup
209215
devices.remove(device);

src/mctp/MCTPReactor.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <functional>
99
#include <memory>
1010
#include <optional>
11-
#include <set>
1211
#include <string>
1312
#include <vector>
1413

@@ -21,6 +20,13 @@ struct AssociationServer
2120
virtual void disassociate(const std::string& path) = 0;
2221
};
2322

23+
enum class MCTPDeviceState
24+
{
25+
Unmanaged,
26+
Assigned,
27+
Unassigned,
28+
};
29+
2430
class MCTPReactor : public std::enable_shared_from_this<MCTPReactor>
2531
{
2632
using MCTPDeviceFactory = std::function<std::shared_ptr<MCTPDevice>(
@@ -47,9 +53,7 @@ class MCTPReactor : public std::enable_shared_from_this<MCTPReactor>
4753

4854
AssociationServer& server;
4955
MCTPDeviceRepository devices;
50-
51-
// Tracks MCTP devices that have failed their setup
52-
std::set<std::shared_ptr<MCTPDevice>> deferred;
56+
std::map<std::size_t, MCTPDeviceState> states;
5357

5458
void deferSetup(const std::shared_ptr<MCTPDevice>& dev);
5559
void setupEndpoint(const std::shared_ptr<MCTPDevice>& dev);

src/tests/test_MCTPReactor.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class MCTPReactorFixture : public testing::Test
6464
device = std::make_shared<MockMCTPDevice>();
6565
EXPECT_CALL(*device, describe())
6666
.WillRepeatedly(testing::Return("mock device"));
67+
EXPECT_CALL(*device, id()).WillRepeatedly(testing::Return(0UL));
6768

6869
endpoint = std::make_shared<MockMCTPEndpoint>();
6970
EXPECT_CALL(*endpoint, device())
@@ -233,6 +234,7 @@ TEST(MCTPReactor, replaceConfiguration)
233234
auto idev = std::make_shared<MockMCTPDevice>();
234235
EXPECT_CALL(*idev, describe())
235236
.WillRepeatedly(testing::Return("mock device: initial"));
237+
EXPECT_CALL(*idev, id()).WillRepeatedly(testing::Return(0UL));
236238
EXPECT_CALL(*idev, setup(testing::_))
237239
.WillOnce(testing::InvokeArgument<0>(std::error_code(), iep));
238240
EXPECT_CALL(*idev, remove()).WillOnce(testing::Invoke([&]() {
@@ -255,6 +257,7 @@ TEST(MCTPReactor, replaceConfiguration)
255257
auto rdev = std::make_shared<MockMCTPDevice>();
256258
EXPECT_CALL(*rdev, describe())
257259
.WillRepeatedly(testing::Return("mock device: replacement"));
260+
EXPECT_CALL(*rdev, id()).WillRepeatedly(testing::Return(0UL));
258261
EXPECT_CALL(*rdev, setup(testing::_))
259262
.WillOnce(testing::InvokeArgument<0>(std::error_code(), rep));
260263
EXPECT_CALL(*rdev, remove()).WillOnce(testing::Invoke([&]() {
@@ -295,6 +298,7 @@ TEST(MCTPReactor, concurrentEndpointSetupReactorTeardown)
295298

296299
EXPECT_CALL(*device, describe())
297300
.WillRepeatedly(testing::Return("mock device"));
301+
EXPECT_CALL(*device, id()).WillRepeatedly(testing::Return(0UL));
298302
EXPECT_CALL(*device, setup(testing::_))
299303
.WillOnce(testing::SaveArg<0>(&setupHandler));
300304

@@ -328,6 +332,7 @@ TEST(MCTPReactor, manageMockDeviceDelayedSetup)
328332

329333
EXPECT_CALL(*device, describe())
330334
.WillRepeatedly(testing::Return("mock device"));
335+
EXPECT_CALL(*device, id()).WillRepeatedly(testing::Return(0UL));
331336
EXPECT_CALL(*device, remove())
332337
.WillOnce(testing::Invoke([ep{endpoint}]() { ep->remove(); }));
333338
EXPECT_CALL(*device, setup(testing::_))

0 commit comments

Comments
 (0)