RDMA++
Loading...
Searching...
No Matches
qp.h
1#pragma once
2
3#include <atomic>
4#include <coroutine>
5#include <cstdint>
6#include <exception>
7#include <memory>
8#include <optional>
9#include <utility>
10#include <vector>
11
12#include <infiniband/verbs.h>
13
14#include "rdmapp/cq.h"
15#include "rdmapp/device.h"
16#include "rdmapp/pd.h"
17#include "rdmapp/srq.h"
18
19#include "rdmapp/detail/noncopyable.h"
20#include "rdmapp/detail/serdes.h"
21
22namespace rdmapp {
23
25 struct qp_header {
26 static constexpr size_t kSerializedSize =
27 sizeof(uint16_t) + 3 * sizeof(uint32_t) + sizeof(union ibv_gid);
28 uint16_t lid;
29 uint32_t qp_num;
30 uint32_t sq_psn;
31 uint32_t user_data_size;
32 union ibv_gid gid;
33 } header;
34 template <class It> static deserialized_qp deserialize(It it) {
35 deserialized_qp des_qp;
36 detail::deserialize(it, des_qp.header.lid);
37 detail::deserialize(it, des_qp.header.qp_num);
38 detail::deserialize(it, des_qp.header.sq_psn);
39 detail::deserialize(it, des_qp.header.user_data_size);
40 detail::deserialize(it, des_qp.header.gid);
41 return des_qp;
42 }
43 std::vector<uint8_t> user_data;
44};
45
50class qp : public noncopyable, public std::enable_shared_from_this<qp> {
51 static std::atomic<uint32_t> next_sq_psn;
52 struct ibv_qp *qp_;
53 struct ibv_srq *raw_srq_;
54 uint32_t sq_psn_;
55 void (qp::*post_recv_fn)(struct ibv_recv_wr const &recv_wr,
56 struct ibv_recv_wr *&bad_recv_wr) const;
57
58 std::shared_ptr<pd> pd_;
59 std::shared_ptr<cq> recv_cq_;
60 std::shared_ptr<cq> send_cq_;
61 std::shared_ptr<srq> srq_;
62 std::vector<uint8_t> user_data_;
63
68 void create();
69
75 void init();
76
77 void destroy();
78
79public:
81 std::shared_ptr<qp> qp_;
82 std::shared_ptr<local_mr> local_mr_;
83 std::exception_ptr exception_;
84 remote_mr remote_mr_;
85 uint64_t compare_add_;
86 uint64_t swap_;
87 uint32_t imm_;
88 struct ibv_wc wc_;
89 const enum ibv_wr_opcode opcode_;
90
91 public:
92 send_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length,
93 enum ibv_wr_opcode opcode);
94 send_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length,
95 enum ibv_wr_opcode opcode, remote_mr const &remote_mr);
96 send_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length,
97 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
98 uint32_t imm);
99 send_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length,
100 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
101 uint64_t add);
102 send_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length,
103 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
104 uint64_t compare, uint64_t swap);
105 send_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr,
106 enum ibv_wr_opcode opcode);
107 send_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr,
108 enum ibv_wr_opcode opcode, remote_mr const &remote_mr);
109 send_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr,
110 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
111 uint32_t imm);
112 send_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr,
113 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
114 uint64_t add);
115 send_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr,
116 enum ibv_wr_opcode opcode, remote_mr const &remote_mr,
117 uint64_t compare, uint64_t swap);
118 bool await_ready() const noexcept;
119 bool await_suspend(std::coroutine_handle<> h) noexcept;
120 uint32_t await_resume() const;
121 constexpr bool is_rdma() const;
122 constexpr bool is_atomic() const;
123 };
124
126 std::shared_ptr<qp> qp_;
127 std::shared_ptr<local_mr> local_mr_;
128 std::exception_ptr exception_;
129 struct ibv_wc wc_;
130 enum ibv_wr_opcode opcode_;
131
132 public:
133 recv_awaitable(std::shared_ptr<qp> qp, std::shared_ptr<local_mr> local_mr);
134 recv_awaitable(std::shared_ptr<qp> qp, void *buffer, size_t length);
135 bool await_ready() const noexcept;
136 bool await_suspend(std::coroutine_handle<> h) noexcept;
137 std::pair<uint32_t, std::optional<uint32_t>> await_resume() const;
138 };
139
153 qp(const uint16_t remote_lid, const uint32_t remote_qpn,
154 const uint32_t remote_psn, const union ibv_gid remote_gid,
155 std::shared_ptr<pd> pd, std::shared_ptr<cq> cq,
156 std::shared_ptr<srq> srq = nullptr);
157
172 qp(const uint16_t remote_lid, const uint32_t remote_qpn,
173 const uint32_t remote_psn, const union ibv_gid remote_gid,
174 std::shared_ptr<pd> pd, std::shared_ptr<cq> recv_cq,
175 std::shared_ptr<cq> send_cq, std::shared_ptr<srq> srq = nullptr);
176
186 qp(std::shared_ptr<pd> pd, std::shared_ptr<cq> cq,
187 std::shared_ptr<srq> srq = nullptr);
188
199 qp(std::shared_ptr<pd> pd, std::shared_ptr<cq> recv_cq,
200 std::shared_ptr<cq> send_cq, std::shared_ptr<srq> srq = nullptr);
201
209 void post_send(struct ibv_send_wr const &send_wr,
210 struct ibv_send_wr *&bad_send_wr);
211
221 void post_recv(struct ibv_recv_wr const &recv_wr,
222 struct ibv_recv_wr *&bad_recv_wr) const;
223
232 [[nodiscard]] send_awaitable send(void *buffer, size_t length);
233
244 [[nodiscard]] send_awaitable write(remote_mr const &remote_mr, void *buffer,
245 size_t length);
246
259 void *buffer, size_t length,
260 uint32_t imm);
261
272 [[nodiscard]] send_awaitable read(remote_mr const &remote_mr, void *buffer,
273 size_t length);
274
286 [[nodiscard]] send_awaitable fetch_and_add(remote_mr const &remote_mr,
287 void *buffer, size_t length,
288 uint64_t add);
289
303 void *buffer, size_t length,
304 uint64_t compare,
305 uint64_t swap);
306
317 [[nodiscard]] recv_awaitable recv(void *buffer, size_t length);
318
326 [[nodiscard]] send_awaitable send(std::shared_ptr<local_mr> local_mr);
327
336 [[nodiscard]] send_awaitable write(remote_mr const &remote_mr,
337 std::shared_ptr<local_mr> local_mr);
338
349 [[nodiscard]] send_awaitable
350 write_with_imm(remote_mr const &remote_mr, std::shared_ptr<local_mr> local_mr,
351 uint32_t imm);
352
361 [[nodiscard]] send_awaitable read(remote_mr const &remote_mr,
362 std::shared_ptr<local_mr> local_mr);
363
374 [[nodiscard]] send_awaitable fetch_and_add(remote_mr const &remote_mr,
375 std::shared_ptr<local_mr> local_mr,
376 uint64_t add);
377
389 [[nodiscard]] send_awaitable
391 std::shared_ptr<local_mr> local_mr, uint64_t compare,
392 uint64_t swap);
393
404 [[nodiscard]] recv_awaitable recv(std::shared_ptr<local_mr> local_mr);
405
412 std::vector<uint8_t> serialize() const;
413
420 std::vector<uint8_t> &user_data();
421
428 std::shared_ptr<pd> pd_ptr() const;
429 ~qp();
430
439 void rtr(uint16_t remote_lid, uint32_t remote_qpn, uint32_t remote_psn,
440 union ibv_gid remote_gid);
441
446 void rts();
447
448private:
455 void post_recv_rq(struct ibv_recv_wr const &recv_wr,
456 struct ibv_recv_wr *&bad_recv_wr) const;
457
464 void post_recv_srq(struct ibv_recv_wr const &recv_wr,
465 struct ibv_recv_wr *&bad_recv_wr) const;
466};
467
468} // namespace rdmapp
469
This class is an abstraction of a Completion Queue.
Definition cq.h:22
Represents a local memory region.
Definition mr.h:34
Represents a remote memory region.
Definition mr.h:108
Definition noncopyable.h:5
This class is an abstraction of a Protection Domain.
Definition pd.h:20
Definition qp.h:125
Definition qp.h:80
This class is an abstraction of an Infiniband Queue Pair.
Definition qp.h:50
void post_recv(struct ibv_recv_wr const &recv_wr, struct ibv_recv_wr *&bad_recv_wr) const
This function is used to post a recv work request to the Queue Pair. It will be posted to either RQ o...
Definition qp.cc:194
void post_send(struct ibv_send_wr const &send_wr, struct ibv_send_wr *&bad_send_wr)
This function is used to post a send work request to the Queue Pair.
Definition qp.cc:184
send_awaitable compare_and_swap(remote_mr const &remote_mr, void *buffer, size_t length, uint64_t compare, uint64_t swap)
This method performs an atomic compare-and-swap operation on the given remote memory region....
Definition qp.cc:379
recv_awaitable recv(void *buffer, size_t length)
This method posts a recv request on the queue pair. The buffer will be filled with data received....
Definition qp.cc:475
std::vector< uint8_t > serialize() const
This function serializes a Queue Pair prepared to be sent to a buffer.
Definition qp.cc:64
send_awaitable fetch_and_add(remote_mr const &remote_mr, void *buffer, size_t length, uint64_t add)
This method performs an atomic fetch-and-add operation on the given remote memory region....
Definition qp.cc:372
send_awaitable write(remote_mr const &remote_mr, void *buffer, size_t length)
This method writes local buffer to a remote memory region. The local buffer will be registered as a m...
Definition qp.cc:354
send_awaitable write_with_imm(remote_mr const &remote_mr, void *buffer, size_t length, uint32_t imm)
This method writes local buffer to a remote memory region with an immediate value....
Definition qp.cc:360
void rtr(uint16_t remote_lid, uint32_t remote_qpn, uint32_t remote_psn, union ibv_gid remote_gid)
This function transitions the Queue Pair to the RTR state.
Definition qp.cc:126
send_awaitable send(void *buffer, size_t length)
This method sends local buffer to remote. The address will be registered as a memory region first and...
Definition qp.cc:349
std::vector< uint8_t > & user_data()
This function provides access to the extra user data of the Queue Pair.
Definition qp.cc:60
std::shared_ptr< pd > pd_ptr() const
This function provides access to the Protection Domain of the Queue Pair.
Definition qp.cc:62
send_awaitable read(remote_mr const &remote_mr, void *buffer, size_t length)
This method reads to local buffer from a remote memory region. The local buffer will be registered as...
Definition qp.cc:366
void rts()
This function transitions the Queue Pair to the RTS state.
Definition qp.cc:160
This class represents a Shared Receive Queue.
Definition srq.h:15
Definition qp.h:24