git.droids-corp.org
/
dpdk.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
net/virtio-user: fix memory hotplug support in vhost-kernel
[dpdk.git]
/
drivers
/
net
/
virtio
/
virtio_user
/
vhost_kernel.c
diff --git
a/drivers/net/virtio/virtio_user/vhost_kernel.c
b/drivers/net/virtio/virtio_user/vhost_kernel.c
index
b244409
..
b3bfcb7
100644
(file)
--- a/
drivers/net/virtio/virtio_user/vhost_kernel.c
+++ b/
drivers/net/virtio/virtio_user/vhost_kernel.c
@@
-70,41
+70,41
@@
static uint64_t vhost_req_user_to_kernel[] = {
[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
};
[VHOST_USER_SET_MEM_TABLE] = VHOST_SET_MEM_TABLE,
};
-struct walk_arg {
- struct vhost_memory_kernel *vm;
- uint32_t region_nr;
-};
static int
static int
-add_memory_region(const struct rte_memseg_list *msl __rte_unused,
- const struct rte_memseg *ms, size_t len, void *arg)
+add_memseg_list(const struct rte_memseg_list *msl, void *arg)
{
{
- struct
walk_arg *wa
= arg;
+ struct
vhost_memory_kernel *vm
= arg;
struct vhost_memory_region *mr;
void *start_addr;
struct vhost_memory_region *mr;
void *start_addr;
+ uint64_t len;
- if (
wa->region_nr
>= max_regions)
+ if (
vm->nregions
>= max_regions)
return -1;
return -1;
- mr = &wa->vm->regions[wa->region_nr++];
- start_addr = ms->addr;
+ start_addr = msl->base_va;
+ len = msl->page_sz * msl->memseg_arr.len;
+
+ mr = &vm->regions[vm->nregions++];
mr->guest_phys_addr = (uint64_t)(uintptr_t)start_addr;
mr->userspace_addr = (uint64_t)(uintptr_t)start_addr;
mr->memory_size = len;
mr->guest_phys_addr = (uint64_t)(uintptr_t)start_addr;
mr->userspace_addr = (uint64_t)(uintptr_t)start_addr;
mr->memory_size = len;
- mr->mmap_offset = 0;
+ mr->mmap_offset = 0; /* flags_padding */
+
+ PMD_DRV_LOG(DEBUG, "index=%u addr=%p len=%" PRIu64,
+ vm->nregions - 1, start_addr, len);
return 0;
}
return 0;
}
-/* By default, vhost kernel module allows 64 regions, but DPDK
allows
- *
256 segments. As a relief, below function merges those virtually
- *
adjacent memsegs into
one region.
+/* By default, vhost kernel module allows 64 regions, but DPDK
may
+ *
have much more memory regions. Below function will treat each
+ *
contiguous memory space reserved by DPDK as
one region.
*/
static struct vhost_memory_kernel *
prepare_vhost_memory_kernel(void)
{
struct vhost_memory_kernel *vm;
*/
static struct vhost_memory_kernel *
prepare_vhost_memory_kernel(void)
{
struct vhost_memory_kernel *vm;
- struct walk_arg wa;
vm = malloc(sizeof(struct vhost_memory_kernel) +
max_regions *
vm = malloc(sizeof(struct vhost_memory_kernel) +
max_regions *
@@
-112,16
+112,18
@@
prepare_vhost_memory_kernel(void)
if (!vm)
return NULL;
if (!vm)
return NULL;
-
wa.region_nr
= 0;
-
wa.vm = vm
;
+
vm->nregions
= 0;
+
vm->padding = 0
;
- if (rte_memseg_contig_walk(add_memory_region, &wa) < 0) {
+ /*
+ * The memory lock has already been taken by memory subsystem
+ * or virtio_user_start_device().
+ */
+ if (rte_memseg_list_walk_thread_unsafe(add_memseg_list, vm) < 0) {
free(vm);
return NULL;
}
free(vm);
return NULL;
}
- vm->nregions = wa.region_nr;
- vm->padding = 0;
return vm;
}
return vm;
}
@@
-147,8
+149,8
@@
prepare_vhost_memory_kernel(void)
(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
(1ULL << VIRTIO_NET_F_CSUM))
(1ULL << VIRTIO_NET_F_HOST_TSO6) | \
(1ULL << VIRTIO_NET_F_CSUM))
-static int
-tap_support
e_mq
(void)
+static
unsigned
int
+tap_support
_features
(void)
{
int tapfd;
unsigned int tap_features;
{
int tapfd;
unsigned int tap_features;
@@
-167,7
+169,7
@@
tap_supporte_mq(void)
}
close(tapfd);
}
close(tapfd);
- return tap_features
& IFF_MULTI_QUEUE
;
+ return tap_features;
}
static int
}
static int
@@
-181,6
+183,7
@@
vhost_kernel_ioctl(struct virtio_user_dev *dev,
struct vhost_memory_kernel *vm = NULL;
int vhostfd;
unsigned int queue_sel;
struct vhost_memory_kernel *vm = NULL;
int vhostfd;
unsigned int queue_sel;
+ unsigned int features;
PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]);
@@
-234,17
+237,20
@@
vhost_kernel_ioctl(struct virtio_user_dev *dev,
}
if (!ret && req_kernel == VHOST_GET_FEATURES) {
}
if (!ret && req_kernel == VHOST_GET_FEATURES) {
+ features = tap_support_features();
/* with tap as the backend, all these features are supported
* but not claimed by vhost-net, so we add them back when
* reporting to upper layer.
*/
/* with tap as the backend, all these features are supported
* but not claimed by vhost-net, so we add them back when
* reporting to upper layer.
*/
- *((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
- *((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
+ if (features & IFF_VNET_HDR) {
+ *((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK;
+ *((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK;
+ }
/* vhost_kernel will not declare this feature, but it does
* support multi-queue.
*/
/* vhost_kernel will not declare this feature, but it does
* support multi-queue.
*/
- if (
tap_supporte_mq()
)
+ if (
features & IFF_MULTI_QUEUE
)
*(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ);
}
*(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ);
}
@@
-339,7
+345,7
@@
vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev,
hdr_size = sizeof(struct virtio_net_hdr);
tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, req_mq,
hdr_size = sizeof(struct virtio_net_hdr);
tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, req_mq,
- (char *)dev->mac_addr);
+ (char *)dev->mac_addr
, dev->features
);
if (tapfd < 0) {
PMD_DRV_LOG(ERR, "fail to open tap for vhost kernel");
return -1;
if (tapfd < 0) {
PMD_DRV_LOG(ERR, "fail to open tap for vhost kernel");
return -1;