The vhost crypto zero-copy feature relies on the RTE_VHOST_USER_ASYNC_COPY flag to enable guest page tracking (guest_pages array population and MAP_POPULATE during mmap).
Introduce a RTE_VHOST_USER_MAP_POPULATE flag that maps to RTE_VHOST_USER_ASYNC_COPY at this point in time. Adjust vhost_crypto example and remove the unnecessary ALLOW_EXPERIMENTAL_API flag as this example does not use any experimental APIs. Signed-off-by: David Marchand <[email protected]> Reviewed-by: Maxime Coquelin <[email protected]> --- Changes since v2: - updated release notes for new flag, - fixed checks on map populate feature, --- doc/guides/prog_guide/vhost_lib.rst | 9 +++++++++ doc/guides/rel_notes/release_26_11.rst | 4 ++++ examples/vhost_crypto/Makefile | 1 - examples/vhost_crypto/main.c | 2 +- examples/vhost_crypto/meson.build | 1 - lib/vhost/rte_vhost.h | 1 + lib/vhost/socket.c | 19 +++++++++++++++---- lib/vhost/vhost.h | 1 + lib/vhost/vhost_user.c | 4 ++-- 9 files changed, 33 insertions(+), 9 deletions(-) diff --git a/doc/guides/prog_guide/vhost_lib.rst b/doc/guides/prog_guide/vhost_lib.rst index 345a621716..2bea814a62 100644 --- a/doc/guides/prog_guide/vhost_lib.rst +++ b/doc/guides/prog_guide/vhost_lib.rst @@ -118,6 +118,15 @@ The following is an overview of some key Vhost API functions: It is disabled by default. + - ``RTE_VHOST_USER_MAP_POPULATE`` + + Guest memory regions will be mapped with ``MAP_POPULATE`` when this flag + is set, pre-faulting pages into memory. This is useful for applications + requiring direct access to guest memory, such as vhost-crypto zero-copy + operations. + + It is disabled by default. + - ``RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS`` Since v16.04, the vhost library forwards checksum and gso requests for diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index 030bd84cea..ecc575ff09 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -309,6 +309,10 @@ API Changes ``rte_event_port_profile_links_get`` and ``rte_event_port_profile_unlink`` +* vhost: Introduced ``RTE_VHOST_USER_MAP_POPULATE`` as a replacement of + ``RTE_VHOST_USER_ASYNC_COPY`` for users that did not rely on the vhost + async copy feature but expected guest pages to be prefaulted. + * reorder: Promoted the following API from experimental to stable: ``rte_reorder_seqn``, ``rte_reorder_drain_up_to_seqn``, ``rte_reorder_min_seqn_set`` and ``rte_reorder_memory_footprint_get``. diff --git a/examples/vhost_crypto/Makefile b/examples/vhost_crypto/Makefile index cc7f2abb90..130953c38e 100644 --- a/examples/vhost_crypto/Makefile +++ b/examples/vhost_crypto/Makefile @@ -6,7 +6,6 @@ APP = vhost-crypto # all source are stored in SRCS-y SRCS-y := main.c -CFLAGS += -DALLOW_EXPERIMENTAL_API PKGCONF ?= pkg-config diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c index 8bdfc40c4b..53bd8fa825 100644 --- a/examples/vhost_crypto/main.c +++ b/examples/vhost_crypto/main.c @@ -623,7 +623,7 @@ main(int argc, char *argv[]) for (j = 0; j < lo->nb_sockets; j++) { ret = rte_vhost_driver_register(lo->socket_files[j], - RTE_VHOST_USER_ASYNC_COPY); + RTE_VHOST_USER_MAP_POPULATE); if (ret < 0) { RTE_LOG(ERR, USER1, "socket %s already exists\n", lo->socket_files[j]); diff --git a/examples/vhost_crypto/meson.build b/examples/vhost_crypto/meson.build index 1c294c286f..47c8fa829f 100644 --- a/examples/vhost_crypto/meson.build +++ b/examples/vhost_crypto/meson.build @@ -6,7 +6,6 @@ # To build this example as a standalone application with an already-installed # DPDK instance, use 'make' -allow_experimental_apis = true deps += ['vhost', 'cryptodev'] sources = files( 'main.c', diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h index a7f9700538..095f9b6d3c 100644 --- a/lib/vhost/rte_vhost.h +++ b/lib/vhost/rte_vhost.h @@ -39,6 +39,7 @@ extern "C" { /* support only linear buffers (no chained mbufs) */ #define RTE_VHOST_USER_LINEARBUF_SUPPORT (1ULL << 6) #define RTE_VHOST_USER_ASYNC_COPY (1ULL << 7) +#define RTE_VHOST_USER_MAP_POPULATE RTE_VHOST_USER_ASYNC_COPY #define RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS (1ULL << 8) #define RTE_VHOST_USER_NET_STATS_ENABLE (1ULL << 9) #define RTE_VHOST_USER_ASYNC_CONNECT (1ULL << 10) diff --git a/lib/vhost/socket.c b/lib/vhost/socket.c index 0943b3e9bb..956f3b2d71 100644 --- a/lib/vhost/socket.c +++ b/lib/vhost/socket.c @@ -44,6 +44,7 @@ struct vhost_user_socket { bool extbuf; bool linearbuf; bool async_copy; + bool map_populate; bool net_compliant_ol_flags; bool stats_enabled; bool async_connect; @@ -246,6 +247,13 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) dev->async_copy = 1; } + if (vsocket->map_populate) { + dev = get_device(vid); + + if (dev) + dev->map_populate = 1; + } + VHOST_CONFIG_LOG(vsocket->path, INFO, "new device, handle is %d", vid); if (vsocket->notify_ops->new_connection) { @@ -937,6 +945,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags) vsocket->extbuf = flags & RTE_VHOST_USER_EXTBUF_SUPPORT; vsocket->linearbuf = flags & RTE_VHOST_USER_LINEARBUF_SUPPORT; vsocket->async_copy = flags & RTE_VHOST_USER_ASYNC_COPY; + vsocket->map_populate = flags & RTE_VHOST_USER_MAP_POPULATE; vsocket->net_compliant_ol_flags = flags & RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS; vsocket->stats_enabled = flags & RTE_VHOST_USER_NET_STATS_ENABLE; vsocket->async_connect = flags & RTE_VHOST_USER_ASYNC_CONNECT; @@ -945,9 +954,10 @@ rte_vhost_driver_register(const char *path, uint64_t flags) else vsocket->iommu_support = flags & RTE_VHOST_USER_IOMMU_SUPPORT; - if (vsocket->async_copy && (vsocket->iommu_support || + if (vsocket->map_populate && (vsocket->iommu_support || (flags & RTE_VHOST_USER_POSTCOPY_SUPPORT))) { - VHOST_CONFIG_LOG(path, ERR, "async copy with IOMMU or post-copy not supported"); + VHOST_CONFIG_LOG(path, ERR, + "guest pages prefaulting not supported with IOMMU or post-copy"); goto out_mutex; } @@ -973,10 +983,11 @@ rte_vhost_driver_register(const char *path, uint64_t flags) vsocket->protocol_features = VHOST_USER_PROTOCOL_FEATURES; } - if (vsocket->async_copy) { + if (vsocket->map_populate) { vsocket->supported_features &= ~(1ULL << VHOST_F_LOG_ALL); vsocket->features &= ~(1ULL << VHOST_F_LOG_ALL); - VHOST_CONFIG_LOG(path, INFO, "logging feature is disabled in async copy mode"); + VHOST_CONFIG_LOG(path, INFO, + "logging feature is disabled with guest pages prefaulting"); } /* diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h index bb4708aed5..7b5c6ccbe2 100644 --- a/lib/vhost/vhost.h +++ b/lib/vhost/vhost.h @@ -499,6 +499,7 @@ struct __rte_cache_aligned virtio_net { RTE_ATOMIC(int16_t) broadcast_rarp; uint32_t nr_vring; int async_copy; + int map_populate; int extbuf; int linearbuf; diff --git a/lib/vhost/vhost_user.c b/lib/vhost/vhost_user.c index 020c993b29..e87ab82e63 100644 --- a/lib/vhost/vhost_user.c +++ b/lib/vhost/vhost_user.c @@ -1384,7 +1384,7 @@ vhost_user_mmap_region(struct virtio_net *dev, return -1; } - populate = dev->async_copy ? MAP_POPULATE : 0; + populate = dev->map_populate ? MAP_POPULATE : 0; mmap_addr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED | populate, region->fd, 0); @@ -1398,7 +1398,7 @@ vhost_user_mmap_region(struct virtio_net *dev, region->host_user_addr = (uint64_t)(uintptr_t)mmap_addr + mmap_offset; mem_set_dump(dev, mmap_addr, mmap_size, false, alignment); - if (dev->async_copy) { + if (dev->map_populate) { if (add_guest_pages(dev, region, alignment) < 0) { VHOST_CONFIG_LOG(dev->ifname, ERR, "adding guest pages to region failed."); -- 2.54.0

