rogue
Loading...
Searching...
No Matches
Core.cpp
Go to the documentation of this file.
1
17#include "rogue/Directives.h"
18
20
21#include <infiniband/verbs.h>
22#include <stdint.h>
23
24#include <cstring>
25#include <string>
26
27#include "rogue/GeneralError.h"
28
30
31#ifndef NO_PYTHON
32 #include <boost/python.hpp>
33namespace bp = boost::python;
34#endif
35
37rpr::Core::Core(const std::string& deviceName,
38 uint8_t ibPort,
39 uint8_t gidIndex,
40 uint32_t maxPayload)
41 : ctx_(nullptr),
42 pd_(nullptr),
43 deviceName_(deviceName),
44 ibPort_(ibPort),
45 gidIndex_(gidIndex),
46 maxPayload_(maxPayload) {
47
48 log_ = rogue::Logging::create("rocev2.Core");
49
50 // -----------------------------------------------------------------------
51 // 1. Find and open the requested ibverbs device
52 // devList is freed on every exit path (success and failure) so a
53 // partial-construction throw never leaks the device list.
54 // -----------------------------------------------------------------------
55 int numDevices = 0;
56 struct ibv_device** devList = ibv_get_device_list(&numDevices);
57 if (!devList || numDevices == 0) {
58 if (devList) ibv_free_device_list(devList);
59 throw(rogue::GeneralError::create("rocev2::Core::Core",
60 "No RDMA devices found on this host"));
61 }
62
63 struct ibv_device* dev = nullptr;
64 for (int i = 0; i < numDevices; ++i) {
65 if (deviceName_ == ibv_get_device_name(devList[i])) {
66 dev = devList[i];
67 break;
68 }
69 }
70
71 if (!dev) {
72 ibv_free_device_list(devList);
73 throw(rogue::GeneralError::create("rocev2::Core::Core",
74 "RDMA device '%s' not found",
75 deviceName_.c_str()));
76 }
77
78 ctx_ = ibv_open_device(dev);
79 ibv_free_device_list(devList);
80
81 if (!ctx_)
82 throw(rogue::GeneralError::create("rocev2::Core::Core",
83 "Failed to open RDMA device '%s'",
84 deviceName_.c_str()));
85
86 // -----------------------------------------------------------------------
87 // 2. Allocate Protection Domain
88 // On failure we close ctx_ explicitly: the destructor does not run on
89 // a partially-constructed object, so without this the context would
90 // leak.
91 // -----------------------------------------------------------------------
92 pd_ = ibv_alloc_pd(ctx_);
93 if (!pd_) {
94 ibv_close_device(ctx_);
95 ctx_ = nullptr;
96 throw(rogue::GeneralError::create("rocev2::Core::Core",
97 "Failed to allocate protection domain"));
98 }
99
100 log_->info("Opened RoCEv2 device '%s', port %u, GID index %u",
101 deviceName_.c_str(), ibPort_, gidIndex_);
102}
103
105//
106// CQ / QP / MR are owned by the derived Server class and are torn down in
107// Server::stop() before the inherited Core destructor runs.
108rpr::Core::~Core() {
109 if (pd_) ibv_dealloc_pd(pd_);
110 if (ctx_) ibv_close_device(ctx_);
111}
112
113void rpr::Core::setup_python() {
114#ifndef NO_PYTHON
115 bp::class_<rpr::Core, rpr::CorePtr, boost::noncopyable>("Core", bp::no_init)
116 .def("maxPayload", &rpr::Core::maxPayload);
117
118 // Expose defaults as module-level attributes:
119 // rogue.protocols.rocev2.DefaultMaxPayload
120 // rogue.protocols.rocev2.DefaultRxQueueDepth
121 bp::scope().attr("DefaultMaxPayload") = rpr::DefaultMaxPayload;
122 bp::scope().attr("DefaultRxQueueDepth") = rpr::DefaultRxQueueDepth;
123#endif
124}
static GeneralError create(std::string src, const char *fmt,...)
Creates a formatted error instance.
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:95
std::shared_ptr< rogue::Logging > log_
Definition Core.h:55
struct ibv_pd * pd_
Definition Core.h:47
struct ibv_context * ctx_
Definition Core.h:46
static const uint32_t DefaultMaxPayload
Definition Core.h:40
static const uint32_t DefaultRxQueueDepth
Definition Core.h:35