1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 XSKY <haomai@xsky.com>
8 * Author: Haomai Wang <haomaiwang@gmail.com>
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
17 #ifndef CEPH_RDMA_DEVICE_H
18 #define CEPH_RDMA_DEVICE_H
20 #include <infiniband/verbs.h>
25 #include "include/int_types.h"
26 #include "include/page.h"
27 #include "common/debug.h"
28 #include "common/errno.h"
29 #include "msg/msg_types.h"
30 #include "msg/async/net_handler.h"
31 #include "common/Mutex.h"
32 #include "msg/async/Event.h"
34 typedef Infiniband::QueuePair QueuePair
;
35 typedef Infiniband::CompletionChannel CompletionChannel
;
36 typedef Infiniband::CompletionQueue CompletionQueue
;
37 typedef Infiniband::ProtectionDomain ProtectionDomain
;
38 typedef Infiniband::MemoryManager::Cluster Cluster
;
39 typedef Infiniband::MemoryManager::Chunk Chunk
;
40 typedef Infiniband::MemoryManager MemoryManager
;
43 struct ibv_context
* ctxt
;
45 struct ibv_port_attr
* port_attr
;
51 explicit Port(CephContext
*cct
, struct ibv_context
* ictxt
, uint8_t ipn
);
53 uint16_t get_lid() { return lid
; }
54 ibv_gid
get_gid() { return gid
; }
55 int get_port_num() { return port_num
; }
56 ibv_port_attr
* get_port_attr() { return port_attr
; }
57 int get_gid_idx() { return gid_idx
; }
62 class C_handle_cq_async
: public EventCallback
{
65 C_handle_cq_async(Device
*d
): device(d
) {}
66 void do_request(int fd
) {
67 device
->handle_async_event();
75 Port
**ports
; // Array of Port objects. index is 1 based (IB port #1 is in
76 // index 1). Index 0 is not used
84 Mutex lock
; // Protects from concurrent intialization of the device
85 bool initialized
= false;
86 EventCallbackRef async_handler
;
87 Infiniband
*infiniband
;
89 void verify_port(int port_num
);
92 explicit Device(CephContext
*c
, Infiniband
*ib
, ibv_device
* d
);
95 void init(int ibport
= -1);
98 void handle_async_event();
100 const char* get_name() const { return name
;}
102 Port
*get_port(int ibport
);
103 uint16_t get_lid(int p
) { return get_port(p
)->get_lid(); }
104 ibv_gid
get_gid(int p
) { return get_port(p
)->get_gid(); }
105 int get_gid_idx(int p
) { return get_port(p
)->get_gid_idx(); }
107 QueuePair
*create_queue_pair(int port
,
109 ibv_srq
* create_shared_receive_queue(uint32_t max_wr
, uint32_t max_sge
);
110 CompletionChannel
*create_comp_channel(CephContext
*c
);
111 CompletionQueue
*create_comp_queue(CephContext
*c
, CompletionChannel
*cc
=NULL
);
112 int post_chunk(Chunk
* chunk
);
113 int post_channel_cluster();
115 MemoryManager
* get_memory_manager() { return memory_manager
; }
116 bool is_tx_buffer(const char* c
) { return memory_manager
->is_tx_buffer(c
);}
117 bool is_rx_buffer(const char* c
) { return memory_manager
->is_rx_buffer(c
);}
118 Chunk
*get_tx_chunk_by_buffer(const char *c
) { return memory_manager
->get_tx_chunk_by_buffer(c
); }
119 int get_tx_buffers(std::vector
<Chunk
*> &c
, size_t bytes
);
120 int poll_tx_cq(int n
, ibv_wc
*wc
);
121 int poll_rx_cq(int n
, ibv_wc
*wc
);
124 struct ibv_context
*ctxt
;
125 ibv_device_attr
*device_attr
;
127 MemoryManager
* memory_manager
= nullptr;
128 ibv_srq
*srq
= nullptr;
129 Infiniband::CompletionQueue
*rx_cq
= nullptr;
130 Infiniband::CompletionChannel
*rx_cc
= nullptr;
131 Infiniband::CompletionQueue
*tx_cq
= nullptr;
132 Infiniband::CompletionChannel
*tx_cc
= nullptr;
133 ProtectionDomain
*pd
= nullptr;
136 inline ostream
& operator<<(ostream
& out
, const Device
&d
)
138 return out
<< d
.get_name();
144 struct ibv_device
** device_list
;
148 unsigned last_poll_dev
= 0;
149 struct pollfd
*poll_fds
;
152 DeviceList(CephContext
*cct
, Infiniband
*ib
);
155 Device
* get_device(const char* device_name
);
156 Device
* get_device(const struct ibv_context
*ctxt
);
161 int poll_tx(int n
, Device
**d
, ibv_wc
*wc
);
162 int poll_rx(int n
, Device
**d
, ibv_wc
*wc
);
163 int poll_blocking(bool &done
);
165 void handle_async_event();