1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* $FreeBSD$
*/
#include <contrib/rdma/ib_verbs.h>
#include <netinet/in.h>
/*
* Krping header stuffs...
*/
struct krping_stats {
unsigned send_bytes;
unsigned send_msgs;
unsigned recv_bytes;
unsigned recv_msgs;
unsigned write_bytes;
unsigned write_msgs;
unsigned read_bytes;
unsigned read_msgs;
};
/*
* These states are used to signal events between the completion handler
* and the main client or server thread.
*
* Once CONNECTED, they cycle through RDMA_READ_ADV, RDMA_WRITE_ADV,
* and RDMA_WRITE_COMPLETE for each ping.
*/
enum test_state {
IDLE = 1,
CONNECT_REQUEST,
ADDR_RESOLVED,
ROUTE_RESOLVED,
CONNECTED,
RDMA_READ_ADV,
RDMA_READ_COMPLETE,
RDMA_WRITE_ADV,
RDMA_WRITE_COMPLETE,
ERROR
};
struct krping_rdma_info {
uint64_t buf;
uint32_t rkey;
uint32_t size;
};
/*
* Control block struct.
*/
struct krping_cb {
int server; /* 0 iff client */
struct ib_cq *cq;
struct ib_pd *pd;
struct ib_qp *qp;
struct ib_mr *dma_mr;
int use_dmamr;
struct ib_recv_wr rq_wr; /* recv work request record */
struct ib_sge recv_sgl; /* recv single SGE */
struct krping_rdma_info recv_buf;/* malloc'd buffer */
struct ib_mr *recv_mr;
struct ib_send_wr sq_wr; /* send work requrest record */
struct ib_sge send_sgl;
struct krping_rdma_info send_buf;/* single send buf */
struct ib_mr *send_mr;
struct ib_send_wr rdma_sq_wr; /* rdma work request record */
struct ib_sge rdma_sgl; /* rdma single SGE */
char *rdma_buf; /* used as rdma sink */
u64 rdma_addr;
struct ib_mr *rdma_mr;
uint32_t remote_rkey; /* remote guys RKEY */
uint64_t remote_addr; /* remote guys TO */
uint32_t remote_len; /* remote guys LEN */
char *start_buf; /* rdma read src */
u64 start_addr;
struct ib_mr *start_mr;
enum test_state state; /* used for cond/signalling */
struct mtx lock;
struct krping_stats stats;
uint16_t port; /* dst port in NBO */
struct in_addr addr; /* dst addr in NBO */
char *addr_str; /* dst addr string */
int verbose; /* verbose logging */
int count; /* ping count */
int size; /* ping data size */
int validate; /* validate ping data */
/* CM stuff */
struct rdma_cm_id *cm_id; /* connection on client side,*/
/* listener on service side. */
struct rdma_cm_id *child_cm_id; /* connection on server side */
TAILQ_ENTRY(krping_cb) list;
int rlat; /* run read latency test */
int wlat; /* run write latency test */
int bw; /* run write bw test */
int duplex; /* run write bw full duplex test */
int poll; /* poll vs block in rlat */
int txdepth;
};
static __inline uint64_t
get_cycles(void)
{
u_int32_t low, high;
__asm __volatile("rdtsc" : "=a" (low), "=d" (high));
return (low | ((u_int64_t)high << 32));
}
#define htonll(x) htobe64((x))
#define ntohll(x) be64toh((x))
typedef uint64_t cycles_t;
extern struct mtx krping_mutex;
TAILQ_HEAD(krping_cb_list, krping_cb);
extern struct krping_cb_list krping_cbs;
int krping_doit(char *cmd);
void krping_init(void);
|