Skip to content

Commit e06264f

Browse files
stedolangretay-js
authored andcommitted
Reintroduce support for OCAMLRUNPARAM=H=1 (force hugepages) (oxcaml#3834)
1 parent 815a93a commit e06264f

File tree

9 files changed

+28
-11
lines changed

9 files changed

+28
-11
lines changed

runtime/caml/osdeps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ extern int caml_format_timestamp(char* buf, size_t sz, int formatted);
106106

107107
/* Memory management platform-specific operations */
108108

109-
void *caml_plat_mem_map(uintnat, int, const char*);
109+
void *caml_plat_mem_map(uintnat size, uintnat flags, const char* name);
110110
void *caml_plat_mem_commit(void *, uintnat, const char*);
111111
void caml_plat_mem_decommit(void *, uintnat, const char*);
112112
void caml_plat_mem_unmap(void *, uintnat);

runtime/caml/platform.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ uintnat caml_mem_round_up_mapping_size(uintnat size);
440440
caml_plat_pagesize. The size given to caml_mem_unmap and caml_mem_decommit
441441
must match the size given to caml_mem_map/caml_mem_commit for mem.
442442
*/
443-
void* caml_mem_map(uintnat size, int reserve_only, const char* name);
443+
enum { CAML_MAP_RESERVE_ONLY = 1 << 0, CAML_MAP_NO_HUGETLB = 1 << 1 };
444+
void* caml_mem_map(uintnat size, uintnat flags, const char* name);
444445
void* caml_mem_commit(void* mem, uintnat size, const char* name);
445446
void caml_mem_decommit(void* mem, uintnat size, const char* name);
446447
void caml_mem_unmap(void* mem, uintnat size);

runtime/caml/startup_aux.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct caml_params {
5656
uintnat cleanup_on_exit;
5757
uintnat event_trace;
5858
uintnat max_domains;
59+
uintnat use_hugetlb_pages;
5960
};
6061

6162
extern const struct caml_params* const caml_params;

runtime/domain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ static void reserve_minor_heaps_from_stw_single(void) {
837837
minor_heap_reservation_bsize = minor_heap_max_bsz * caml_params->max_domains;
838838

839839
/* reserve memory space for minor heaps */
840-
heaps_base = caml_mem_map(minor_heap_reservation_bsize, 1 /* reserve_only */, "minor reservation");
840+
heaps_base = caml_mem_map(minor_heap_reservation_bsize, CAML_MAP_RESERVE_ONLY, "minor reservation");
841841
if (heaps_base == NULL)
842842
caml_fatal_error("Not enough heap memory to reserve minor heaps");
843843

runtime/fiber.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ Caml_inline struct stack_info* alloc_for_stack (mlsize_t wosize)
217217
#else
218218
const char* mapping_name = "stack";
219219
#endif
220-
stack = caml_mem_map(len, 0, mapping_name);
220+
/* These mappings should never use HugeTLB pages, due to the guard page */
221+
stack = caml_mem_map(len, CAML_MAP_NO_HUGETLB, mapping_name);
221222
if (stack == NULL) {
222223
return NULL;
223224
}

runtime/gc_ctrl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ CAMLprim value caml_runtime_parameters (value unit)
571571
char *no_tweaks = "";
572572
/* keep in sync with runtime4 and with parse_ocamlrunparam */
573573
value res = caml_alloc_sprintf
574-
("b=%d,c="F_Z",d="F_Z",e="F_Z",i="F_Z",l="F_Z
574+
("b=%d,c="F_Z",d="F_Z",e="F_Z",H="F_Z",i="F_Z",l="F_Z
575575
",m="F_Z",M="F_Z",n="F_Z",o="F_Z",O="F_Z
576576
",p="F_Z",s="F_Z",t="F_Z",v="F_Z",V="F_Z
577577
",W="F_Z"%s",
@@ -581,7 +581,7 @@ CAMLprim value caml_runtime_parameters (value unit)
581581
/* d */ caml_params->max_domains,
582582
/* e */ caml_params->runtime_events_log_wsize,
583583
/* h is runtime 4 init heap size */
584-
/* H is runtime 4 huge pages */
584+
/* H */ caml_params->use_hugetlb_pages,
585585
/* i */ caml_major_heap_increment,
586586
/* l */ caml_max_stack_wsize,
587587
/* m */ caml_custom_minor_ratio,

runtime/platform.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ uintnat caml_mem_round_up_mapping_size(uintnat size)
400400

401401
#define Is_page_aligned(size) ((size & (caml_plat_pagesize - 1)) == 0)
402402

403-
void* caml_mem_map(uintnat size, int reserve_only, const char* name)
403+
void* caml_mem_map(uintnat size, uintnat flags, const char* name)
404404
{
405-
void* mem = caml_plat_mem_map(size, reserve_only, name);
405+
void* mem = caml_plat_mem_map(size, flags, name);
406406

407407
if (mem == 0) {
408408
CAML_GC_MESSAGE(ADDRSPACE,

runtime/startup_aux.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static void init_startup_params(void)
7777
params.init_max_stack_wsz = Max_stack_def;
7878
params.max_domains = Max_domains_def;
7979
params.runtime_events_log_wsize = Default_runtime_events_log_wsize;
80+
params.use_hugetlb_pages = 0;
8081

8182
#ifdef DEBUG
8283
// Silenced in flambda-backend to make it easier to run tests that
@@ -152,7 +153,7 @@ static void parse_ocamlrunparam(char_os* opt)
152153
case 'd': scanmult (opt, &params.max_domains); break;
153154
case 'e': scanmult (opt, &params.runtime_events_log_wsize); break;
154155
case 'h': break; /* init heap size in runtime 4 */
155-
case 'H': break; /* use huge pages in runtime 4 */
156+
case 'H': scanmult (opt, &params.use_hugetlb_pages); break;
156157
case 'i': scanmult (opt, &params.init_major_heap_increment); break;
157158
case 'l': scanmult (opt, &params.init_max_stack_wsz); break;
158159
case 'm': scanmult (opt, &params.init_custom_minor_ratio); break;

runtime/unix.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "caml/io.h"
7474
#include "caml/alloc.h"
7575
#include "caml/platform.h"
76+
#include "caml/startup_aux.h"
7677

7778
#ifndef S_ISREG
7879
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
@@ -536,9 +537,11 @@ static void* mmap_named(void* addr, size_t length, int prot, int flags,
536537
}
537538
#endif
538539

539-
void *caml_plat_mem_map(uintnat size, int reserve_only, const char* name)
540+
void *caml_plat_mem_map(uintnat size, uintnat caml_flags, const char* name)
540541
{
541542
uintnat alignment = caml_plat_hugepagesize;
543+
uintnat reserve_only = caml_flags & CAML_MAP_RESERVE_ONLY;
544+
uintnat no_hugetlb = caml_flags & CAML_MAP_NO_HUGETLB;
542545
#ifdef WITH_ADDRESS_SANITIZER
543546
return aligned_alloc(alignment, (size + (alignment - 1)) & ~(alignment - 1));
544547
#else
@@ -555,6 +558,15 @@ void *caml_plat_mem_map(uintnat size, int reserve_only, const char* name)
555558
return mem;
556559
}
557560

561+
#ifdef HAS_HUGE_PAGES
562+
if (caml_params->use_hugetlb_pages && !reserve_only && !no_hugetlb) {
563+
/* If requested, try mapping with MAP_HUGETLB */
564+
mem = mmap_named(0, size, prot, flags | MAP_HUGETLB, -1, 0, name);
565+
if (mem == MAP_FAILED) mem = NULL;
566+
return mem;
567+
}
568+
#endif
569+
558570
/* Sensible kernels (on Linux, that means >= 6.7) will always provide aligned
559571
mappings. To avoid penalising such kernels, try mapping the exact desired
560572
size first and see if it happens to be aligned. */
@@ -599,9 +611,10 @@ static void* map_fixed(void* mem, uintnat size, int prot, const char* name)
599611
done using mprotect, since Cygwin's mmap doesn't implement the required
600612
functions for committing using mmap. */
601613

602-
void *caml_plat_mem_map(uintnat size, int reserve_only, const char* name)
614+
void *caml_plat_mem_map(uintnat size, uintnat flags, const char* name)
603615
{
604616
void* mem;
617+
uintnat reserve_only = flags & CAML_MAP_RESERVE_ONLY;
605618

606619
mem = mmap(0, size, reserve_only ? PROT_NONE : (PROT_READ | PROT_WRITE),
607620
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

0 commit comments

Comments
 (0)