Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mi: Introduce asynchronous event message handling #967

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

chorkin
Copy link
Contributor

@chorkin chorkin commented Mar 4, 2025

Added new functionality to mi.c and mi-mctp.c to handle AEMs. Included new example mi-mctp-ae.c for usage.

@chorkin
Copy link
Contributor Author

chorkin commented Mar 4, 2025

@jk-ozlabs, there's something funky going on with the existing mi-mctp tests. I was hoping you might shed some light here. Also looking for guidance on how we can add new tests to handle these changes.

@chorkin
Copy link
Contributor Author

chorkin commented Mar 4, 2025

@igaw, it seems we have build checks that have been added since the last time I upstreamed something. But they're all failing for me here. Any guidance you can provide?

Added new functionality to mi.c and mi-mctp.c to handle AEMs.  Included
new example mi-mctp-ae.c for usage.

Signed-off-by: Chuck Horkin <[email protected]>
@chorkin chorkin force-pushed the user/chorkin/aem_work_upstream branch from ac53516 to 90ad63d Compare March 4, 2025 00:23
goto cleanup_get_info;
}
//Need to send a AEM Sync to enable things
#ifndef TEST_CODE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jk-ozlabs , I plan to remove this code, but was going to keep it in if it was somehow useful for testing purposes and we could reuse it somewhere else. I'll delete or move pending other comments I get.


/* POLLIN has indicated events, notify libnvme. Will likely result in
* one (or more) of the struct nvme_mi_aem_callbacks being invoked.
* NOTE: WE NEED TO LOOK AT AEM GENERATION NUMBER HERE. See AEMTI
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

};

LIBNVME_MI_1_11 {
global:
nvme_mi_control;
nvme_mi_get_async_message;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake and should be removed

pollfds[0].events = POLLIN;
timeout = 1;//1?
retry:
rc = ops.poll(pollfds, 1, timeout);//This is probably unecessary
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment. Same for //1? above

@@ -429,11 +486,6 @@ int nvme_mi_submit(nvme_mi_ep_t ep, struct nvme_mi_req *req,
return -1;
}

if (req->data_len & 0x3) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jk-ozlabs , correct me if I'm wrong, but this check should only be applicable to admin commands and is actually causing problems with AEM SYNC (Configuration Set: AEM) for some data lengths. Didn't want it to slip under the radar.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to this point, all MI messages have been a multiple of 4 bytes. If that's changing, we can reconsider this check.

@jk-ozlabs
Copy link
Collaborator

Neat, I'll take a look!

@jk-ozlabs
Copy link
Collaborator

I think the overall concept here is sound, but we are missing a few implementation details for an overall feasibility check too. There are some style things, but we can address those once the general framework is settled. I have added some comments in a review.

I've been thinking about how we should be handling the multiple-endpoint cases, as we can only have one socket listening on incoming NVMe-MI message types. A couple of options there:

  • a shared socket for all AEM events on all endpoints (eg, on the nvme_mi_root_t), where a call to fetch AEM events on any enpoint will receive all events, and queue those that are not for the current. A subsequent call for any other endpoints would first check that queue before receiving more directly from the socket

or:

  • we add socket syscall semantics for AF_MCTP, to specify the remote MCTP EID on the listening socket, and stick with one per nvme_mi_ep_t. this would require kernel changes, but I think that's probably a common use-case that would be good to support.

I figure the latter is probably best, so will take a look at what's required for that.

pollfds[0].events = POLLIN;
timeout = 1;//1?
retry:
rc = ops.poll(pollfds, 1, timeout);//This is probably unecessary
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, no need for the poll here. If we have the fd in non-blocking mode, just do the recvmsg directly (and handle the EAGAIN)

return 0;
}

static int nvme_mi_mctp_read(struct nvme_mi_ep *ep,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want a name that indicates that this is for the aem messaging.

Comment on lines +3337 to +3338
Ack,
None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want better namespacing on these, and consistent SCREAMING_SNAKE_CASE

*
* Return: -1 if error, 0 otherwise
*/
int nvme_mi_get_pollfd(nvme_mi_ep_t ep, struct pollfd *fs);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if we want the struct pollfd or just the int fd returned here. Any specific reason for the pollfd?

Comment on lines +641 to +642
.async_read = nvme_mi_mctp_read,
.async_poll_fd = nvme_mi_mctp_async_poll_fd,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only a minor naming convention, but we probably want to be careful between the terms async (as an IO-handling pattern) and "Async Event Messaging" (as the NVMe-MI facility). I would suggest using aem consistently here.

std_in_timeout.tv_usec = 0;

// Check if there's input on stdin
retval = select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &std_in_timeout);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just include STDIN_FILENO on the set that you're polling on

@jk-ozlabs
Copy link
Collaborator

(BTW, I would suggest converting to a draft while still working out details)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants