| 391 | } |
| 392 | |
| 393 | static int |
| 394 | try_expand_heap_primary(struct malloc_heap *heap, uint64_t pg_sz, |
| 395 | size_t elt_size, int socket, unsigned int flags, size_t align, |
| 396 | size_t bound, bool contig) |
| 397 | { |
| 398 | struct malloc_elem *elem; |
| 399 | struct rte_memseg **ms; |
| 400 | void *map_addr; |
| 401 | size_t alloc_sz; |
| 402 | int n_segs; |
| 403 | bool callback_triggered = false; |
| 404 | |
| 405 | alloc_sz = RTE_ALIGN_CEIL(RTE_ALIGN_CEIL(elt_size, align) + |
| 406 | MALLOC_ELEM_OVERHEAD, pg_sz); |
| 407 | n_segs = alloc_sz / pg_sz; |
| 408 | |
| 409 | /* we can't know in advance how many pages we'll need, so we malloc */ |
| 410 | ms = malloc(sizeof(*ms) * n_segs); |
| 411 | if (ms == NULL) |
| 412 | return -1; |
| 413 | memset(ms, 0, sizeof(*ms) * n_segs); |
| 414 | |
| 415 | elem = alloc_pages_on_heap(heap, pg_sz, elt_size, socket, flags, align, |
| 416 | bound, contig, ms, n_segs); |
| 417 | |
| 418 | if (elem == NULL) |
| 419 | goto free_ms; |
| 420 | |
| 421 | map_addr = ms[0]->addr; |
| 422 | |
| 423 | /* notify user about changes in memory map */ |
| 424 | eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC, map_addr, alloc_sz); |
| 425 | |
| 426 | /* notify other processes that this has happened */ |
| 427 | if (request_sync()) { |
| 428 | /* we couldn't ensure all processes have mapped memory, |
| 429 | * so free it back and notify everyone that it's been |
| 430 | * freed back. |
| 431 | * |
| 432 | * technically, we could've avoided adding memory addresses to |
| 433 | * the map, but that would've led to inconsistent behavior |
| 434 | * between primary and secondary processes, as those get |
| 435 | * callbacks during sync. therefore, force primary process to |
| 436 | * do alloc-and-rollback syncs as well. |
| 437 | */ |
| 438 | callback_triggered = true; |
| 439 | goto free_elem; |
| 440 | } |
| 441 | heap->total_size += alloc_sz; |
| 442 | |
| 443 | RTE_LOG(DEBUG, EAL, "Heap on socket %d was expanded by %zdMB\n", |
| 444 | socket, alloc_sz >> 20ULL); |
| 445 | |
| 446 | free(ms); |
| 447 | |
| 448 | return 0; |
| 449 | |
| 450 | free_elem: |
no test coverage detected