Skip to content

Commit 3054362

Browse files
Adding support for asynchronous file transfer
- File transfer between BMC and Host is synchronous mechanism. - File transfer interrupted because of many reasons, so if file transfer interrupted between BMC and Host then PLDM is ending up in the hung state and not able to respond to the upcoming new requests. User has to do work around to restart the PLDM to get work again. - I have added asynchronous file transfer support using eventloop mechanism and non-blocking socket communication, so file transfer will be taken care by event loop and PLDM is free to receive another request from the Host. - If file transfer will be stuck or interrupted during asynchronous transfer then time-out occurs and file transfer will be aborted and same status communicated to the Host.
2 parents 7dde80c + 1430595 commit 3054362

20 files changed

+601
-412
lines changed

oem/ibm/libpldmresponder/file_io.cpp

+44-40
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using namespace pldm::responder::utils;
2727
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
2828
namespace responder
2929
{
30-
extern SocketWriteStatus socketWriteStatus;
30+
// extern SocketWriteStatus socketWriteStatus;
3131
namespace fs = std::filesystem;
3232

3333
namespace dma
@@ -49,7 +49,6 @@ struct AspeedXdmaOp
4949

5050
int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
5151
{
52-
socketWriteStatus = NotReady;
5352
uint32_t pageAlLength = getpageAlignedLength();
5453
int rc = 0;
5554
int xdmaFd = -1;
@@ -62,6 +61,7 @@ int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
6261
<< rc << "\n";
6362
return rc;
6463
}
64+
6565
void* vgaMemDump = getXDMAsharedlocation();
6666
if (MAP_FAILED == vgaMemDump)
6767
{
@@ -71,41 +71,51 @@ int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
7171
<< rc << "\n";
7272
return rc;
7373
}
74-
AspeedXdmaOp xdmaOp;
75-
xdmaOp.upstream = 0;
76-
xdmaOp.hostAddr = address;
77-
xdmaOp.len = length;
78-
rc = write(xdmaFd, &xdmaOp, sizeof(xdmaOp));
79-
if (rc < 0)
80-
{
81-
rc = errno;
82-
std::cerr
83-
<< "transferHostDataToSocket : Failed to execute the DMA operation, RC="
84-
<< rc << " ADDRESS=" << address << " LENGTH=" << length << "\n";
74+
auto mmapCleanup = [pageAlLength, &rc, xdmaFd, this](void* vgaMem) {
8575
if (rc != -EINTR)
8676
{
87-
munmap(vgaMemDump, pageAlLength);
8877
if (xdmaFd > 0)
8978
{
9079
close(xdmaFd);
9180
setXDMASourceFd(-1);
9281
}
82+
munmap(vgaMem, pageAlLength);
83+
memAddr = nullptr;
9384
}
9485
else
9586
{
9687
std::cerr
9788
<< "transferHostDataToSocket : Received interrupt during dump DMA transfer. Skipping Unmap"
9889
<< std::endl;
9990
}
91+
};
92+
std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMemDump,
93+
mmapCleanup);
94+
95+
AspeedXdmaOp xdmaOp;
96+
xdmaOp.upstream = 0;
97+
xdmaOp.hostAddr = address;
98+
xdmaOp.len = length;
99+
rc = write(xdmaFd, &xdmaOp, sizeof(xdmaOp));
100+
if (rc < 0)
101+
{
102+
rc = -errno;
103+
std::cerr
104+
<< "transferHostDataToSocket : Failed to execute the DMA operation, RC="
105+
<< rc << " ADDRESS=" << address << " LENGTH=" << length << "\n";
100106
return rc;
101107
}
102108

103109
rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemDump), length);
104110
if (rc < 0)
105111
{
112+
rc = -errno;
113+
close(fd);
106114
std::cerr
107-
<< "transferHostDataToSocket writing To Unix Socket failed. \n";
108-
return -1;
115+
<< "transferHostDataToSocket: Closing socket as writeToUnixSocket failed with RC:"
116+
<< rc << "\n";
117+
118+
return rc;
109119
}
110120
rc = length;
111121

