dpdk中的大页初始化

[root@localhost ~]# cd /sys/kernel/mm/hugepages
[root@localhost hugepages]# ls -al
total 0
drwxr-xr-x. 4 root root 0 6月   5 04:53 .
drwxr-xr-x. 5 root root 0 6月   5 04:53 ..
drwxr-xr-x. 2 root root 0 6月   6 07:27 hugepages-1048576kB
drwxr-xr-x. 2 root root 0 6月   6 07:27 hugepages-2048kB
[root@localhost hugepages]# cd hugepages-2048kB
[root@localhost hugepages-2048kB]# ls
free_hugepages  nr_hugepages  nr_hugepages_mempolicy  nr_overcommit_hugepages  resv_hugepages  surplus_hugepages
[root@localhost hugepages-2048kB]#

在dpdk中主要通过eal_hugepage_info_init 来会的大页的信息,也就是主要parse /sys/kernel/mm/hugepages 这个目录下面的内容
这个目录下面的内容如上所示
int
eal_hugepage_info_init(void)
{
	const char dirent_start_text[] = "hugepages-";
	const size_t dirent_start_len = sizeof(dirent_start_text) - 1;
	unsigned i, num_sizes = 0;
	DIR *dir;
	struct dirent *dirent;
	#打开包含大页的目录 /sys/kernel/mm/hugepages
	dir = opendir(sys_dir_path);
	if (dir == NULL) {
		RTE_LOG(ERR, EAL,
			"Cannot open directory %s to read system hugepage info\n",
			sys_dir_path);
		return -1;
	}
	#从本例看大页的目录下有两个子目录,这两个子目录是按照大页的size 来分类的,所以下面这个for 循环会循环两次
	for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) {
		struct hugepage_info *hpi;
		#比较目录名是否以开始 ,例如 hugepages-2048kB
		if (strncmp(dirent->d_name, dirent_start_text,
			    dirent_start_len) != 0)
			continue;
		#大页的size的种类不能超过3个,本例中就刚好是两个
		if (num_sizes >= MAX_HUGEPAGE_SIZES)
			break;
		#得到要保存大页信息的全局变量
		hpi = &internal_config.hugepage_info[num_sizes];
		#根据目录的name得到大页的size ,例如hugepages-1048576kB的size就是页大小就是2048K
		hpi->hugepage_sz =
			rte_str_to_size(&dirent->d_name[dirent_start_len]);
		#得到大页的目录
		hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);

		/* first, check if we have a mountpoint */
		#如果大页的目录为null,则可能还没有mount hugetlbfs
		if (hpi->hugedir == NULL) {
			uint32_t num_pages;

			num_pages = get_num_hugepages(dirent->d_name);
			if (num_pages > 0)
				RTE_LOG(NOTICE, EAL,
					"%" PRIu32 " hugepages of size "
					"%" PRIu64 " reserved, but no mounted "
					"hugetlbfs found for that size\n",
					num_pages, hpi->hugepage_sz);
			continue;
		}

		/* try to obtain a writelock */
		#打开这个目录,并保存目录描述符
		hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);

		/* if blocking lock failed */
		#锁定这个目录
		if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
			RTE_LOG(CRIT, EAL,
				"Failed to lock hugepage directory!\n");
			break;
		}
		/* clear out the hugepages dir from unused pages */
		if (clear_hugedir(hpi->hugedir) == -1)
			break;

		/* for now, put all pages into socket 0,
		 * later they will be sorted */
		#得到实际大页的个数
		hpi->num_pages[0] = get_num_hugepages(dirent->d_name);

#ifndef RTE_ARCH_64
		/* for 32-bit systems, limit number of hugepages to
		 * 1GB per page size */
		 #如果是32 位系统的话,则大页不能超过1GB
		hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
					    RTE_PGSIZE_1G / hpi->hugepage_sz);
#endif

		num_sizes++;
	}
	#关掉这个目录/sys/kernel/mm/hugepages
	closedir(dir);

	/* something went wrong, and we broke from the for loop above */
	if (dirent != NULL)
		return -1;

	internal_config.num_hugepage_sizes = num_sizes;

	/* sort the page directory entries by size, largest to smallest */
	#对已经保存的大页按照size 从小到大排序
	qsort(&internal_config.hugepage_info[0], num_sizes,
	      sizeof(internal_config.hugepage_info[0]), compare_hpi);

	/* now we have all info, check we have at least one valid size */
	#再次检查保存大页的全局变量中目录和大约的个数不能为null
	for (i = 0; i < num_sizes; i++)
		if (internal_config.hugepage_info[i].hugedir != NULL &&
		    internal_config.hugepage_info[i].num_pages[0] > 0)
			return 0;

	/* no valid hugepage mounts available, return error */
	return -1;
}

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/80599992