コード例 #1
0
ファイル: init.c プロジェクト: Xilinx/embeddedsw
static int metal_init_page_sizes(void)
{
	const int max_sizes = MAX_PAGE_SIZES - 1;
	long sizes[max_sizes];

	/* Determine system page size. */
	sizes[0] = getpagesize();
	if (sizes[0] <= 0) {
		metal_log(METAL_LOG_ERROR, "failed to get page size\n");
		return -ENOSYS;
	}
	_metal.page_size  = sizes[0];
	_metal.page_shift = metal_log2(sizes[0]);
	metal_add_page_size(_metal.tmp_path, _metal.page_shift, 0);

#ifdef HAVE_HUGETLBFS_H
#ifndef MAP_HUGE_SHIFT
	/* System does not support multiple huge page sizes. */
	sizes[0] = gethugepagesize();
	if (sizes[0] > 0) {
		metal_add_page_size(hugetlbfs_find_path(),
				    metal_log2(sizes[0]),
				    MAP_HUGETLB);
	}
#else
	if (gethugepagesize() >= 0) {
		int i, count;

		/* System supports multiple huge page sizes. */
		count = gethugepagesizes(sizes, max_sizes);
		for (i = 0; i < count; i++) {
			int shift = metal_log2(sizes[i]);
			if ((shift & MAP_HUGE_MASK) != shift)
				continue;
			metal_add_page_size(
				hugetlbfs_find_path_for_size(sizes[i]),
				shift, (MAP_HUGETLB |
				(shift << MAP_HUGE_SHIFT)));
		}
	}
#endif
#endif

	/* Finally sort the resulting array by size. */
	qsort(_metal.page_sizes, _metal.num_page_sizes,
	      sizeof(struct metal_page_size), metal_pagesize_compare);

	return 0;
}
コード例 #2
0
void hugetlbfs_setup_morecore(void)
{
	char *ep;
	unsigned long heapaddr;

	if (! __hugetlb_opts.morecore)
		return;
	if (strcasecmp(__hugetlb_opts.morecore, "no") == 0) {
		INFO("HUGETLB_MORECORE=%s, not setting up morecore\n",
						__hugetlb_opts.morecore);
		return;
	}

	/*
	 * Determine the page size that will be used for the heap.
	 * This can be set explicitly by setting HUGETLB_MORECORE to a valid
	 * page size string or by setting HUGETLB_DEFAULT_PAGE_SIZE.
	 */
	if (strncasecmp(__hugetlb_opts.morecore, "y", 1) == 0)
		hpage_size = gethugepagesize();
	else if (__hugetlb_opts.thp_morecore)
		hpage_size = kernel_default_hugepage_size();
	else
		hpage_size = parse_page_size(__hugetlb_opts.morecore);

	if (hpage_size <= 0) {
		if (errno == ENOSYS)
			WARNING("Hugepages unavailable\n");
		else if (errno == EOVERFLOW || errno == ERANGE)
			WARNING("Hugepage size too large\n");
		else if (errno == EINVAL)
			WARNING("Invalid huge page size\n");
		else
			WARNING("Hugepage size (%s)\n", strerror(errno));
		return;
	}

	/*
	 * We won't need an fd for the heap mmaps if we are using MAP_HUGETLB
	 * or we are depending on transparent huge pages
	 */
	if(__hugetlb_opts.thp_morecore || (__hugetlb_opts.map_hugetlb &&
			hpage_size == kernel_default_hugepage_size())) {
		heap_fd = -1;
	} else {
		if (!hugetlbfs_find_path_for_size(hpage_size)) {
			WARNING("Hugepage size %li unavailable", hpage_size);
			return;
		}

		heap_fd = hugetlbfs_unlinked_fd_for_size(hpage_size);
		if (heap_fd < 0) {
			WARNING("Couldn't open hugetlbfs file for morecore\n");
			return;
		}
	}

	/*
	 * THP morecore uses sbrk to allocate more heap space, counting on the
	 * kernel to back the area with THP.  So setting heapbase is
	 * meaningless if thp_morecore is used.
	 */
	if (!__hugetlb_opts.thp_morecore && __hugetlb_opts.heapbase) {
		heapaddr = strtoul(__hugetlb_opts.heapbase, &ep, 16);
		if (*ep != '\0') {
			WARNING("Can't parse HUGETLB_MORECORE_HEAPBASE: %s\n",
			      __hugetlb_opts.heapbase);
			return;
		}
	} else {
		heapaddr = (unsigned long)sbrk(0);
		if (!__hugetlb_opts.thp_morecore)
			heapaddr = hugetlbfs_next_addr(heapaddr);
	}

	INFO("setup_morecore(): heapaddr = 0x%lx\n", heapaddr);

	heaptop = heapbase = (void *)heapaddr;
	if (__hugetlb_opts.thp_morecore)
		__morecore = &thp_morecore;
	else
		__morecore = &hugetlbfs_morecore;

	/* Set some allocator options more appropriate for hugepages */

	if (__hugetlb_opts.shrink_ok)
		mallopt(M_TRIM_THRESHOLD, hpage_size / 2);
	else
		mallopt(M_TRIM_THRESHOLD, -1);
	mallopt(M_TOP_PAD, hpage_size / 2);
	/* we always want to use our morecore, not ordinary mmap().
	 * This doesn't appear to prohibit malloc() from falling back
	 * to mmap() if we run out of hugepages. */
	mallopt(M_MMAP_MAX, 0);
}