Skip to content

Commit c69db7d

Browse files
committed
Expose IRQ & event descriptors
Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
1 parent 7d5b83c commit c69db7d

5 files changed

Lines changed: 91 additions & 48 deletions

File tree

src/include/libocxl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ typedef struct ocxl_event {
139139
};
140140
} ocxl_event;
141141

142-
143142
/* setup.c */
144143
void ocxl_enable_messages(uint64_t sources);
145144
void ocxl_set_error_message_handler(void (*handler)(ocxl_err error, const char *message));
@@ -169,9 +168,12 @@ ocxl_err ocxl_afu_attach(ocxl_afu_h afu);
169168
ocxl_err ocxl_afu_irq_alloc(ocxl_afu_h afu, void *info, ocxl_irq_h * irq_handle);
170169
uint64_t ocxl_afu_irq_get_handle(ocxl_afu_h afu, ocxl_irq_h irq);
171170
int ocxl_afu_get_event_fd(ocxl_afu_h afu);
171+
int ocxl_afu_irq_get_descriptor(ocxl_afu_h afu, ocxl_irq_h irq);
172+
int ocxl_afu_get_event_descriptor(ocxl_afu_h afu);
172173
int ocxl_afu_event_check_versioned(ocxl_afu_h afu, int timeout, ocxl_event *events, uint16_t event_count,
173174
uint16_t event_api_version);
174175