@@ -121,7 +131,9 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
121131
int xdmaFd = getDMAFd(true, false);
122132
if (xdmaFd < 0)
123133
{
124-
std::cerr << " transferDataHost : Failed to open the XDMA device \n";
134+
rc = -errno;
135+
std::cerr << " transferDataHost : Failed to open the XDMA device rc:"
136+
<< rc << "\n";
125137
return -1;
126138
}
127139

@@ -157,6 +169,7 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
157169
rc = lseek(fd, offset, SEEK_SET);
158170
if (rc == -1)
159171
{
172+
rc = -errno;
160173
std::cerr << "transferDataHost upstream : lseek failed, ERROR="
161174
<< errno << ", UPSTREAM=" << upstream
162175
<< ", OFFSET=" << offset << "\n";
@@ -171,6 +184,7 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
171184
rc = read(fd, buffer.data(), length);
172185
if (rc == -1)
173186
{
187+
rc = -errno;
174188
std::cerr << "transferDataHost upstream : file read failed, ERROR="
175189
<< errno << ", UPSTREAM=" << upstream
176190
<< ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
@@ -194,27 +208,10 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
194208
xdmaOp.hostAddr = address;
195209
xdmaOp.len = length;
196210

197-
// int retry = 0;
198-
199-
// do
200-
// {
201211
rc = write(xdmaFd, &xdmaOp, sizeof(xdmaOp));
202-
// std::cout << "KK total length of write0 from DMA:" << length
203-
// << " read out of total length rc:" << rc << " offset:" <<
204-
// offset
205-
// << " address:" << address << "\n";
206-
// if (rc > 0)
207-
// {
208-
// break;
209-
// }
210-
// retry++;
211-
// std::cout << "KK write0 retry:" << retry << " errno:" << errno <<
212-
// "\n"; usleep(1000000);
213-
// } while (retry < 3);
214-
215212
if (rc < 0)
216213
{
217-
rc = errno;
214+
rc = -errno;
218215
std::cerr
219216
<< "transferDataHost : Failed to execute the DMA operation, RC="
220217
<< rc << " UPSTREAM=" << upstream << " ADDRESS=" << address
@@ -227,6 +224,7 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
227224
rc = lseek(fd, offset, SEEK_SET);
228225
if (rc == -1)
229226
{
227+
rc = -errno;
230228
std::cerr << "transferDataHost downstream : lseek failed, ERROR="
231229
<< errno << ", UPSTREAM=" << upstream
232230
<< ", OFFSET=" << offset << " fd:" << fd << " rc:" << rc
@@ -237,6 +235,7 @@ int32_t DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
237235
rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
238236
if (rc == -1)
239237
{
238+
rc = -errno;
240239
std::cerr
241240
<< "transferDataHost downstream : file write failed, ERROR="
242241
<< errno << ", UPSTREAM=" << upstream << ", LENGTH=" << length
@@ -730,11 +729,16 @@ Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
730729
responseHdr.instance_id = request->hdr.instance_id;
731730
responseHdr.command = cmd;
732731
responseHdr.key = responseHdr.respInterface->getRequestHeaderIndex();
733-
rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
734-
? handler->writeFromMemory(offset, length, address,
735-
oemPlatformHandler, responseHdr, event)
736-
: handler->readIntoMemory(offset, length, address,
737-
oemPlatformHandler, responseHdr, event);
732+
if (cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY)
733+
{
734+
handler->writeFromMemory(offset, length, address, oemPlatformHandler,
735+
responseHdr, event);
736+
}
737+
else
738+
{
739+
handler->readIntoMemory(offset, length, address, oemPlatformHandler,
740+
responseHdr, event);
741+
}
738742

739743
return {};
740744
}

0 commit comments

Comments
 (0)