Esempio n. 1
0
static uint64_t get_default_hp_size(void)
{
	const char proc_meminfo[] = "/proc/meminfo";
	const char str_hugepagesz[] = "Hugepagesize:";
	unsigned int hugepagesz_len = sizeof(str_hugepagesz) - 1;
	char buffer[256];
	unsigned long long size = 0;

	FILE *fd = fopen(proc_meminfo, "r");

	if (!fd)
		ODP_PRINT("Cannot open %s\n", proc_meminfo);

	while (fgets(buffer, sizeof(buffer), fd))
		if (strncmp(buffer, str_hugepagesz, hugepagesz_len) == 0) {
			size = odp_str_to_size(&buffer[hugepagesz_len]);
			break;
		}

	fclose(fd);
	if (size == 0)
		ODP_PRINT("Cannot get default hugepage "
			  "size from %s\n", proc_meminfo);

	return size;
}
Esempio n. 2
0
/* create the ring */
struct odp_ring *odp_ring_create(const char *name, unsigned count,
				 int socket_id, unsigned flags)
{
	char mz_name[ODP_MEMZONE_NAMESIZE];
	struct odp_ring *r;
	struct odp_tailq_entry *te;
	const struct odp_mm_district *mz;
	ssize_t ring_size;
	int mz_flags = 0;
	struct odp_ring_list *ring_list = NULL;

	ring_list = ODP_TAILQ_CAST(odp_ring_tailq.head, odp_ring_list);

	ring_size = odp_ring_get_memsize(count);
	if (ring_size < 0) {
		odp_err = ring_size;
		return NULL;
	}

	te = malloc(sizeof(*te));
	if (te == NULL) {
		ODP_PRINT("Cannot reserve memory for tailq\n");
		odp_err = ENOMEM;
		return NULL;
	}

	snprintf(mz_name, sizeof(mz_name), "%s%s", ODP_RING_MZ_PREFIX, name);

	odp_rwlock_write_lock(ODP_TAILQ_RWLOCK);

	/* reserve a memory zone for this ring. If we can't get odp_config or
	 * we are secondary process, the mm_district_reserve function will set
	 * odp_err for us appropriately-hence no check in this this function */
	mz = odp_mm_district_reserve(mz_name, mz_name, ring_size,
				     socket_id, mz_flags);
	if (mz != NULL) {
		r = mz->addr;

		/* no need to check return value here, we already checked the
		 * arguments above */

		odp_ring_init(r, name, count, flags);

		te->data = (void *)r;

		TAILQ_INSERT_TAIL(ring_list, te, next);
	} else {
		r = NULL;
		ODP_PRINT("Cannot reserve memory\n");
		free(te);
	}

	odp_rwlock_write_unlock(ODP_TAILQ_RWLOCK);

	return r;
}
Esempio n. 3
0
void odp_shm_print_all(void)
{
	int i;

	ODP_PRINT("\nShared memory\n");
	ODP_PRINT("--------------\n");
	ODP_PRINT("  page size:      %" PRIu64 " kB\n",
		  odp_sys_page_size() / 1024);
	ODP_PRINT("  huge page size: %" PRIu64 " kB\n",
		  odp_sys_huge_page_size() / 1024);
	ODP_PRINT("\n");

	ODP_PRINT("  id name                       kB align huge addr\n");

	for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
		odp_shm_block_t *block;

		block = &odp_shm_tbl->block[i];

		if (block->addr)
			ODP_PRINT("  %2i %-24s %4" PRIu64 "  %4" PRIu64
				  " %2c   %p\n",
				  i,
				  block->name,
				  block->size / 1024,
				  block->align,
				  (block->huge ? '*' : ' '),
				  block->addr);
	}

	ODP_PRINT("\n");
}
Esempio n. 4
0
int odp_buffer_snprint(char *str, uint32_t n, odp_buffer_t buf)
{
	odp_buffer_hdr_t *hdr;
	int len = 0;

	if (!odp_buffer_is_valid(buf)) {
		ODP_PRINT("Buffer is not valid.\n");
		return len;
	}

	hdr = odp_buf_to_hdr(buf);

	len += snprintf(&str[len], n-len,
			"Buffer\n");
	len += snprintf(&str[len], n-len,
			"  pool         %" PRIu64 "\n",
			odp_pool_to_u64(hdr->pool_hdl));
	len += snprintf(&str[len], n-len,
			"  addr         %p\n",        hdr->addr);
	len += snprintf(&str[len], n-len,
			"  size         %" PRIu32 "\n",        hdr->size);
	len += snprintf(&str[len], n-len,
			"  ref_count    %" PRIu32 "\n",
			odp_atomic_load_u32(&hdr->ref_count));
	len += snprintf(&str[len], n-len,
			"  type         %i\n",        hdr->type);

	return len;
}
Esempio n. 5
0
static int get_num_hugepages(const char *subdir)
{
	char path[ODP_PATH_MAX];
	unsigned long resv_pages, num_pages = 0;
	const char   *nr_hp_file;

	/* first, check how many reserved pages kernel reports */
	snprintf(path, sizeof(path), "%s/%s/%s",
		 sys_dir_path, subdir, "resv_hugepages");
	resv_pages = odp_parse_sysfs_value(path);
	if (resv_pages < 0)
		return 0;

	/* if secondary process, just look at the number of hugepages,
	 * otherwise look at number of free hugepages */
	if (local_config.process_type == ODP_PROC_SECONDARY)
		nr_hp_file = "nr_hugepages";
	else
		nr_hp_file = "free_hugepages";

	snprintf(path, sizeof(path), "%s/%s/%s",
		 sys_dir_path, subdir, nr_hp_file);
	num_pages = odp_parse_sysfs_value(path);
	if (num_pages < 0)
		return 0;

	if (num_pages == 0)
		ODP_PRINT("No free hugepages repohodpd in %s\n", subdir);

	/* adjust num_pages in case of primary process */
	if ((num_pages > 0) && (local_config.process_type == ODP_PROC_PRIMARY))
		num_pages -= resv_pages;

	return (int)num_pages;
}
Esempio n. 6
0
void odp_buffer_print(odp_buffer_t buf)
{
	int max_len = 512;
	char str[max_len];
	int len;

	len = odp_buffer_snprint(str, max_len-1, buf);
	str[len] = 0;

	ODP_PRINT("\n%s\n", str);
}
Esempio n. 7
0
/* return the size of memory occupied by a ring */
ssize_t odp_ring_get_memsize(unsigned count)
{
	ssize_t sz;

	/* count must be a power of 2 */
	if ((!POWEROF2(count)) || (count > ODP_RING_SZ_MASK)) {
		ODP_PRINT("Requested size is invalid, must be power of 2, and "
			  "do not exceed the size limit %u\n",
			  ODP_RING_SZ_MASK);
		return -EINVAL;
	}

	sz = sizeof(struct odp_ring) + count * sizeof(void *);
	sz = ODP_ALIGN(sz, ODP_CACHE_LINE_SIZE);
	return sz;
}
Esempio n. 8
0
int odp_hugepage_info_init(void)
{
	unsigned i, num_sizes = 0;
	struct dirent *dirent = NULL;
	DIR *dir = NULL;
	struct odp_hugepage_type *hpt = NULL;

	dir = opendir(sys_dir_path);
	if (!dir)
		ODP_PRINT("Cannot open directory %s to "
			  "read system hugepage info\n", sys_dir_path);

	dirent = readdir(dir);

	/* loop get different kinds of hugepages in
	 * the system hugepage directory */
	while (dirent) {
		if (strncmp(dirent->d_name, "hugepages-",
			    ODP_SYS_HGPG_STR_LEN) == 0) {
			hpt = &local_config.odp_hugepage_type[num_sizes];

			hpt->hugepage_sz =
				odp_str_to_size(&dirent->d_name[
							ODP_SYS_HGPG_STR_LEN]);
			hpt->hugedir = get_hugepage_dir(hpt->hugepage_sz);

			/* first, check if we have a mountpoint */
			if (!hpt->hugedir) {
				int32_t num_pages;

				num_pages = get_num_hugepages(dirent->d_name);
				if (num_pages > 0) {
					ODP_PRINT("%d hugepages of"
						  " size %lu reserved, ",
						  num_pages,
						  hpt->hugepage_sz);
					ODP_PRINT("but no mounted hugetlbfs"
						  " found for that size\n");
				}
			} else {
				/* try to obtain a writelock */
				hpt->lock_descriptor = open(hpt->hugedir,
							    O_RDONLY);

				/* if blocking lock failed */
				if (flock(hpt->lock_descriptor,
					  LOCK_EX) == -1) {
					ODP_ERR("Failed to lock hugepage"
						" directory!\n");
					closedir(dir);
					return -1;
				}

				/* clear out the hugepages
				* dir from unused pages */
				if (clear_hugedir(hpt->hugedir) == -1) {
					closedir(dir);
					return -1;
				}

				/* for now, put all pages into socket 0,
				 * later they will be sohodpd */
				hpt->num_pages[0] =
					get_num_hugepages(dirent->d_name);
				hpt->num_pages[0] =
					ODP_MIN(hpt->num_pages[0],
						ODP_PAGE_MEMORY_MAX /
						hpt->hugepage_sz);
				num_sizes++;
			}
		}

		dirent = readdir(dir);
	}

	closedir(dir);
	local_config.num_hugepage_types = num_sizes;

	/* sort the page directory entries by size, largest to smallest */
	for (i = 0; i < num_sizes; i++) {
		unsigned int j;

		for (j = i + 1; j < num_sizes; j++)
			if (local_config.odp_hugepage_type[j - 1].hugepage_sz <
			    local_config.odp_hugepage_type[j].hugepage_sz)
				swap_hpt(
					&local_config.odp_hugepage_type[j - 1],
					&local_config.odp_hugepage_type[j]);
	}

	/* now we have all info, check we have at least one valid size */
	for (i = 0; i < num_sizes; i++)
		if (local_config.odp_hugepage_type[i].hugedir &&
		    (local_config.odp_hugepage_type[i].num_pages[0] > 0))
			return 0;

	/* no valid hugepage mounts available, return error */
	return -1;
}
Esempio n. 9
0
/*
 * Clear the hugepage directory of whatever hugepage files
 * there are. Checks if the file is locked (i.e.
 * if it's in use by another ODP process).
 */
