]> git.proxmox.com Git - ceph.git/blob - ceph/src/msg/async/dpdk/dpdk_rte.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / msg / async / dpdk / dpdk_rte.cc
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18
19 #include <rte_config.h>
20 #include <rte_common.h>
21 #include <rte_ethdev.h>
22 #include <rte_version.h>
23
24 #include "DPDK.h"
25 #include "dpdk_rte.h"
26
27 namespace dpdk {
28
29 static inline std::vector<char> string2vector(std::string str) {
30 auto v = std::vector<char>(str.begin(), str.end());
31 v.push_back('\0');
32 return v;
33 }
34
35 bool eal::initialized = false;
36 std::thread eal::t;
37 std::mutex eal::lock;
38 std::condition_variable eal::cond;
39 std::list<std::function<void()>> eal::funcs;
40
41 static int bitcount(unsigned n)
42 {
43 unsigned int c =0 ;
44 for (c = 0; n; ++c)
45 n &= (n -1);
46 return c;
47 }
48
49 int eal::init(CephContext *c)
50 {
51 if (initialized) {
52 return 1;
53 }
54
55 bool done = false;
56 t = std::thread([&]() {
57 // TODO: Inherit these from the app parameters - "opts"
58 std::vector<std::vector<char>> args {
59 string2vector(string("ceph")),
60 string2vector("-c"), string2vector(c->_conf->get_val<std::string>("ms_dpdk_coremask")),
61 string2vector("-n"), string2vector(c->_conf->ms_dpdk_memory_channel),
62 };
63
64 Tub<std::string> hugepages_path;
65 if (!c->_conf->ms_dpdk_hugepages.empty()) {
66 hugepages_path.construct(c->_conf->ms_dpdk_hugepages);
67 }
68
69 // If "hugepages" is not provided and DPDK PMD drivers mode is requested -
70 // use the default DPDK huge tables configuration.
71 if (hugepages_path) {
72 args.push_back(string2vector("--huge-dir"));
73 args.push_back(string2vector(*hugepages_path));
74
75 //
76 // We don't know what is going to be our networking configuration so we
77 // assume there is going to be a queue per-CPU. Plus we'll give a DPDK
78 // 64MB for "other stuff".
79 //
80 unsigned int x;
81 std::stringstream ss;
82 ss << std::hex << "fffefffe";
83 ss >> x;
84 size_t size_MB = mem_size(bitcount(x)) >> 20;
85 std::stringstream size_MB_str;
86 size_MB_str << size_MB;
87
88 args.push_back(string2vector("-m"));
89 args.push_back(string2vector(size_MB_str.str()));
90 } else if (!c->_conf->ms_dpdk_pmd.empty()) {
91 args.push_back(string2vector("--no-huge"));
92 }
93
94 std::string rte_file_prefix;
95 rte_file_prefix = "rte_";
96 rte_file_prefix += c->_conf->name.to_str();
97 args.push_back(string2vector("--file-prefix"));
98 args.push_back(string2vector(rte_file_prefix));
99
100 std::vector<char*> cargs;
101
102 for (auto&& a: args) {
103 cargs.push_back(a.data());
104 }
105 /* initialise the EAL for all */
106 int ret = rte_eal_init(cargs.size(), cargs.data());
107 if (ret < 0)
108 return ret;
109
110 std::unique_lock<std::mutex> l(lock);
111 initialized = true;
112 done = true;
113 cond.notify_all();
114 while (true) {
115 if (!funcs.empty()) {
116 auto f = std::move(funcs.front());
117 funcs.pop_front();
118 f();
119 cond.notify_all();
120 } else {
121 cond.wait(l);
122 }
123 }
124 });
125 t.detach();
126 std::unique_lock<std::mutex> l(lock);
127 while (!done)
128 cond.wait(l);
129 return 0;
130 }
131
132 size_t eal::mem_size(int num_cpus)
133 {
134 size_t memsize = 0;
135 //
136 // PMD mempool memory:
137 //
138 // We don't know what is going to be our networking configuration so we
139 // assume there is going to be a queue per-CPU.
140 //
141 memsize += num_cpus * qp_mempool_obj_size();
142
143 // Plus we'll give a DPDK 64MB for "other stuff".
144 memsize += (64UL << 20);
145
146 return memsize;
147 }
148
149 } // namespace dpdk