dev-amdgpu: Fix pending PCI RLC doorbell (#1157)
SDMA RLC queues do not currently remove their doorbell mapping. This can cause issues re-registering the queue and prevents the pending doorbells feature from working. In addition the data value of the doorbell (the ring buffer rptr) is not saved, leading to UB when this workaround is used. This commit removes the doorbell mapping from the gpu device when the SDMA engine unmaps an RLC queue and copies the next doorbell value to the pending packet as was originally intended. Change-Id: Ifd551450f439c065579afcf916f8ff192e7598ab
This commit is contained in:
@@ -517,10 +517,13 @@ AMDGPUDevice::writeDoorbell(PacketPtr pkt, Addr offset)
|
||||
offset);
|
||||
|
||||
// We have to ACK the PCI packet immediately, so create a copy of the
|
||||
// packet here to send again.
|
||||
// packet here to send again. The packet data contains the value of
|
||||
// the doorbell to write so we need to copy that as the original
|
||||
// packet gets deleted after the PCI write() method returns.
|
||||
RequestPtr pending_req(pkt->req);
|
||||
PacketPtr pending_pkt = Packet::createWrite(pending_req);
|
||||
uint8_t *pending_data = new uint8_t[pkt->getSize()];
|
||||
memcpy(pending_data, pkt->getPtr<uint8_t>(), pkt->getSize());
|
||||
pending_pkt->dataDynamic(pending_data);
|
||||
|
||||
pendingDoorbellPkts.emplace(offset, pending_pkt);
|
||||
@@ -709,6 +712,12 @@ AMDGPUDevice::setDoorbellType(uint32_t offset, QueueType qt, int ip_id)
|
||||
doorbells[offset].ip_id = ip_id;
|
||||
}
|
||||
|
||||
void
|
||||
AMDGPUDevice::unsetDoorbell(uint32_t offset)
|
||||
{
|
||||
doorbells.erase(offset);
|
||||
}
|
||||
|
||||
void
|
||||
AMDGPUDevice::setSDMAEngine(Addr offset, SDMAEngine *eng)
|
||||
{
|
||||
|
||||
@@ -196,6 +196,7 @@ class AMDGPUDevice : public PciDevice
|
||||
* Set handles to GPU blocks.
|
||||
*/
|
||||
void setDoorbellType(uint32_t offset, QueueType qt, int ip_id = 0);
|
||||
void unsetDoorbell(uint32_t offset);
|
||||
void processPendingDoorbells(uint32_t offset);
|
||||
void setSDMAEngine(Addr offset, SDMAEngine *eng);
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ SDMAEngine::deallocateRLCQueues()
|
||||
for (auto doorbell: rlcInfo) {
|
||||
if (doorbell) {
|
||||
unregisterRLCQueue(doorbell);
|
||||
gpuDevice->unsetDoorbell(doorbell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user