static int clear_hugedir(const char *hugedir)
{
	DIR *dir;
	struct dirent *dirent;
	int  dir_fd, fd, lck_result;
	const char filter[] = "*map_*"; /* matches hugepage files */

	/* open directory */
	dir = opendir(hugedir);
	if (!dir) {
		ODP_PRINT("Unable to open hugepage directory %s\n", hugedir);
		goto error;
	}

	dir_fd = dirfd(dir);

	dirent = readdir(dir);
	if (!dirent) {
		ODP_PRINT("Unable to read hugepage directory %s\n", hugedir);
		goto error;
	}

	while (dirent) {
		/* skip files that don't match the hugepage pattern */
		if (fnmatch(filter, dirent->d_name, 0) > 0) {
			dirent = readdir(dir);
			continue;
		}

		/* try and lock the file */
		fd = openat(dir_fd, dirent->d_name, O_RDONLY);

		/* skip to next file */
		if (fd == -1) {
			dirent = readdir(dir);
			continue;
		}

		/* non-blocking lock */
		lck_result = flock(fd, LOCK_EX | LOCK_NB);

		/* if lock succeeds, unlock and remove the file */
		if (lck_result != -1) {
			flock(fd, LOCK_UN);
			unlinkat(dir_fd, dirent->d_name, 0);
		}

		close(fd);
		dirent = readdir(dir);
	}

	closedir(dir);
	return 0;

error:
	if (dir)
		closedir(dir);

	ODP_PRINT("Error while clearing hugepage dir: %s\n", strerror(errno));

	return -1;
}
Esempio n. 10
0
static const char *get_hugepage_dir(uint64_t hugepage_sz)
{
	enum proc_mount_fieldnames {
		DEVICE = 0,
		MOUNTPT,
		FSTYPE,
		OPTIONS,
		_FIELDNAME_MAX
	};
	static uint64_t default_size;
	const char split_tok = ' ';
	char *splitstr[_FIELDNAME_MAX];
	char  buf[ODP_BUFF_SIZE];
	char *retval = NULL;

	FILE *fd = fopen("/proc/mounts", "r");

	if (!fd)
		ODP_PRINT("Cannot open proc_mount\n");

	if (default_size == 0)
		default_size = get_default_hp_size();

	while (fgets(buf, sizeof(buf), fd)) {
		if (odp_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX,
				 split_tok) != _FIELDNAME_MAX) {
			ODP_PRINT("Error parsing proc_mount\n");
			break; /* return NULL */
		}

		if (strncmp(splitstr[FSTYPE], HUGETLBFS_DESC,
			    HGTLB_DSC_LEN) == 0) {
			const char *pagesz_str = strstr(splitstr[OPTIONS],
							HUGEPAGE_SIZE_DESC);

			/* if no explicit page size, the
			 * default page size is compared */
			if (!pagesz_str) {
				if (hugepage_sz == default_size) {
					retval = strdup(splitstr[MOUNTPT]);
					break;
				}
			}

			/* there is an explicit page size, so check it */
			else {
				uint64_t pagesz =
					odp_str_to_size(
						&pagesz_str[HP_DESC_LEN]);

				if (pagesz == hugepage_sz) {
					retval = strdup(splitstr[MOUNTPT]);
					break;
				}
			}
		} /* end if strncmp hugetlbfs */
	}   /* end while fgets */

	fclose(fd);
	return retval;
}