Skip to content

Commit 7c402a2

Browse files
committed
mi: Add support for multiple csi buffers
These are used to send up to two concurrent requests over MI to the endpoint. Signed-off-by: Chuck Horkin <[email protected]>
1 parent 526bc01 commit 7c402a2

6 files changed

Lines changed: 97 additions & 6 deletions

File tree

examples/mi-mctp.c

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
#include <stdlib.h>
1818
#include <stddef.h>
1919
#include <string.h>
20+
#include <pthread.h>
2021

2122
#include <libnvme-mi.h>
2223

2324
#include <ccan/array_size/array_size.h>
2425
#include <ccan/endian/endian.h>
26+
#include <bits/pthreadtypes.h>
2527

2628
static void show_port_pcie(struct nvme_mi_read_port_info *port)
2729
{
@@ -375,7 +377,7 @@ int do_get_log_page(nvme_mi_ep_t ep, int argc, char **argv)
375377
{
376378
struct nvme_get_log_args args = { 0 };
377379
struct nvme_mi_ctrl *ctrl;
378-
uint8_t buf[512];
380+
uint8_t buf[4096];
379381
uint16_t ctrl_id;
380382
int rc, tmp;
381383

@@ -421,6 +423,13 @@ int do_get_log_page(nvme_mi_ep_t ep, int argc, char **argv)
421423
return 0;
422424
}
423425

426+
struct thread_struct {
427+
nvme_mi_ep_t ep;
428+
int argc;
429+
char **argv;
430+
int rc;
431+
};
432+
424433
int do_admin_raw(nvme_mi_ep_t ep, int argc, char **argv)
425434
{
426435
struct nvme_mi_admin_req_hdr req;
@@ -513,6 +522,14 @@ int do_admin_raw(nvme_mi_ep_t ep, int argc, char **argv)
513522
return 0;
514523
}
515524

525+
void *csi_thread_helper(void *context)
526+
{
527+
struct thread_struct *s = (struct thread_struct *) context;
528+
529+
s->rc = do_get_log_page(s->ep, s->argc, s->argv);
530+
return NULL;
531+
}
532+
516533
static struct {
517534
uint8_t id;
518535
const char *name;
@@ -729,9 +746,61 @@ enum action {
729746
ACTION_CONFIG_GET,
730747
ACTION_CONFIG_SET,
731748
ACTION_CONTROL_PRIMITIVE,
749+
ACTION_CSI_TEST,
732750
};
733751

734-
static int do_action_endpoint(enum action action, nvme_mi_ep_t ep, int argc, char** argv)
752+
int do_csi_test(nvme_root_t root, nvme_mi_ep_t ep,
753+
int net, __u8 eid, int argc, char **argv)
754+
{
755+
int rc = 0;
756+
nvme_mi_ep_t ep2 = nvme_mi_open_mctp(root, net, eid);
757+
758+
if (!ep2)
759+
errx(EXIT_FAILURE, "can't open MCTP endpoint %d:%d", net, eid);
760+
761+
pthread_t thread;
762+
763+
set_csi(ep, 0);//Not necessary, but to be explicit
764+
set_csi(ep2, 1);
765+
struct thread_struct s;
766+
767+
s.ep = ep2;
768+
s.argc = argc;
769+
s.argv = argv;
770+
771+
// Create a new thread to run my_function
772+
if (pthread_create(&thread, NULL, csi_thread_helper, &s)) {
773+
fprintf(stderr, "Error creating thread\n");
774+
return 1;
775+
}
776+
777+
rc = do_get_log_page(ep, argc, argv);
778+
779+
// Main thread continues to do other work
780+
printf("Main thread finished\n");
781+
782+
// Wait for the created thread to finish
783+
if (pthread_join(thread, NULL)) {
784+
fprintf(stderr, "Error joining thread\n");
785+
return 2;
786+
}
787+
788+
printf("Second thread finished with rc=%d\n", s.rc);
789+
790+
if (rc)
791+
return rc;
792+
if (s.rc)
793+
return s.rc;
794+
return 0;
795+
}
796+
797+
static int do_action_endpoint(enum action action,
798+
nvme_root_t root,
799+
int net,
800+
uint8_t eid,
801+
nvme_mi_ep_t ep,
802+
int argc,
803+
char **argv)
735804
{
736805
int rc;
737806

@@ -763,6 +832,9 @@ static int do_action_endpoint(enum action action, nvme_mi_ep_t ep, int argc, cha
763832
case ACTION_CONTROL_PRIMITIVE:
764833
rc = do_control_primitive(ep, argc, argv);
765834
break;
835+
case ACTION_CSI_TEST:
836+
rc = do_csi_test(root, ep, net, eid, argc, argv);
837+
break;
766838
default:
767839
/* This shouldn't be possible, as we should be covering all
768840
* of the enum action options above. Hoever, keep the compilers
@@ -810,6 +882,7 @@ int main(int argc, char **argv)
810882
" get-config [port]\n"
811883
" set-config <port> <type> <val>\n"
812884
" control-primitive [action(abort|pause|resume|get-state|replay)]\n"
885+
" csi-test\n"
813886
"\n"
814887
" 'dbus' target will query D-Bus for known MCTP endpoints\n"
815888
);
@@ -833,6 +906,8 @@ int main(int argc, char **argv)
833906
action = ACTION_GET_LOG_PAGE;
834907
} else if (!strcmp(action_str, "admin")) {
835908
action = ACTION_ADMIN_RAW;
909+
} else if (!strcmp(action_str, "csi-test")) {
910+
action = ACTION_CSI_TEST;
836911
} else if (!strcmp(action_str, "security-info")) {
837912
action = ACTION_SECURITY_INFO;
838913
} else if (!strcmp(action_str, "get-config")) {
@@ -859,7 +934,7 @@ int main(int argc, char **argv)
859934
nvme_mi_for_each_endpoint(root, ep) {
860935
char *desc = nvme_mi_endpoint_desc(ep);
861936
printf("%s\n", desc);
862-
rc = do_action_endpoint(action, ep, argc, argv);
937+
rc = do_action_endpoint(action, root, net, eid, ep, argc, argv);
863938
printf("---\n");
864939
free(desc);
865940
}
@@ -872,7 +947,7 @@ int main(int argc, char **argv)
872947
ep = nvme_mi_open_mctp(root, net, eid);
873948
if (!ep)
874949
errx(EXIT_FAILURE, "can't open MCTP endpoint %d:%d", net, eid);
875-
rc = do_action_endpoint(action, ep, argc, argv);
950+
rc = do_action_endpoint(action, root, net, eid, ep, argc, argv);
876951
nvme_mi_close(ep);
877952
nvme_mi_free_root(root);
878953
}

src/libnvme-mi.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
LIBNVME_MI_1_14 {
2+
global:
3+
set_csi;
4+
};
5+
16
LIBNVME_MI_1_12 {
27
global:
38
nvme_mi_mi_xfer;

src/nvme/mi-mctp.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ static int nvme_mi_mctp_submit(struct nvme_mi_ep *ep,
337337

338338
rc = -1;
339339
len = ops.recvmsg(mctp->sd, &resp_msg, MSG_DONTWAIT);
340-
341340
if (len < 0) {
342341
errno_save = errno;
343342
nvme_msg(ep->root, LOG_ERR,

src/nvme/mi.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ int nvme_mi_submit(nvme_mi_ep_t ep, struct nvme_mi_req *req,
505505
return 0;
506506
}
507507

508+
void set_csi(nvme_mi_ep_t ep, uint8_t csi)
509+
{
510+
ep->csi = csi & 0b1;
511+
}
512+
508513
static void nvme_mi_admin_init_req(struct nvme_mi_req *req,
509514
struct nvme_mi_admin_req_hdr *hdr,
510515
__u16 ctrl_id, __u8 opcode)
@@ -676,7 +681,9 @@ int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl,
676681

677682
admin_req->hdr.type = NVME_MI_MSGTYPE_NVME;
678683
admin_req->hdr.nmp = (NVME_MI_ROR_REQ << 7) |
679-
(NVME_MI_MT_ADMIN << 3);
684+
(NVME_MI_MT_ADMIN << 3) |
685+
(ctrl->ep->csi & 1);
686+
680687
admin_req->ctrl_id = cpu_to_le16(ctrl->id);
681688
memset(&req, 0, sizeof(req));
682689
req.hdr = &admin_req->hdr;
@@ -929,6 +936,7 @@ static int __nvme_mi_admin_get_log(nvme_mi_ctrl_t ctrl,
929936
ndw = (len >> 2) - 1;
930937

931938
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_get_log_page);
939+
req_hdr.hdr.nmp |= (ctrl->ep->csi & 1);
932940
req_hdr.cdw1 = cpu_to_le32(args->nsid);
933941
req_hdr.cdw10 = cpu_to_le32((ndw & 0xffff) << 16 |
934942
((!final || args->rae) ? 1 : 0) << 15 |

src/nvme/mi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ struct nvme_mi_ep;
478478
*/
479479
typedef struct nvme_mi_ep * nvme_mi_ep_t;
480480

481+
void set_csi(nvme_mi_ep_t ep, uint8_t csi);
482+
481483
/**
482484
* nvme_mi_first_endpoint - Start endpoint iterator
483485
* @m: &nvme_root_t object

src/nvme/private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ struct nvme_mi_ep {
265265
unsigned int mprt_max;
266266
unsigned long quirks;
267267

268+
__u8 csi;
269+
268270
/* inter-command delay, for NVME_QUIRK_MIN_INTER_COMMAND_TIME */
269271
unsigned int inter_command_us;
270272
struct timespec last_resp_time;

0 commit comments

Comments
 (0)