static inline memkind_t hbw_get_kind(int pagesize) { memkind_t result = NULL; int policy = hbw_get_policy(); if (policy == HBW_POLICY_BIND || policy == HBW_POLICY_INTERLEAVE) { switch (pagesize) { case HBW_PAGESIZE_2MB: result = MEMKIND_HBW_HUGETLB; break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_HBW_GBTLB; break; default: if (policy == HBW_POLICY_BIND) { result = MEMKIND_HBW; } else { result = MEMKIND_HBW_INTERLEAVE; } break; } } else if (memkind_check_available(MEMKIND_HBW) == 0) { switch (pagesize) { case HBW_PAGESIZE_2MB: result = MEMKIND_HBW_PREFERRED_HUGETLB; break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_HBW_PREFERRED_GBTLB; break; default: result = MEMKIND_HBW_PREFERRED; break; } } else { switch (pagesize) { case HBW_PAGESIZE_2MB: result = MEMKIND_HUGETLB; break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_GBTLB; break; default: result = MEMKIND_DEFAULT; break; } } return result; }
//////////////////////////////////////////////////////////////////////////// // This function is executed at library load time. // Initilize HBW arena by making a dummy allocation/free at library load // time. Until HBW initialization is complete, we must not call any // allocation routines with HBW as kind. //////////////////////////////////////////////////////////////////////////// void __attribute__ ((constructor)) autohbw_load(void) { // First set the default memory type this library allocates. This can // be overridden by env variable // Note: 'memkind_hbw_preferred' will allow falling back to DDR but // 'memkind_hbw will not' // Note: If HBM is not installed on a system, memkind_hbw_preferred call // woudl fail. Therefore, we need to check for availability first. // int ret = 0; if (memkind_check_available(MEMKIND_HBW) == 0) { ret = memkind_get_kind_by_name("memkind_hbw_preferred", &HBW_Type); } else { printf("WARN: *** No HBM found in system. Will use default (DDR) " "OR user specifid type ***\n"); ret = memkind_get_kind_by_name("memkind_default", &HBW_Type); } assert(!ret && "FATAL: Could not find default memory type\n"); // Read any env variables. This has to be done first because DbgLevel // is set using env variables and debug printing is used below // setEnvValues(); // read any env variables DBG(1) printf("INFO: autohbw.so loaded!\n"); // dummy HBW call to initialize HBW arena // void *pp = memkind_malloc(HBW_Type, 16); // if (pp) { // We have successfully initilized HBW arena // DBG(2) printf("\t-HBW int call succeeded\n"); memkind_free(0, pp); MemkindInitDone = TRUE; // enable HBW allocation } else { errPrn("\t-HBW init call FAILED. Is required memory type present on your system?\n"); assert(0 && "HBW/memkind initialization faild"); } }
int hbw_check_available(void) { return memkind_check_available(MEMKIND_HBW); }
// This function is intended to be called once per pagesize // Getting kind should be done using hbw_get_kind() defined below static memkind_t hbw_choose_kind(hbw_pagesize_t pagesize) { memkind_t result = NULL; hbw_set_policy(hbw_policy_g); int policy = hbw_get_policy(); // PREFERRED policy have separate handling cause it can fallback // to non-HBW kinds in case of HBW absence if (policy != HBW_POLICY_PREFERRED ) { switch (pagesize) { case HBW_PAGESIZE_2MB: if(policy == HBW_POLICY_BIND_ALL) { result = MEMKIND_HBW_ALL_HUGETLB; } else { result = MEMKIND_HBW_HUGETLB; } break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_HBW_GBTLB; break; default: if (policy == HBW_POLICY_BIND) { result = MEMKIND_HBW; } else if (policy == HBW_POLICY_BIND_ALL) { result = MEMKIND_HBW_ALL; } else { result = MEMKIND_HBW_INTERLEAVE; } break; } } else if (memkind_check_available(MEMKIND_HBW) == 0) { switch (pagesize) { case HBW_PAGESIZE_2MB: result = MEMKIND_HBW_PREFERRED_HUGETLB; break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_HBW_PREFERRED_GBTLB; break; default: result = MEMKIND_HBW_PREFERRED; break; } } else { switch (pagesize) { case HBW_PAGESIZE_2MB: result = MEMKIND_HUGETLB; break; case HBW_PAGESIZE_1GB: case HBW_PAGESIZE_1GB_STRICT: result = MEMKIND_GBTLB; break; default: result = MEMKIND_DEFAULT; break; } } return result; }
MEMKIND_EXPORT int hbw_check_available(void) { return (memkind_check_available(MEMKIND_HBW) == 0) ? 0 : ENODEV; }