mem: allow querying offset into segment fd
authorAnatoly Burakov <anatoly.burakov@intel.com>
Tue, 4 Sep 2018 15:15:49 +0000 (16:15 +0100)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 19 Sep 2018 13:01:58 +0000 (15:01 +0200)
In a few cases, user may need to query offset into fd for a
particular memory segment (for example, to selectively map
pages). This commit adds a new API to do that.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
lib/librte_eal/bsdapp/eal/eal_memalloc.c
lib/librte_eal/common/eal_common_memory.c
lib/librte_eal/common/eal_memalloc.h
lib/librte_eal/common/include/rte_memory.h
lib/librte_eal/linuxapp/eal/eal_memalloc.c
lib/librte_eal/rte_eal_version.map

index 80e4c3d..06afbcc 100644 (file)
@@ -60,6 +60,12 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)
        return -ENOTSUP;
 }
 
+int
+eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
+{
+       return -ENOTSUP;
+}
+
 int
 eal_memalloc_init(void)
 {
index 4a80dea..0b69804 100644 (file)
@@ -599,6 +599,56 @@ rte_memseg_get_fd(const struct rte_memseg *ms)
        return ret;
 }
 
+int __rte_experimental
+rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms,
+               size_t *offset)
+{
+       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 || offset == 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_offset(msl_idx, seg_idx, offset);
+       if (ret < 0) {
+               rte_errno = -ret;
+               ret = -1;
+       }
+       return ret;
+}
+
+int __rte_experimental
+rte_memseg_get_fd_offset(const struct rte_memseg *ms, size_t *offset)
+{
+       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_offset_thread_unsafe(ms, offset);
+       rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+
+       return ret;
+}
+
 /* init memory subsystem */
 int
 rte_eal_memory_init(void)
index 70a214d..af917c2 100644 (file)
@@ -84,6 +84,9 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx);
 int
 eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd);
 
+int
+eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset);
+
 int
 eal_memalloc_init(void);
 
index 0d2a300..14bd277 100644 (file)
@@ -365,6 +365,55 @@ rte_memseg_get_fd(const struct rte_memseg *ms);
 int __rte_experimental
 rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms);
 
+/**
+ * Get offset into segment 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.
+ *
+ * @param ms
+ *   A pointer to memseg for which to get file descriptor.
+ * @param offset
+ *   A pointer to offset value where the result will be stored.
+ *
+ * @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
+ *     - EINVAL  - ``offset`` pointer was NULL
+ *     - 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_offset(const struct rte_memseg *ms, size_t *offset);
+
+/**
+ * Get offset into segment 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.
+ *
+ * @param ms
+ *   A pointer to memseg for which to get file descriptor.
+ * @param offset
+ *   A pointer to offset value where the result will be stored.
+ *
+ * @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
+ *     - EINVAL  - ``offset`` pointer was NULL
+ *     - 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_offset_thread_unsafe(const struct rte_memseg *ms,
+               size_t *offset);
+
 /**
  * Dump the physical memory layout to a file.
  *
index 21f8427..6fc9dc0 100644 (file)
@@ -1406,6 +1406,30 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
        return fd;
 }
 
+int
+eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
+{
+       struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+       /* fd_list not initialized? */
+       if (fd_list[list_idx].len == 0)
+               return -ENODEV;
+       if (internal_config.single_file_segments) {
+               size_t pgsz = mcfg->memsegs[list_idx].page_sz;
+
+               /* segment not active? */
+               if (fd_list[list_idx].memseg_list_fd < 0)
+                       return -ENOENT;
+               *offset = pgsz * seg_idx;
+       } else {
+               /* segment not active? */
+               if (fd_list[list_idx].fds[seg_idx] < 0)
+                       return -ENOENT;
+               *offset = 0;
+       }
+       return 0;
+}
+
 int
 eal_memalloc_init(void)
 {
index fb200de..73282bb 100644 (file)
@@ -328,7 +328,9 @@ EXPERIMENTAL {
        rte_memseg_contig_walk;
        rte_memseg_contig_walk_thread_unsafe;
        rte_memseg_get_fd;
+       rte_memseg_get_fd_offset;
        rte_memseg_get_fd_thread_unsafe;
+       rte_memseg_get_fd_offset_thread_unsafe;
        rte_memseg_list_walk;
        rte_memseg_list_walk_thread_unsafe;
        rte_memseg_walk;