dev-hsa: enable interruptible hsa signal support
Event creation and management support from emulated drivers is required to support interruptible signals in HSA and this support was not available. This changeset adds the event creation and management support in the emulated driver. With this patch, each interruptible signal created by the HSA runtime is associated with a signal event. The HSA runtime can then put a thread waiting on a signal condition to sleep asking the driver to monitor the event associated with that signal. If the signal is modified by the GPU, the dispatcher notifies the driver about signal value change. If the modifier is a CPU thread, the thread will have to make HSA API calls to modify the signal and these API calls will notify the driver about signal value change. Once the driver is notified about a change in the signal value, the driver checks to see if any thread is sleeping on that signal and wake up the sleeping thread associated with that event. The driver has also implemented the time_out wakeup that can wake up the thread after a certain time period has expired. This is also true for barrier packets. Each signal has an event address in a kernel managed and allocated event page that can be used as a mailbox pointer to notify an event. However, this feature used by non-CPU agents to communicate with the driver is not implemented by this changeset because the non-CPU HSA agents in our model can directly communicate with driver in our implementation. Having said that, adding that feature should be trivial because the event address and event pages are correctly setup by this changeset and just adding the event page's virtual address to our PIO doorbell interface in the page tables and registering that pio address to the driver should be sufficient. Managing mailbox pointer for an event is based on event ID and using this event ID as an index into event page, this changeset already provides a unique mailbox pointer for each event. Change-Id: Ic62794076ddd47526b1f952fdb4c1bad632bdd2e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38335 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com> Maintainer: Matt Sinclair <mattdsinclair@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Kyle Roarty
parent
368216033a
commit
965ad12b9a
@@ -39,6 +39,9 @@
|
||||
#include "debug/GPUKernelInfo.hh"
|
||||
#include "gpu-compute/dispatcher.hh"
|
||||
#include "params/GPUCommandProcessor.hh"
|
||||
#include "sim/process.hh"
|
||||
#include "sim/proxy_ptr.hh"
|
||||
#include "sim/syscall_emul_buf.hh"
|
||||
|
||||
GPUCommandProcessor::GPUCommandProcessor(const Params &p)
|
||||
: HSADevice(p), dispatcher(*p.dispatcher)
|
||||
@@ -146,6 +149,57 @@ GPUCommandProcessor::submitDispatchPkt(void *raw_pkt, uint32_t queue_id,
|
||||
++dynamic_task_id;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GPUCommandProcessor::functionalReadHsaSignal(Addr signal_handle)
|
||||
{
|
||||
Addr value_addr = getHsaSignalValueAddr(signal_handle);
|
||||
auto tc = system()->threads[0];
|
||||
ConstVPtr<Addr> prev_value(value_addr, tc);
|
||||
return *prev_value;
|
||||
}
|
||||
|
||||
void
|
||||
GPUCommandProcessor::updateHsaSignal(Addr signal_handle, uint64_t signal_value)
|
||||
{
|
||||
// The signal value is aligned 8 bytes from
|
||||
// the actual handle in the runtime
|
||||
Addr value_addr = getHsaSignalValueAddr(signal_handle);
|
||||
Addr mailbox_addr = getHsaSignalMailboxAddr(signal_handle);
|
||||
Addr event_addr = getHsaSignalEventAddr(signal_handle);
|
||||
DPRINTF(GPUCommandProc, "Triggering completion signal: %x!\n", value_addr);
|
||||
|
||||
Addr *new_signal = new Addr;
|
||||
*new_signal = signal_value;
|
||||
|
||||
dmaWriteVirt(value_addr, sizeof(Addr), nullptr, new_signal, 0);
|
||||
|
||||
auto tc = system()->threads[0];
|
||||
ConstVPtr<uint64_t> mailbox_ptr(mailbox_addr, tc);
|
||||
|
||||
// Notifying an event with its mailbox pointer is
|
||||
// not supported in the current implementation. Just use
|
||||
// mailbox pointer to distinguish between interruptible
|
||||
// and default signal. Interruptible signal will have
|
||||
// a valid mailbox pointer.
|
||||
if (*mailbox_ptr != 0) {
|
||||
// This is an interruptible signal. Now, read the
|
||||
// event ID and directly communicate with the driver
|
||||
// about that event notification.
|
||||
ConstVPtr<uint32_t> event_val(event_addr, tc);
|
||||
|
||||
DPRINTF(GPUCommandProc, "Calling signal wakeup event on "
|
||||
"signal event value %d\n", *event_val);
|
||||
signalWakeupEvent(*event_val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUCommandProcessor::attachDriver(HSADriver *hsa_driver)
|
||||
{
|
||||
fatal_if(driver, "Should not overwrite driver.");
|
||||
driver = hsa_driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* submitVendorPkt() is for accepting vendor-specific packets from
|
||||
* the HSAPP. Vendor-specific packets may be used by the runtime to
|
||||
@@ -230,6 +284,12 @@ GPUCommandProcessor::dispatchPkt(HSAQueueEntry *task)
|
||||
dispatcher.dispatch(task);
|
||||
}
|
||||
|
||||
void
|
||||
GPUCommandProcessor::signalWakeupEvent(uint32_t event_id)
|
||||
{
|
||||
driver->signalWakeupEvent(event_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* The CP is responsible for traversing all HSA-ABI-related data
|
||||
* structures from memory and initializing the ABI state.
|
||||
|
||||
Reference in New Issue
Block a user