@@ -36,9 +36,12 @@ DEFINE_int32(rdma_memory_pool_initial_size_mb, 1024,
3636 " Initial size of memory pool for RDMA (MB)" );
3737DEFINE_int32 (rdma_memory_pool_increase_size_mb, 1024 ,
3838 " Increased size of memory pool for RDMA (MB)" );
39- DEFINE_int32 (rdma_memory_pool_max_regions, 4 , " Max number of regions" );
39+ DEFINE_int32 (rdma_memory_pool_max_regions, 1 , " Max number of regions" );
4040DEFINE_int32 (rdma_memory_pool_buckets, 4 , " Number of buckets to reduce race" );
4141DEFINE_int32 (rdma_memory_pool_tls_cache_num, 128 , " Number of cached block in tls" );
42+ DEFINE_bool (rdma_memory_pool_user_specified_memory, false ,
43+ " If true, the user must call UserExtendBlockPool() to extend "
44+ " memory. bRPC will not handle memory extension." );
4245
4346static RegisterCallback g_cb = NULL ;
4447
@@ -125,31 +128,13 @@ uint32_t GetRegionId(const void* buf) {
125128 return r->id ;
126129}
127130
128- // Extend the block pool with a new region (with different region ID)
129- static void * ExtendBlockPool (size_t region_size, int block_type) {
130- if (region_size < 1 ) {
131- errno = EINVAL ;
132- return NULL ;
133- }
134-
131+ static void * ExtendBlockPoolImpl (void * region_base, size_t region_size,
132+ int block_type) {
135133 if (g_region_num == FLAGS_rdma_memory_pool_max_regions) {
136134 LOG (INFO ) << " Memory pool reaches max regions" ;
137135 errno = ENOMEM ;
138136 return NULL ;
139137 }
140-
141- // Regularize region size
142- region_size = region_size * BYTES_IN_MB / g_block_size[block_type] / g_buckets;
143- region_size *= g_block_size[block_type] * g_buckets;
144-
145- LOG (INFO ) << " Start extend rdma memory " << region_size / BYTES_IN_MB << " MB" ;
146-
147- void * region_base = NULL ;
148- if (posix_memalign (®ion_base, 4096 , region_size) != 0 ) {
149- PLOG_EVERY_SECOND (ERROR ) << " Memory not enough" ;
150- return NULL ;
151- }
152-
153138 uint32_t id = g_cb (region_base, region_size);
154139 if (id == 0 ) {
155140 free (region_base);
@@ -168,7 +153,7 @@ static void* ExtendBlockPool(size_t region_size, int block_type) {
168153 return NULL ;
169154 }
170155 }
171-
156+
172157 Region* region = &g_regions[g_region_num++];
173158 region->start = (uintptr_t )region_base;
174159 region->size = region_size;
@@ -178,23 +163,79 @@ static void* ExtendBlockPool(size_t region_size, int block_type) {
178163 for (size_t i = 0 ; i < g_buckets; ++i) {
179164 node[i]->start = (void *)(region->start + i * (region_size / g_buckets));
180165 node[i]->len = region_size / g_buckets;
181- node[i]->next = NULL ;
166+ node[i]->next = g_info-> idle_list [block_type][i] ;
182167 g_info->idle_list [block_type][i] = node[i];
183168 g_info->idle_size [block_type][i] += node[i]->len ;
184169 }
185170
186171 return region_base;
187172}
188173
189- void * InitBlockPool (RegisterCallback cb) {
190- if (!cb) {
174+ // Extend the block pool with a new region (with different region ID)
175+ static void * ExtendBlockPool (size_t region_size, int block_type) {
176+ if (region_size < 1 ) {
191177 errno = EINVAL ;
192178 return NULL ;
193179 }
180+
181+ if (FLAGS_rdma_memory_pool_user_specified_memory) {
182+ LOG_EVERY_SECOND (ERROR ) << " Fail to extend new region, "
183+ " rdma_memory_pool_user_specified_memory is "
184+ " true, ExtendBlockPool is disabled" ;
185+ return NULL ;
186+ }
187+
188+ // Regularize region size
189+ region_size = region_size * BYTES_IN_MB / g_block_size[block_type] / g_buckets;
190+ region_size *= g_block_size[block_type] * g_buckets;
191+
192+ LOG (INFO ) << " Start extend rdma memory " << region_size / BYTES_IN_MB << " MB" ;
193+
194+ void * region_base = NULL ;
195+ if (posix_memalign (®ion_base, 4096 , region_size) != 0 ) {
196+ PLOG_EVERY_SECOND (ERROR ) << " Memory not enough" ;
197+ return NULL ;
198+ }
199+
200+ return ExtendBlockPoolImpl (region_base, region_size, block_type);
201+ }
202+
203+ void * ExtendBlockPoolByUser (void * region_base, size_t region_size,
204+ int block_type) {
205+ if (FLAGS_rdma_memory_pool_user_specified_memory == false ) {
206+ LOG_EVERY_SECOND (ERROR ) << " User extend memory is disabled" ;
207+ return NULL ;
208+ }
209+ if (reinterpret_cast <uintptr_t >(region_base) % 4096 != 0 ) {
210+ LOG_EVERY_SECOND (ERROR ) << " region_base must be 4096 aligned" ;
211+ return NULL ;
212+ }
213+
214+ uint64_t index = butil::fast_rand () % g_buckets;
215+ BAIDU_SCOPED_LOCK (*g_info->lock [block_type][index]);
216+ BAIDU_SCOPED_LOCK (g_info->extend_lock );
217+
218+ if (g_region_num > 1 && FLAGS_rdma_memory_pool_buckets > 1 ) {
219+ LOG_EVERY_SECOND (ERROR )
220+ << " Runtime extend memory only support single bucket" ;
221+ return NULL ;
222+ }
223+ region_size =
224+ region_size * BYTES_IN_MB / g_block_size[block_type] / g_buckets;
225+ region_size *= g_block_size[block_type] * g_buckets;
226+
227+ return ExtendBlockPoolImpl (region_base, region_size, block_type);
228+ }
229+
230+ bool InitBlockPool (RegisterCallback cb) {
231+ if (!cb) {
232+ errno = EINVAL ;
233+ return false ;
234+ }
194235 if (g_cb) {
195236 LOG (WARNING ) << " Do not initialize block pool repeatedly" ;
196237 errno = EINVAL ;
197- return NULL ;
238+ return false ;
198239 }
199240 g_cb = cb;
200241 if (FLAGS_rdma_memory_pool_max_regions < RDMA_MEMORY_POOL_MIN_REGIONS ||
@@ -204,7 +245,7 @@ void* InitBlockPool(RegisterCallback cb) {
204245 << RDMA_MEMORY_POOL_MIN_REGIONS << " ,"
205246 << RDMA_MEMORY_POOL_MAX_REGIONS << " ]!" ;
206247 errno = EINVAL ;
207- return NULL ;
248+ return false ;
208249 }
209250 if (FLAGS_rdma_memory_pool_initial_size_mb < RDMA_MEMORY_POOL_MIN_SIZE ||
210251 FLAGS_rdma_memory_pool_initial_size_mb > RDMA_MEMORY_POOL_MAX_SIZE ) {
@@ -213,7 +254,7 @@ void* InitBlockPool(RegisterCallback cb) {
213254 << RDMA_MEMORY_POOL_MIN_SIZE << " ,"
214255 << RDMA_MEMORY_POOL_MAX_SIZE << " ]!" ;
215256 errno = EINVAL ;
216- return NULL ;
257+ return false ;
217258 }
218259 if (FLAGS_rdma_memory_pool_increase_size_mb < RDMA_MEMORY_POOL_MIN_SIZE ||
219260 FLAGS_rdma_memory_pool_increase_size_mb > RDMA_MEMORY_POOL_MAX_SIZE ) {
@@ -222,7 +263,7 @@ void* InitBlockPool(RegisterCallback cb) {
222263 << RDMA_MEMORY_POOL_MIN_SIZE << " ,"
223264 << RDMA_MEMORY_POOL_MAX_SIZE << " ]!" ;
224265 errno = EINVAL ;
225- return NULL ;
266+ return false ;
226267 }
227268 if (FLAGS_rdma_memory_pool_buckets < RDMA_MEMORY_POOL_MIN_BUCKETS ||
228269 FLAGS_rdma_memory_pool_buckets > RDMA_MEMORY_POOL_MAX_BUCKETS ) {
@@ -231,41 +272,54 @@ void* InitBlockPool(RegisterCallback cb) {
231272 << RDMA_MEMORY_POOL_MIN_BUCKETS << " ,"
232273 << RDMA_MEMORY_POOL_MAX_BUCKETS << " ]!" ;
233274 errno = EINVAL ;
234- return NULL ;
275+ return false ;
276+ }
277+ // runtime extend block pool only support 1 bucket
278+ if (FLAGS_rdma_memory_pool_max_regions > 1 &&
279+ FLAGS_rdma_memory_pool_buckets > 1 ) {
280+ LOG (WARNING ) << " rdma runtime extend block pool only support 1 bucket" ;
281+ return false ;
235282 }
236283 g_buckets = FLAGS_rdma_memory_pool_buckets;
237284
238285 g_info = new (std::nothrow) GlobalInfo;
239286 if (!g_info) {
240- return NULL ;
287+ return false ;
241288 }
242289
243290 for (int i = 0 ; i < BLOCK_SIZE_COUNT ; ++i) {
244291 g_info->idle_list [i].resize (g_buckets, NULL );
245292 if (g_info->idle_list [i].size () != g_buckets) {
246- return NULL ;
293+ return false ;
247294 }
248295 g_info->lock [i].resize (g_buckets, NULL );
249296 if (g_info->lock [i].size () != g_buckets) {
250- return NULL ;
297+ return false ;
251298 }
252299 g_info->idle_size [i].resize (g_buckets, 0 );
253300 if (g_info->idle_size [i].size () != g_buckets) {
254- return NULL ;
301+ return false ;
255302 }
256303 for (size_t j = 0 ; j < g_buckets; ++j) {
257304 g_info->lock [i][j] = new (std::nothrow) butil::Mutex;
258305 if (!g_info->lock [i][j]) {
259- return NULL ;
306+ return false ;
260307 }
261308 }
262309 }
263310
264311 g_dump_mutex = new butil::Mutex;
265312 g_tls_info_mutex = new butil::Mutex;
266313
267- return ExtendBlockPool (FLAGS_rdma_memory_pool_initial_size_mb,
268- BLOCK_DEFAULT );
314+ if (FLAGS_rdma_memory_pool_user_specified_memory) {
315+ return true ;
316+ }
317+
318+ if (ExtendBlockPool (FLAGS_rdma_memory_pool_initial_size_mb,
319+ BLOCK_DEFAULT ) != NULL ) {
320+ return true ;
321+ }
322+ return false ;
269323}
270324
271325static void * AllocBlockFrom (int block_type) {
0 commit comments