mem: add external API to retrieve page fd
Now that we can retrieve page fd's internally, we can expose it as an external API. This will add two flavors of API - thread-safe and non-thread-safe. Fix up internal API's to return values we need without modifying rte_errno internally if called from within EAL. We do not want calling code to accidentally close an internal fd, so we make a duplicate of it before we return it to the user. Caller is therefore responsible for closing this fd. Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
This commit is contained in:
parent
1009ba1704
commit
41dbdb6872
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <rte_errno.h>
|
||||||
#include <rte_log.h>
|
#include <rte_log.h>
|
||||||
#include <rte_memory.h>
|
#include <rte_memory.h>
|
||||||
|
|
||||||
@ -50,13 +51,13 @@ eal_memalloc_sync_with_primary(void)
|
|||||||
int
|
int
|
||||||
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
|
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
|
||||||
{
|
{
|
||||||
return -1;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)
|
eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)
|
||||||
{
|
{
|
||||||
return -1;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -550,6 +550,55 @@ rte_memseg_list_walk(rte_memseg_list_walk_t func, void *arg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __rte_experimental
|
||||||
|
rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms)
|
||||||
|
{
|
||||||
|
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
|
||||||
|
struct rte_memseg_list *msl;
|
||||||
|
struct rte_fbarray *arr;
|
||||||
|
int msl_idx, seg_idx, ret;
|
||||||
|
|
||||||
|
if (ms == NULL) {
|
||||||
|
rte_errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
msl = rte_mem_virt2memseg_list(ms->addr);
|
||||||
|
if (msl == NULL) {
|
||||||
|
rte_errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
arr = &msl->memseg_arr;
|
||||||
|
|
||||||
|
msl_idx = msl - mcfg->memsegs;
|
||||||
|
seg_idx = rte_fbarray_find_idx(arr, ms);
|
||||||
|
|
||||||
|
if (!rte_fbarray_is_used(arr, seg_idx)) {
|
||||||
|
rte_errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eal_memalloc_get_seg_fd(msl_idx, seg_idx);
|
||||||
|
if (ret < 0) {
|
||||||
|
rte_errno = -ret;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __rte_experimental
|
||||||
|
rte_memseg_get_fd(const struct rte_memseg *ms)
|
||||||
|
{
|
||||||
|
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rte_rwlock_read_lock(&mcfg->memory_hotplug_lock);
|
||||||
|
ret = rte_memseg_get_fd_thread_unsafe(ms);
|
||||||
|
rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* init memory subsystem */
|
/* init memory subsystem */
|
||||||
int
|
int
|
||||||
rte_eal_memory_init(void)
|
rte_eal_memory_init(void)
|
||||||
|
@ -76,9 +76,11 @@ eal_memalloc_mem_alloc_validator_unregister(const char *name, int socket_id);
|
|||||||
int
|
int
|
||||||
eal_memalloc_mem_alloc_validate(int socket_id, size_t new_len);
|
eal_memalloc_mem_alloc_validate(int socket_id, size_t new_len);
|
||||||
|
|
||||||
|
/* returns fd or -errno */
|
||||||
int
|
int
|
||||||
eal_memalloc_get_seg_fd(int list_idx, int seg_idx);
|
eal_memalloc_get_seg_fd(int list_idx, int seg_idx);
|
||||||
|
|
||||||
|
/* returns 0 or -errno */
|
||||||
int
|
int
|
||||||
eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd);
|
eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd);
|
||||||
|
|
||||||
|
@ -317,6 +317,54 @@ rte_memseg_contig_walk_thread_unsafe(rte_memseg_contig_walk_t func, void *arg);
|
|||||||
int __rte_experimental
|
int __rte_experimental
|
||||||
rte_memseg_list_walk_thread_unsafe(rte_memseg_list_walk_t func, void *arg);
|
rte_memseg_list_walk_thread_unsafe(rte_memseg_list_walk_t func, void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return file descriptor associated with a particular memseg (if available).
|
||||||
|
*
|
||||||
|
* @note This function read-locks the memory hotplug subsystem, and thus cannot
|
||||||
|
* be used within memory-related callback functions.
|
||||||
|
*
|
||||||
|
* @note This returns an internal file descriptor. Performing any operations on
|
||||||
|
* this file descriptor is inherently dangerous, so it should be treated
|
||||||
|
* as read-only for all intents and purposes.
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
* A pointer to memseg for which to get file descriptor.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Valid file descriptor in case of success.
|
||||||
|
* -1 in case of error, with ``rte_errno`` set to the following values:
|
||||||
|
* - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg
|
||||||
|
* - ENODEV - ``ms`` fd is not available
|
||||||
|
* - ENOENT - ``ms`` is an unused segment
|
||||||
|
* - ENOTSUP - segment fd's are not supported
|
||||||
|
*/
|
||||||
|
int __rte_experimental
|
||||||
|
rte_memseg_get_fd(const struct rte_memseg *ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return file descriptor associated with a particular memseg (if available).
|
||||||
|
*
|
||||||
|
* @note This function does not perform any locking, and is only safe to call
|
||||||
|
* from within memory-related callback functions.
|
||||||
|
*
|
||||||
|
* @note This returns an internal file descriptor. Performing any operations on
|
||||||
|
* this file descriptor is inherently dangerous, so it should be treated
|
||||||
|
* as read-only for all intents and purposes.
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
* A pointer to memseg for which to get file descriptor.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Valid file descriptor in case of success.
|
||||||
|
* -1 in case of error, with ``rte_errno`` set to the following values:
|
||||||
|
* - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg
|
||||||
|
* - ENODEV - ``ms`` fd is not available
|
||||||
|
* - ENOENT - ``ms`` is an unused segment
|
||||||
|
* - ENOTSUP - segment fd's are not supported
|
||||||
|
*/
|
||||||
|
int __rte_experimental
|
||||||
|
rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the physical memory layout to a file.
|
* Dump the physical memory layout to a file.
|
||||||
*
|
*
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <rte_log.h>
|
#include <rte_log.h>
|
||||||
#include <rte_eal_memconfig.h>
|
#include <rte_eal_memconfig.h>
|
||||||
#include <rte_eal.h>
|
#include <rte_eal.h>
|
||||||
|
#include <rte_errno.h>
|
||||||
#include <rte_memory.h>
|
#include <rte_memory.h>
|
||||||
#include <rte_spinlock.h>
|
#include <rte_spinlock.h>
|
||||||
|
|
||||||
@ -1381,7 +1382,7 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)
|
|||||||
int len = mcfg->memsegs[list_idx].memseg_arr.len;
|
int len = mcfg->memsegs[list_idx].memseg_arr.len;
|
||||||
|
|
||||||
if (alloc_list(list_idx, len) < 0)
|
if (alloc_list(list_idx, len) < 0)
|
||||||
return -1;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
fd_list[list_idx].fds[seg_idx] = fd;
|
fd_list[list_idx].fds[seg_idx] = fd;
|
||||||
|
|
||||||
@ -1391,12 +1392,18 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)
|
|||||||
int
|
int
|
||||||
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
|
eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
|
||||||
{
|
{
|
||||||
if (internal_config.single_file_segments)
|
int fd;
|
||||||
return fd_list[list_idx].memseg_list_fd;
|
if (internal_config.single_file_segments) {
|
||||||
/* list not initialized */
|
fd = fd_list[list_idx].memseg_list_fd;
|
||||||
if (fd_list[list_idx].len == 0)
|
} else if (fd_list[list_idx].len == 0) {
|
||||||
return -1;
|
/* list not initialized */
|
||||||
return fd_list[list_idx].fds[seg_idx];
|
fd = -1;
|
||||||
|
} else {
|
||||||
|
fd = fd_list[list_idx].fds[seg_idx];
|
||||||
|
}
|
||||||
|
if (fd < 0)
|
||||||
|
return -ENODEV;
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -327,6 +327,8 @@ EXPERIMENTAL {
|
|||||||
rte_mem_virt2memseg_list;
|
rte_mem_virt2memseg_list;
|
||||||
rte_memseg_contig_walk;
|
rte_memseg_contig_walk;
|
||||||
rte_memseg_contig_walk_thread_unsafe;
|
rte_memseg_contig_walk_thread_unsafe;
|
||||||
|
rte_memseg_get_fd;
|
||||||
|
rte_memseg_get_fd_thread_unsafe;
|
||||||
rte_memseg_list_walk;
|
rte_memseg_list_walk;
|
||||||
rte_memseg_list_walk_thread_unsafe;
|
rte_memseg_list_walk_thread_unsafe;
|
||||||
rte_memseg_walk;
|
rte_memseg_walk;
|
||||||
|
Loading…
Reference in New Issue
Block a user