From: Tiwei Bie <tiwei.bie@intel.com>
To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org
Cc: seanbh@gmail.com, anatoly.burakov@intel.com
Subject: [PATCH 2/3] net/virtio-user: avoid parsing process mappings
Date: Wed, 5 Sep 2018 12:28:51 +0800 [thread overview]
Message-ID: <20180905042852.6212-3-tiwei.bie@intel.com> (raw)
In-Reply-To: <20180905042852.6212-1-tiwei.bie@intel.com>
Recently some memory APIs were introduced to allow users to
get the file descriptor and offset for each memory segment.
We can leverage those APIs to get rid of the /proc magic on
memory table preparation in vhost-user backend.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_user/vhost_user.c | 211 +++++++++-----------
1 file changed, 90 insertions(+), 121 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/vhost_user.c b/drivers/net/virtio/virtio_user/vhost_user.c
index ef6e43df8..8bd49610b 100644
--- a/drivers/net/virtio/virtio_user/vhost_user.c
+++ b/drivers/net/virtio/virtio_user/vhost_user.c
@@ -11,6 +11,9 @@
#include <string.h>
#include <errno.h>
+#include <rte_fbarray.h>
+#include <rte_eal_memconfig.h>
+
#include "vhost.h"
#include "virtio_user_dev.h"
@@ -121,133 +124,103 @@ vhost_user_read(int fd, struct vhost_user_msg *msg)
return -1;
}
-struct hugepage_file_info {
- uint64_t addr; /**< virtual addr */
- size_t size; /**< the file size */
- char path[PATH_MAX]; /**< path to backing file */
+struct walk_arg {
+ struct vhost_memory *vm;
+ int *fds;
+ int region_nr;
};
-/* Two possible options:
- * 1. Match HUGEPAGE_INFO_FMT to find the file storing struct hugepage_file
- * array. This is simple but cannot be used in secondary process because
- * secondary process will close and munmap that file.
- * 2. Match HUGEFILE_FMT to find hugepage files directly.
- *
- * We choose option 2.
- */
static int
-get_hugepage_file_info(struct hugepage_file_info huges[], int max)
+update_memory_region(const struct rte_memseg_list *msl __rte_unused,
+ const struct rte_memseg *ms, void *arg)
{
- int idx, k, exist;
- FILE *f;
- char buf[BUFSIZ], *tmp, *tail;
- char *str_underline, *str_start;
- int huge_index;
- uint64_t v_start, v_end;
- struct stat stats;
-
- f = fopen("/proc/self/maps", "r");
- if (!f) {
- PMD_DRV_LOG(ERR, "cannot open /proc/self/maps");
- return -1;
- }
-
- idx = 0;
- while (fgets(buf, sizeof(buf), f) != NULL) {
- if (sscanf(buf, "%" PRIx64 "-%" PRIx64, &v_start, &v_end) < 2) {
- PMD_DRV_LOG(ERR, "Failed to parse address");
- goto error;
- }
-
- tmp = strchr(buf, ' ') + 1; /** skip address */
- tmp = strchr(tmp, ' ') + 1; /** skip perm */
- tmp = strchr(tmp, ' ') + 1; /** skip offset */
- tmp = strchr(tmp, ' ') + 1; /** skip dev */
- tmp = strchr(tmp, ' ') + 1; /** skip inode */
- while (*tmp == ' ') /** skip spaces */
- tmp++;
- tail = strrchr(tmp, '\n'); /** remove newline if exists */
- if (tail)
- *tail = '\0';
-
- /* Match HUGEFILE_FMT, aka "%s/%smap_%d",
- * which is defined in eal_filesystem.h
- */
- str_underline = strrchr(tmp, '_');
- if (!str_underline)
- continue;
-
- str_start = str_underline - strlen("map");
- if (str_start < tmp)
- continue;
-
- if (sscanf(str_start, "map_%d", &huge_index) != 1)
- continue;
-
- /* skip duplicated file which is mapped to different regions */
- for (k = 0, exist = -1; k < idx; ++k) {
- if (!strcmp(huges[k].path, tmp)) {
- exist = k;
- break;
- }
- }
- if (exist >= 0)
- continue;
-
- if (idx >= max) {
- PMD_DRV_LOG(ERR, "Exceed maximum of %d", max);
- goto error;
- }
-
- huges[idx].addr = v_start;
- huges[idx].size = v_end - v_start; /* To be corrected later */
- snprintf(huges[idx].path, PATH_MAX, "%s", tmp);
- idx++;
- }
-
- /* correct the size for files who have many regions */
- for (k = 0; k < idx; ++k) {
- if (stat(huges[k].path, &stats) < 0) {
- PMD_DRV_LOG(ERR, "Failed to stat %s, %s\n",
- huges[k].path, strerror(errno));
- continue;
- }
- huges[k].size = stats.st_size;
- PMD_DRV_LOG(INFO, "file %s, size %zx\n",
- huges[k].path, huges[k].size);
- }
-
- fclose(f);
- return idx;
-
-error:
- fclose(f);
- return -1;
-}
-
-static int
-prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[])
-{
- int i, num;
- struct hugepage_file_info huges[VHOST_MEMORY_MAX_NREGIONS];
+ struct walk_arg *wa = arg;
struct vhost_memory_region *mr;
+ uint64_t start_addr, end_addr;
+ size_t offset;
+ int i, fd;
- num = get_hugepage_file_info(huges, VHOST_MEMORY_MAX_NREGIONS);
- if (num < 0) {
- PMD_INIT_LOG(ERR, "Failed to prepare memory for vhost-user");
+ fd = rte_memseg_get_fd_thread_unsafe(ms);
+ if (fd < 0) {
+ PMD_DRV_LOG(ERR, "Failed to get fd, ms=%p rte_errno=%d",
+ ms, rte_errno);
return -1;
}
- for (i = 0; i < num; ++i) {
- mr = &msg->payload.memory.regions[i];
- mr->guest_phys_addr = huges[i].addr; /* use vaddr! */
- mr->userspace_addr = huges[i].addr;
- mr->memory_size = huges[i].size;
- mr->mmap_offset = 0;
- fds[i] = open(huges[i].path, O_RDWR);
+ if (rte_memseg_get_fd_offset_thread_unsafe(ms, &offset) < 0) {
+ PMD_DRV_LOG(ERR, "Failed to get offset, ms=%p rte_errno=%d",
+ ms, rte_errno);
+ return -1;
+ }
+
+ start_addr = (uint64_t)(uintptr_t)ms->addr;
+ end_addr = start_addr + ms->len;
+
+ for (i = 0; i < wa->region_nr; i++) {
+ if (wa->fds[i] != fd)
+ continue;
+
+ mr = &wa->vm->regions[i];
+
+ if (mr->userspace_addr + mr->memory_size < end_addr)
+ mr->memory_size = end_addr - mr->userspace_addr;
+
+ if (mr->userspace_addr > start_addr) {
+ mr->userspace_addr = start_addr;
+ mr->guest_phys_addr = start_addr;
+ }
+
+ if (mr->mmap_offset > offset)
+ mr->mmap_offset = offset;
+
+ PMD_DRV_LOG(DEBUG, "index=%d fd=%d offset=0x%" PRIx64
+ " addr=0x%" PRIx64 " len=%" PRIu64, i, fd,
+ mr->mmap_offset, mr->userspace_addr,
+ mr->memory_size);
+
+ return 0;
+ }
+
+ if (i >= VHOST_MEMORY_MAX_NREGIONS) {
+ PMD_DRV_LOG(ERR, "Too many memory regions");
+ return -1;
}
- msg->payload.memory.nregions = num;
+ mr = &wa->vm->regions[i];
+ wa->fds[i] = fd;
+
+ mr->guest_phys_addr = start_addr;
+ mr->userspace_addr = start_addr;
+ mr->memory_size = ms->len;
+ mr->mmap_offset = offset;
+
+ PMD_DRV_LOG(DEBUG, "index=%d fd=%d offset=0x%" PRIx64
+ " addr=0x%" PRIx64 " len=%" PRIu64, i, fd,
+ mr->mmap_offset, mr->userspace_addr,
+ mr->memory_size);
+
+ wa->region_nr++;
+
+ return 0;
+}
+
+static int
+prepare_vhost_memory_user(struct vhost_user_msg *msg, int fds[])
+{
+ struct walk_arg wa;
+
+ wa.region_nr = 0;
+ wa.vm = &msg->payload.memory;
+ wa.fds = fds;
+
+ /*
+ * The memory lock has already been taken by memory subsystem
+ * or virtio_user_start_device().
+ */
+ if (rte_memseg_walk_thread_unsafe(update_memory_region, &wa) < 0)
+ return -1;
+
+ msg->payload.memory.nregions = wa.region_nr;
msg->payload.memory.padding = 0;
return 0;
@@ -280,7 +253,7 @@ vhost_user_sock(struct virtio_user_dev *dev,
int need_reply = 0;
int fds[VHOST_MEMORY_MAX_NREGIONS];
int fd_num = 0;
- int i, len;
+ int len;
int vhostfd = dev->vhostfd;
RTE_SET_USED(m);
@@ -364,10 +337,6 @@ vhost_user_sock(struct virtio_user_dev *dev,
return -1;
}
- if (req == VHOST_USER_SET_MEM_TABLE)
- for (i = 0; i < fd_num; ++i)
- close(fds[i]);
-
if (need_reply) {
if (vhost_user_read(vhostfd, &msg) < 0) {
PMD_DRV_LOG(ERR, "Received msg failed: %s",
--
2.18.0
next prev parent reply other threads:[~2018-09-05 4:31 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-05 4:28 [PATCH 0/3] Some fixes/improvements for virtio-user memory table Tiwei Bie
2018-09-05 4:28 ` [PATCH 1/3] net/virtio-user: fix deadlock in memory events callback Tiwei Bie
2018-09-05 8:10 ` Sean Harte
2018-09-07 9:30 ` Burakov, Anatoly
2018-09-11 12:52 ` Maxime Coquelin
2018-09-05 4:28 ` Tiwei Bie [this message]
2018-09-07 9:39 ` [PATCH 2/3] net/virtio-user: avoid parsing process mappings Burakov, Anatoly
2018-09-07 11:35 ` Tiwei Bie
2018-09-07 12:21 ` Burakov, Anatoly
2018-09-10 3:59 ` Tiwei Bie
2018-09-17 10:17 ` Burakov, Anatoly
2018-09-17 11:57 ` Tiwei Bie
2018-09-17 13:06 ` Burakov, Anatoly
2018-09-11 12:58 ` Maxime Coquelin
2018-09-05 4:28 ` [PATCH 3/3] net/virtio-user: fix memory hotplug support in vhost-kernel Tiwei Bie
2018-09-07 9:44 ` Burakov, Anatoly
2018-09-07 11:37 ` Tiwei Bie
2018-09-07 12:24 ` Burakov, Anatoly
2018-09-10 4:04 ` Tiwei Bie
2018-09-17 10:18 ` Burakov, Anatoly
2018-09-11 13:10 ` Maxime Coquelin
2018-09-11 13:11 ` [PATCH 0/3] Some fixes/improvements for virtio-user memory table Maxime Coquelin
2018-09-20 7:35 ` Maxime Coquelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180905042852.6212-3-tiwei.bie@intel.com \
--to=tiwei.bie@intel.com \
--cc=anatoly.burakov@intel.com \
--cc=dev@dpdk.org \
--cc=maxime.coquelin@redhat.com \
--cc=seanbh@gmail.com \
--cc=zhihong.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.