1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

make DMA ip unmap memory owned by itself

unmapping of the scatter gather attribute memory was done
after the DMA destructor was called, leading to Card trying to
unmap memory that was already freed.
This lead to crashing during cleaning up.

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2023-01-04 17:17:21 +01:00
parent d818ecd365
commit 80af655ac5
3 changed files with 31 additions and 2 deletions

View file

@ -88,8 +88,8 @@ public:
std::shared_ptr<ip::Core>
lookupIp(const ip::IpIdentifier &id) const;
bool
mapMemoryBlock(const MemoryBlock &block);
bool mapMemoryBlock(const MemoryBlock &block);
bool unmapMemoryBlock(const MemoryBlock &block);
private:
// Cache a set of already mapped memory blocks

View file

@ -218,6 +218,29 @@ std::shared_ptr<ip::Core> PCIeCard::lookupIp(const ip::IpIdentifier &id) const
return nullptr;
}
bool PCIeCard::unmapMemoryBlock(const MemoryBlock &block)
{
if (memoryBlocksMapped.find(block.getAddrSpaceId()) == memoryBlocksMapped.end()) {
throw std::runtime_error("Block " + std::to_string(block.getAddrSpaceId()) + " is not mapped but was requested to be unmapped.");
}
auto &mm = MemoryManager::get();
// Unmap all memory blocks
auto translation = mm.getTranslation(addrSpaceIdDeviceToHost, block.getAddrSpaceId());
const uintptr_t iova = translation.getLocalAddr(0);
const size_t size = translation.getSize();
logger->debug("Unmap block {} at IOVA {:#x} of size {:#x}",
block.getAddrSpaceId(), iova, size);
vfioContainer->memoryUnmap(iova, size);
memoryBlocksMapped.erase(block.getAddrSpaceId());
return true;
}
bool PCIeCard::mapMemoryBlock(const MemoryBlock &block)
{
if (not vfioContainer->isIommuEnabled()) {

View file

@ -205,6 +205,12 @@ bool Dma::reset()
Dma::~Dma()
{
// Unmap memory in our ownership, MemoryBlock gets deleted and removed from
// graph by this destructor as well.
if (hasScatterGather()) {
card->unmapMemoryBlock(*sgRingTx);
card->unmapMemoryBlock(*sgRingRx);
}
Dma::reset();
}