ZBLOG

linux NVMe RDMA的代码案例

以下是一个简单的Linux NVMe RDMA代码案例,用于连接到远程NVMe设备并进行读写操作:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <infiniband/verbs.h>
  7. #define BUFFER_SIZE 4096
  8. int main() {
  9. int nvme_fd;
  10. struct ibv_context *context;
  11. struct ibv_pd *pd;
  12. struct ibv_cq *cq;
  13. struct ibv_qp *qp;
  14. struct ibv_mr *mr;
  15. void *buffer;
  16. // 打开NVMe设备文件
  17. nvme_fd = open("/dev/nvme0n1", O_RDWR | O_DIRECT);
  18. if (nvme_fd == -1) {
  19. perror("Failed to open NVMe device file");
  20. return -1;
  21. }
  22. // 创建InfiniBand上下文
  23. context = ibv_open_device(NULL);
  24. if (context == NULL) {
  25. perror("Failed to open InfiniBand device");
  26. close(nvme_fd);
  27. return -1;
  28. }
  29. // 分配Protection Domain(PD)
  30. pd = ibv_alloc_pd(context);
  31. if (pd == NULL) {
  32. perror("Failed to allocate Protection Domain");
  33. ibv_close_device(context);
  34. close(nvme_fd);
  35. return -1;
  36. }
  37. // 创建完成队列(Completion Queue)
  38. cq = ibv_create_cq(context, 2, NULL, NULL, 0);
  39. if (cq == NULL) {
  40. perror("Failed to create Completion Queue");
  41. ibv_dealloc_pd(pd);
  42. ibv_close_device(context);
  43. close(nvme_fd);
  44. return -1;
  45. }
  46. // 创建队列对(Queue Pair)
  47. struct ibv_qp_init_attr qp_init_attr;
  48. memset(&qp_init_attr, 0, sizeof(qp_init_attr));
  49. qp_init_attr.qp_type = IBV_QPT_RC;
  50. qp_init_attr.send_cq = cq;
  51. qp_init_attr.recv_cq = cq;
  52. qp_init_attr.cap.max_send_wr = 2;
  53. qp_init_attr.cap.max_send_sge = 1;
  54. qp_init_attr.cap.max_recv_wr = 2;
  55. qp_init_attr.cap.max_recv_sge = 1;
  56. qp = ibv_create_qp(pd, &qp_init_attr);
  57. if (qp == NULL) {
  58. perror("Failed to create Queue Pair");
  59. ibv_destroy_cq(cq);
  60. ibv_dealloc_pd(pd);
  61. ibv_close_device(context);
  62. close(nvme_fd);
  63. return -1;
  64. }
  65. // 注册内存缓冲区
  66. buffer = malloc(BUFFER_SIZE);
  67. if (buffer == NULL) {
  68. perror("Failed to allocate memory for buffer");
  69. ibv_destroy_qp(qp);
  70. ibv_destroy_cq(cq);
  71. ibv_dealloc_pd(pd);
  72. ibv_close_device(context);
  73. close(nvme_fd);
  74. return -1;
  75. }
  76. memset(buffer, 0, BUFFER_SIZE);
  77. mr = ibv_reg_mr(pd, buffer, BUFFER_SIZE, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE);
  78. if (mr == NULL) {
  79. perror("Failed to register memory region");
  80. free(buffer);
  81. ibv_destroy_qp(qp);
  82. ibv_destroy_cq(cq);
  83. ibv_dealloc_pd(pd);
  84. ibv_close_device(context);
  85. close(nvme_fd);
  86. return -1;
  87. }
  88. // 进行RDMA操作,例如读取数据到缓冲区
  89. struct ibv_sge sge;
  90. memset(&sge, 0, sizeof(sge));
  91. sge.addr = (uintptr_t)buffer;
  92. sge.length = BUFFER_SIZE;
  93. sge.lkey = mr->lkey;
  94. struct ibv_send_wr send_wr;
  95. memset(&send_wr, 0, sizeof(send_wr));
  96. send_wr.wr_id = 1;
  97. send_wr.sg_list = &sge;
  98. send_wr.num_sge = 1;
  99. send_wr.opcode = IBV_WR_RDMA_READ;
  100. send_wr.send_flags = IBV_SEND_SIGNALED;
  101. struct ibv_send_wr *bad_send_wr;
  102. if (ibv_post_send(qp, &send_wr, &bad_send_wr) != 0) {
  103. perror("Failed to post RDMA READ request");
  104. ibv_dereg_mr(mr);
  105. free(buffer);
  106. ibv_destroy_qp(qp);
  107. ibv_destroy_cq(cq);
  108. ibv_dealloc_pd(pd);
  109. ibv_close_device(context);
  110. close(nvme_fd);
  111. return -1;
  112. }
  113. // 等待RDMA完成
  114. struct ibv_wc wc[2];
  115. if(ibv_poll_cq(cq, 2, wc) <= 0){
  116. perror("Failed to poll completion queue");
  117. }
  118. else{
  119. if(wc[0].status != IBV_WC_SUCCESS){
  120. perror("Error in WR completion status");
  121. }
  122. else{
  123. printf("RDMA Read completed successfully!\n");
  124. // 在buffer中可以找到从NVMe读取的数据
  125. }
  126. }
  127. // 清理资源
  128. ibv_dereg_mr(mr);
  129. free(buffer);
  130. ibv_destroy_qp(qp);
  131. ibv_destroy_cq(cq);
  132. ibv_dealloc_pd(pd);
  133. ibv_close_device(context);
  134. close(nvme_fd);
  135. return 0;
  136. }

这只是一个简单示例,并且假设你已经正确配置了RDMA环境并有权限执行NVMe操作。在实际使用中,你可能需要根据具体情况进行修改。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=3631

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?