176+
175177
/**
176178
* @addtogroup ocxl_irq
177179
* @{

src/irq.c

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,37 @@ uint64_t ocxl_afu_irq_get_handle(ocxl_afu_h afu, ocxl_irq_h irq)
204204
return (uint64_t)my_afu->irqs[irq].addr;
205205
}
206206

207+
/**
208+
* Get the file descriptor associated with an IRQ
209+
*
210+
* This descriptor may be used with select/poll to determine if an IRQ is triggered
211+
*
212+
* @param afu the AFU the IRQ belongs to
213+
* @param irq the IRQ to get the descriptor of
214+
* @return the handle, or -1 if the descriptor is invalid
215+
*/
216+
int ocxl_afu_irq_get_descriptor(ocxl_afu_h afu, ocxl_irq_h irq)
217+
{
218+
ocxl_afu *my_afu = (ocxl_afu *) afu;
219+
220+
if (irq > my_afu->irq_count) {
221+
return -1;
222+
}
223+
224+
return my_afu->irqs[irq].event.eventfd;
225+
}
226+
227+
207228
/**
208229
* Get a descriptor that will trigger a poll when an AFU event occurs
209230
*
231+
<<<<<<< HEAD
210232
* When triggered, call ocxl_read_afu_event() to extract the event information
233+
=======
234+
* When triggered, call ocxl_afu_event_check() to extract the event information.
235+
*
236+
* @see ocxl_afu_event_check()
237+
>>>>>>> 4339b2e... Make ocxl_read_afu_event internal
211238
*
212239
* @pre the AFU has been opened
213240
* @see ocxl_afu_event_check()
@@ -250,61 +277,83 @@ static void populate_xsl_fault_error(ocxl_afu *afu, ocxl_event *event, void *bod
250277

251278
/**
252279
* @internal
253-
* Read events from the main AFU descriptor
280+
*
281+
* Read a single AFU event from the main AFU descriptor.
282+
*
283+
* An AFU may report OpenCAPI events independently from it's IRQs. When an event is
284+
* available, as notified by the descriptor returned by ocxl_afu_get_event_fd()
285+
* triggering a poll() or select(), this function will extract the information
286+
* and notify the caller if there are any further events to be queried.
287+
*
288+
* If an event is available and should be handled by the caller,
289+
* OCXL_EVENT_ACTION_SUCCESS is returned, and the event struct populated. The event struct
290+
* should be parsed by first checking the type:
291+
* Value | Action
292+
* ------------------------------ | -------
293+
* OCXL_EVENT_IRQ | This value cannot be generated by this function
294+
* OCXL_EVENT_TRANSLATION_FAULT | An OpenCAPI translation fault error has been issued, that is, the system has been unable to resolve an effective address. Events[i].translation_fault will be populated with the details of the error
295+
*
296+
* @see ocxl_afu_get_event_fd()
254297
*
255298
* @param afu the AFU to read the event from
256-
* @param max_supported_event the id of the maximum supported kernel event, events with an ID higher than this will be ignored
299+
* @param event_api_version the version of the event API that the caller wants to see
257300
* @param[out] event event to populate
258301
* @param[out] last true if this was the last event to read from the kernel for now
259302
* @retval OCXL_EVENT_ACTION_SUCCESS if the event should be handled
260303
* @retval OCXL_EVENT_ACTION_FAIL if the event read failed (fatal)
261304
* @retval OCXL_EVENT_ACTION_NONE if there was no event to read
262305
* @retval OCXL_EVENT_ACTION_IGNORE if the read was successful but should be ignored
263306
*/
264-
static ocxl_event_action read_afu_event(ocxl_afu *afu, uint16_t max_supported_event,
265-
ocxl_event *event, bool *last) // hack to allow static symbol extraction
307+
static ocxl_event_action read_afu_event(ocxl_afu_h afu, uint16_t event_api_version, ocxl_event *event, int *last)
266308
{
309+
ocxl_afu *my_afu = (ocxl_afu *) afu;
310+
267311
size_t event_size = sizeof(ocxl_kernel_event_header);
268-
*last = true;
312+
*last = 0;
269313

270-
switch (max_supported_event) {
271-
case OCXL_AFU_EVENT_XSL_FAULT_ERROR:
314+
uint16_t max_supported_event = 0;
315+
316+
switch (event_api_version) {
317+
case 0:
272318
event_size += sizeof(ocxl_kernel_event_xsl_fault_error);
319+
max_supported_event = OCXL_AFU_EVENT_XSL_FAULT_ERROR;
273320
break;
274321
default:
275-
errmsg(afu, OCXL_INTERNAL_ERROR, "Unknown maximum supported event type %u", max_supported_event);
322+
errmsg(afu, OCXL_INTERNAL_ERROR, "Unsupported event API version %u, your libocxl library may be too old",
323+
event_api_version);
276324
return OCXL_EVENT_ACTION_FAIL;
277325
}
278326

279327
char buf[event_size];
280328

281329
int buf_used;
282-
if ((buf_used = read(afu->fd, buf, event_size)) < 0) {
330+
if ((buf_used = read(my_afu->fd, buf, event_size)) < 0) {
283331
if (errno == EAGAIN || errno == EWOULDBLOCK) {
332+
*last = 1;
284333
return OCXL_EVENT_ACTION_NONE;
285334
}
286335

287336
errmsg(afu, OCXL_INTERNAL_ERROR, "read of event header from fd %d for AFU '%s' failed: %d: %s",
288-
afu->fd, afu->identifier.afu_name, errno, strerror(errno));
337+
my_afu->fd, my_afu->identifier.afu_name, errno, strerror(errno));
289338
return OCXL_EVENT_ACTION_FAIL;
290339
} else if (buf_used < sizeof(ocxl_kernel_event_header)) {
291340
errmsg(afu, OCXL_INTERNAL_ERROR, "short read of event header from fd %d for AFU '%s'",
292-
afu->fd, afu->identifier.afu_name);
341+
my_afu->fd, my_afu->identifier.afu_name);
293342
return OCXL_EVENT_ACTION_FAIL;
294343
}
295344

296345
ocxl_kernel_event_header *header = (ocxl_kernel_event_header *)buf;
297346

298347
if (header->type > max_supported_event) {
299-
TRACE(afu, "Unknown event received from kernel of type %u", header->type);
348+
TRACE(my_afu, "Unknown event received from kernel of type %u", header->type);
300349
*last = !! (header->flags & OCXL_KERNEL_EVENT_FLAG_LAST);
301350
return OCXL_EVENT_ACTION_IGNORE;
302351
}
303352

304353
switch (header->type) {
305354
case OCXL_AFU_EVENT_XSL_FAULT_ERROR:
306355
if (buf_used != sizeof(ocxl_kernel_event_header) + sizeof(ocxl_kernel_event_xsl_fault_error)) {
307-
errmsg(afu, OCXL_INTERNAL_ERROR,
356+
errmsg(my_afu, OCXL_INTERNAL_ERROR,
308357
"Incorrectly sized buffer received from kernel for XSL fault error, expected %d, got %d",
309358
sizeof(ocxl_kernel_event_header) + sizeof(ocxl_kernel_event_xsl_fault_error),
310359
buf_used);
@@ -314,7 +363,7 @@ static ocxl_event_action read_afu_event(ocxl_afu *afu, uint16_t max_supported_ev
314363
break;
315364

316365
default:
317-
errmsg(afu, OCXL_INTERNAL_ERROR, "Unknown event %d, max_supported_event %d",
366+
errmsg(my_afu, OCXL_INTERNAL_ERROR, "Unknown event %d, max_supported_event %d",
318367
header->type, max_supported_event);
319368
return OCXL_EVENT_ACTION_FAIL;
320369
}
@@ -323,7 +372,6 @@ static ocxl_event_action read_afu_event(ocxl_afu *afu, uint16_t max_supported_ev
323372
return OCXL_EVENT_ACTION_SUCCESS;
324373
}
325374

326-
327375
/**
328376
* Check for pending IRQs and other events
329377
*
@@ -340,19 +388,6 @@ int ocxl_afu_event_check_versioned(ocxl_afu_h afu, int timeout, ocxl_event *even
340388
uint16_t event_api_version)
341389
{
342390
ocxl_afu *my_afu = (ocxl_afu *) afu;
343-
uint16_t max_supported_event;
344-
345-
switch (event_api_version) {
346-
case 0:
347-
max_supported_event = OCXL_AFU_EVENT_XSL_FAULT_ERROR;
348-
break;
349-
350-
default:
351-
errmsg(my_afu, OCXL_INTERNAL_ERROR, "Unsupported event API version %u, your libocxl library may be too old",
352-
event_api_version);
353-
return -1;
354-
}
355-
356391
TRACE(my_afu, "Waiting up to %dms for AFU events", timeout);
357392

358393
if (event_count > my_afu->epoll_event_count) {
@@ -382,11 +417,11 @@ int ocxl_afu_event_check_versioned(ocxl_afu_h afu, int timeout, ocxl_event *even
382417
epoll_fd_source *info = (epoll_fd_source *)my_afu->epoll_events[event].data.ptr;
383418
ocxl_event_action ret;
384419
uint64_t count;
385-
bool last;
420+
int last;
386421

387422
switch (info->type) {
388423
case EPOLL_SOURCE_OCXL:
389-
while ((ret = read_afu_event(my_afu, max_supported_event, &events[triggered], &last)),
424+
while ((ret = read_afu_event(my_afu, event_api_version, &events[triggered], &last)),
390425
ret == OCXL_EVENT_ACTION_SUCCESS || ret == OCXL_EVENT_ACTION_IGNORE) {
391426
if (ret == OCXL_EVENT_ACTION_SUCCESS) {
392427
triggered++;

src/libocxl_internal.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ typedef struct ocxl_irq ocxl_irq;
9494

9595
/**
9696
* @internal
97+
*
98+
* The type of action to be taken upon return from the ocxl_read_afu_event() function
99+
*/
100+
typedef enum ocxl_event_action {
101+
OCXL_EVENT_ACTION_SUCCESS, /**< The event read was successful and should be handled */
102+
OCXL_EVENT_ACTION_FAIL, /**< The event read failed */
103+
OCXL_EVENT_ACTION_NONE, /**< There was no event to read */
104+
OCXL_EVENT_ACTION_IGNORE, /**< The event read was successful, but should be ignored */
105+
} ocxl_event_action;
106+
107+
108+
/**
109+
* @internal
110+
*
97111
* Metadata for determining which source triggered an epoll fd
98112
*/
99113
typedef struct epoll_fd_source {
@@ -108,6 +122,7 @@ typedef struct epoll_fd_source {
108122

109123
/**
110124
* @internal
125+
*
111126
* AFU IRQ information
112127
*/
113128
struct ocxl_irq {
@@ -122,6 +137,7 @@ struct ocxl_irq {
122137

123138
/**
124139
* @internal
140+
*
125141
* Represents an AFU
126142
*/
127143
struct ocxl_afu {
@@ -160,17 +176,6 @@ struct ocxl_afu {
160176
#endif
161177
};
162178

163-
/**
164-
* @internal
165-
* The type of action of the read_afu_event() function
166-
*/
167-
typedef enum ocxl_event_action {
168-
OCXL_EVENT_ACTION_SUCCESS, /**< The event read was successful and should be handled */
169-
OCXL_EVENT_ACTION_FAIL, /**< The event read failed */
170-
OCXL_EVENT_ACTION_NONE, /**< There was no event to read */
171-
OCXL_EVENT_ACTION_IGNORE, /**< The event read was successful, but should be ignored */
172-
} ocxl_event_action;
173-
174179
void irq_dealloc(ocxl_afu * afu, ocxl_irq * irq);
175180

176181
#endif /* _LIBOCXL_INTERNAL_H */

symver.map

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ LIBOCXL_0 {
1919
ocxl_afu_open_specific;
2020
ocxl_afu_attach;
2121
ocxl_afu_irq_alloc;
22-
ocxl_afu_irq_get_handle;
22+
ocxl_afu_irq_get_handle;
2323
ocxl_afu_get_event_fd;
24-
ocxl_afu_event_check;
24+
ocxl_afu_irq_get_descriptor;
25+
ocxl_afu_get_event_descriptor;
2526
ocxl_afu_event_check_versioned;
2627
ocxl_afu_set_ppc64_amr;
2728
ocxl_mmio_map;

unittests/unittests.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static void test_read_afu_event() {
839839

840840
ocxl_afu * my_afu = (ocxl_afu *)afu;
841841
ocxl_event event;
842-
bool last = false;
842+
int last = 0;
843843
ASSERT(OCXL_EVENT_ACTION_NONE == read_afu_event(my_afu, 0, &event, &last));
844844
ASSERT(last);
845845

@@ -849,7 +849,7 @@ static void test_read_afu_event() {
849849
force_translation_fault((void *)0xfeeddeadbeeff00d, 16);
850850
#endif
851851

852-
last = false;
852+
last = 0;
853853
ASSERT(OCXL_EVENT_ACTION_SUCCESS == read_afu_event(my_afu, 0, &event, &last));
854854
ASSERT(last);
855855
ASSERT(event.type == OCXL_EVENT_TRANSLATION_FAULT);
@@ -865,7 +865,7 @@ static void test_read_afu_event() {
865865
force_translation_fault((void *)0xfeeddeadbeeff00d, 16);
866866
#endif
867867

868-
last = false;
868+
last = 0;
869869
ASSERT(OCXL_EVENT_ACTION_SUCCESS == read_afu_event(my_afu, 0, &event, &last));
870870
ASSERT(last);
871871
ASSERT(event.type == OCXL_EVENT_TRANSLATION_FAULT);
@@ -875,7 +875,7 @@ static void test_read_afu_event() {
875875
#endif
876876
ASSERT(event.translation_fault.count == 16);
877877

878-
last = false;
878+
last = 0;
879879
ASSERT(OCXL_EVENT_ACTION_NONE == read_afu_event(my_afu, 0, &event, &last));
880880
ASSERT(last);
881881

0 commit comments

Comments
 (0)