summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lewycky <Andrew.Lewycky@amd.com>2014-10-13 11:30:18 +0300
committerOded Gabbay <oded.gabbay@gmail.com>2015-05-05 12:26:59 +0300
commit201e9ff0907484f9b1089a36971f57e6aa8fbcf1 (patch)
tree3acd2b7a725266e11c1aec57a2e19745af2738fb
parent7b889dde713fcf7b4e4b3c9bbe6f58ea370b8579 (diff)
Add HSA Signals module
Signed-off-by: Andrew Lewycky <Andrew.Lewycky@amd.com> Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
-rw-r--r--src/events.c162
1 files changed, 132 insertions, 30 deletions
diff --git a/src/events.c b/src/events.c
index cb07116..be58253 100644
--- a/src/events.c
+++ b/src/events.c
@@ -25,9 +25,20 @@
#include "libhsakmt.h"
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
+#include <sys/mman.h>
+#include "linux/kfd_ioctl.h"
+
+static HSAuint64 *events_page = NULL;
+
+static bool IsSystemEventType(HSA_EVENTTYPE type)
+{
+ // Debug events behave as signal events.
+ return (type != HSA_EVENTTYPE_SIGNAL && type != HSA_EVENTTYPE_DEBUG_EVENT);
+}
HSAKMT_STATUS
HSAKMTAPI
@@ -51,6 +62,45 @@ hsaKmtCreateEvent(
return HSAKMT_STATUS_ERROR;
}
+ memset(e, 0, sizeof(*e));
+
+ struct kfd_ioctl_create_event_args args;
+ memset(&args, 0, sizeof(args));
+
+ args.event_type = EventDesc->EventType;
+ args.auto_reset = !ManualReset;
+
+ if (kmtIoctl(kfd_fd, AMDKFD_IOC_CREATE_EVENT, &args) != 0) {
+ free(e);
+ *Event = NULL;
+ return HSAKMT_STATUS_ERROR;
+ }
+
+ if (events_page == NULL && args.event_page_offset > 0) {
+ events_page = mmap(NULL, 4096, PROT_WRITE | PROT_READ,
+ MAP_SHARED, kfd_fd, args.event_page_offset);
+ if (events_page == NULL) {
+ hsaKmtDestroyEvent(e);
+ return HSAKMT_STATUS_ERROR;
+ }
+ }
+
+ if (args.event_page_offset > 0 && args.event_slot_index < KFD_SIGNAL_EVENT_LIMIT)
+ e->EventData.HWData2 = (HSAuint64)&events_page[args.event_slot_index];
+
+ e->EventId = args.event_id;
+ e->EventData.HWData1 = args.event_id;
+
+ e->EventData.HWData3 = args.event_trigger_data;
+
+ if (IsSignaled && !IsSystemEventType(e->EventData.EventType)) {
+ struct kfd_ioctl_set_event_args set_args;
+ memset(&set_args, 0, sizeof(set_args));
+ set_args.event_id = args.event_id;
+
+ kmtIoctl(kfd_fd, AMDKFD_IOC_SET_EVENT, &set_args);
+ }
+
*Event = e;
return HSAKMT_STATUS_SUCCESS;
@@ -64,6 +114,18 @@ hsaKmtDestroyEvent(
{
CHECK_KFD_OPEN();
+ if (!Event)
+ return HSAKMT_STATUS_INVALID_HANDLE;
+
+ struct kfd_ioctl_destroy_event_args args;
+ memset(&args, 0, sizeof(args));
+
+ args.event_id = Event->EventId;
+
+ if (kmtIoctl(kfd_fd, AMDKFD_IOC_DESTROY_EVENT, &args) != 0) {
+ return HSAKMT_STATUS_ERROR;
+ }
+
free(Event);
return HSAKMT_STATUS_SUCCESS;
@@ -76,6 +138,22 @@ hsaKmtSetEvent(
)
{
CHECK_KFD_OPEN();
+
+ if (!Event)
+ return HSAKMT_STATUS_INVALID_HANDLE;
+
+ /* Although the spec is doesn't say, don't allow system-defined events to be signaled. */
+ if (IsSystemEventType(Event->EventData.EventType))
+ return HSAKMT_STATUS_ERROR;
+
+ struct kfd_ioctl_set_event_args args;
+ memset(&args, 0, sizeof(args));
+
+ args.event_id = Event->EventId;
+
+ if (kmtIoctl(kfd_fd, AMDKFD_IOC_SET_EVENT, &args) == -1)
+ return HSAKMT_STATUS_ERROR;
+
return HSAKMT_STATUS_SUCCESS;
}
@@ -86,6 +164,22 @@ hsaKmtResetEvent(
)
{
CHECK_KFD_OPEN();
+
+ if (!Event)
+ return HSAKMT_STATUS_INVALID_HANDLE;
+
+ /* Although the spec is doesn't say, don't allow system-defined events to be signaled. */
+ if (IsSystemEventType(Event->EventData.EventType))
+ return HSAKMT_STATUS_ERROR;
+
+ struct kfd_ioctl_reset_event_args args;
+ memset(&args, 0, sizeof(args));
+
+ args.event_id = Event->EventId;
+
+ if (kmtIoctl(kfd_fd, AMDKFD_IOC_RESET_EVENT, &args) == -1)
+ return HSAKMT_STATUS_ERROR;
+
return HSAKMT_STATUS_SUCCESS;
}
@@ -96,6 +190,10 @@ hsaKmtQueryEventState(
)
{
CHECK_KFD_OPEN();
+
+ if (!Event)
+ return HSAKMT_STATUS_INVALID_HANDLE;
+
return HSAKMT_STATUS_SUCCESS;
}
@@ -106,36 +204,10 @@ hsaKmtWaitOnEvent(
HSAuint32 Milliseconds //IN
)
{
- CHECK_KFD_OPEN();
-
- if (Milliseconds == HSA_EVENTTIMEOUT_INFINITE)
- {
- while (1) { pause(); }
- }
- else if (Milliseconds != HSA_EVENTTIMEOUT_IMMEDIATE)
- {
- struct timespec req;
-
- req.tv_sec = Milliseconds / 1000;
- req.tv_nsec = (long)(Milliseconds % 1000) * 1000000;
-
- while (1)
- {
- struct timespec rem;
-
- int err = nanosleep(&req, &rem);
- if (err == -1 && errno == EINTR)
- {
- req = rem;
- }
- else
- {
- break; // success or other error
- }
- }
- }
+ if (!Event)
+ return HSAKMT_STATUS_INVALID_HANDLE;
- return HSAKMT_STATUS_WAIT_TIMEOUT;
+ return hsaKmtWaitOnMultipleEvents(&Event, 1, true, Milliseconds);
}
HSAKMT_STATUS
@@ -149,5 +221,35 @@ hsaKmtWaitOnMultipleEvents(
{
CHECK_KFD_OPEN();
- return hsaKmtWaitOnEvent(NULL, Milliseconds);
+ if (!Events)
+ return HSAKMT_STATUS_INVALID_HANDLE;
+
+ uint32_t *event_ids = malloc(NumEvents * sizeof(uint32_t));
+ for (HSAuint32 i = 0; i < NumEvents; i++) {
+ event_ids[i] = Events[i]->EventId;
+ }
+
+ struct kfd_ioctl_wait_events_args args;
+ memset(&args, 0, sizeof(args));
+
+ args.wait_for_all = WaitOnAll;
+ args.timeout = Milliseconds;
+ args.num_events = NumEvents;
+ args.events_ptr = (uint64_t)(uintptr_t)event_ids;
+
+ HSAKMT_STATUS result;
+
+ if (kmtIoctl(kfd_fd, AMDKFD_IOC_WAIT_EVENTS, &args) == -1) {
+ result = HSAKMT_STATUS_ERROR;
+ }
+ else if (args.wait_result == KFD_IOC_WAIT_RESULT_TIMEOUT) {
+ result = HSAKMT_STATUS_WAIT_TIMEOUT;
+ }
+ else {
+ result = HSAKMT_STATUS_SUCCESS;
+ }
+
+ free(event_ids);
+
+ return result;
}