mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 21:40:49 +00:00
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQEcBAABAgAGBQJXffbYAAoJEO8Ells5jWIRZnAH/2bleryOC4i6Pwz7cNpX07MQ YmJ97K6RueVcYjj7pSi4l8nzv18K0k43x04ST6WIpHbRf07RIJIBOVn/f8xUnNo/ EonhPgYWZXZX7h9EWnjUWccKU8ReQO06lUi2H7XX6f6Ba3maG2A4HCvhraE+noIr pkM4Qj6niD+i6hZsznmhuLWUE+ynt2JdmBIxxG+e12t/Hq5vW7IYPj6Y1IQia9r9 vkz2wWmmiVTty6g5d/pu8yyWt+b2ob8cQ0OoRrqr1uNF/h4uWcUlgUZEe/DJER3M u+s5xVKLM4FK+w0grBKMCDzmRsjixV42tcS0H8LABpdRce8PINOmpsO3QI+Ul5g= =YU37 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging # gpg: Signature made Thu 07 Jul 2016 07:29:44 BST # gpg: using RSA key 0xEF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: tap: vhost busy polling support Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
5563168c53
@ -172,7 +172,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
}
|
||||
|
||||
r = vhost_dev_init(&net->dev, options->opaque,
|
||||
options->backend_type);
|
||||
options->backend_type, options->busyloop_timeout);
|
||||
if (r < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
|
||||
s->dev.backend_features = 0;
|
||||
|
||||
ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
|
||||
VHOST_BACKEND_TYPE_KERNEL);
|
||||
VHOST_BACKEND_TYPE_KERNEL, 0);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
|
||||
strerror(-ret));
|
||||
|
@ -138,6 +138,12 @@ static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
|
||||
return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
|
||||
}
|
||||
|
||||
static int vhost_kernel_set_vring_busyloop_timeout(struct vhost_dev *dev,
|
||||
struct vhost_vring_state *s)
|
||||
{
|
||||
return vhost_kernel_call(dev, VHOST_SET_VRING_BUSYLOOP_TIMEOUT, s);
|
||||
}
|
||||
|
||||
static int vhost_kernel_set_features(struct vhost_dev *dev,
|
||||
uint64_t features)
|
||||
{
|
||||
@ -185,6 +191,8 @@ static const VhostOps kernel_ops = {
|
||||
.vhost_get_vring_base = vhost_kernel_get_vring_base,
|
||||
.vhost_set_vring_kick = vhost_kernel_set_vring_kick,
|
||||
.vhost_set_vring_call = vhost_kernel_set_vring_call,
|
||||
.vhost_set_vring_busyloop_timeout =
|
||||
vhost_kernel_set_vring_busyloop_timeout,
|
||||
.vhost_set_features = vhost_kernel_set_features,
|
||||
.vhost_get_features = vhost_kernel_get_features,
|
||||
.vhost_set_owner = vhost_kernel_set_owner,
|
||||
|
@ -960,6 +960,28 @@ static void vhost_eventfd_del(MemoryListener *listener,
|
||||
{
|
||||
}
|
||||
|
||||
static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
|
||||
int n, uint32_t timeout)
|
||||
{
|
||||
int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n);
|
||||
struct vhost_vring_state state = {
|
||||
.index = vhost_vq_index,
|
||||
.num = timeout,
|
||||
};
|
||||
int r;
|
||||
|
||||
if (!dev->vhost_ops->vhost_set_vring_busyloop_timeout) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = dev->vhost_ops->vhost_set_vring_busyloop_timeout(dev, &state);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vhost_virtqueue_init(struct vhost_dev *dev,
|
||||
struct vhost_virtqueue *vq, int n)
|
||||
{
|
||||
@ -990,7 +1012,7 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
|
||||
}
|
||||
|
||||
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
VhostBackendType backend_type)
|
||||
VhostBackendType backend_type, uint32_t busyloop_timeout)
|
||||
{
|
||||
uint64_t features;
|
||||
int i, r;
|
||||
@ -1031,6 +1053,17 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
goto fail_vq;
|
||||
}
|
||||
}
|
||||
|
||||
if (busyloop_timeout) {
|
||||
for (i = 0; i < hdev->nvqs; ++i) {
|
||||
r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
|
||||
busyloop_timeout);
|
||||
if (r < 0) {
|
||||
goto fail_busyloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hdev->features = features;
|
||||
|
||||
hdev->memory_listener = (MemoryListener) {
|
||||
@ -1073,6 +1106,11 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
hdev->memory_changed = false;
|
||||
memory_listener_register(&hdev->memory_listener, &address_space_memory);
|
||||
return 0;
|
||||
fail_busyloop:
|
||||
while (--i >= 0) {
|
||||
vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i, 0);
|
||||
}
|
||||
i = hdev->nvqs;
|
||||
fail_vq:
|
||||
while (--i >= 0) {
|
||||
vhost_virtqueue_cleanup(hdev->vqs + i);
|
||||
|
@ -57,6 +57,8 @@ typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
|
||||
struct vhost_vring_file *file);
|
||||
typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
|
||||
struct vhost_vring_file *file);
|
||||
typedef int (*vhost_set_vring_busyloop_timeout_op)(struct vhost_dev *dev,
|
||||
struct vhost_vring_state *r);
|
||||
typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
|
||||
uint64_t features);
|
||||
typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
|
||||
@ -91,6 +93,7 @@ typedef struct VhostOps {
|
||||
vhost_get_vring_base_op vhost_get_vring_base;
|
||||
vhost_set_vring_kick_op vhost_set_vring_kick;
|
||||
vhost_set_vring_call_op vhost_set_vring_call;
|
||||
vhost_set_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout;
|
||||
vhost_set_features_op vhost_set_features;
|
||||
vhost_get_features_op vhost_get_features;
|
||||
vhost_set_owner_op vhost_set_owner;
|
||||
|
@ -64,7 +64,8 @@ struct vhost_dev {
|
||||
};
|
||||
|
||||
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
VhostBackendType backend_type);
|
||||
VhostBackendType backend_type,
|
||||
uint32_t busyloop_timeout);
|
||||
void vhost_dev_cleanup(struct vhost_dev *hdev);
|
||||
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
|
||||
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
|
||||
|
@ -10,6 +10,7 @@ typedef struct vhost_net VHostNetState;
|
||||
typedef struct VhostNetOptions {
|
||||
VhostBackendType backend_type;
|
||||
NetClientState *net_backend;
|
||||
uint32_t busyloop_timeout;
|
||||
void *opaque;
|
||||
} VhostNetOptions;
|
||||
|
||||
|
@ -663,6 +663,11 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
|
||||
|
||||
options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
|
||||
options.net_backend = &s->nc;
|
||||
if (tap->has_poll_us) {
|
||||
options.busyloop_timeout = tap->poll_us;
|
||||
} else {
|
||||
options.busyloop_timeout = 0;
|
||||
}
|
||||
|
||||
if (vhostfdname) {
|
||||
vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
|
||||
@ -687,7 +692,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
|
||||
return;
|
||||
}
|
||||
} else if (vhostfdname) {
|
||||
error_setg(errp, "vhostfd= is not valid without vhost");
|
||||
error_setg(errp, "vhostfd(s)= is not valid without vhost");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[])
|
||||
|
||||
options.net_backend = ncs[i];
|
||||
options.opaque = s->chr;
|
||||
options.busyloop_timeout = 0;
|
||||
s->vhost_net = vhost_net_init(&options);
|
||||
if (!s->vhost_net) {
|
||||
error_report("failed to init vhost_net for queue %d", i);
|
||||
|
@ -2592,6 +2592,9 @@
|
||||
#
|
||||
# @queues: #optional number of queues to be created for multiqueue capable tap
|
||||
#
|
||||
# @poll-us: #optional maximum number of microseconds that could
|
||||
# be spent on busy polling for tap (since 2.7)
|
||||
#
|
||||
# Since 1.2
|
||||
##
|
||||
{ 'struct': 'NetdevTapOptions',
|
||||
@ -2608,7 +2611,8 @@
|
||||
'*vhostfd': 'str',
|
||||
'*vhostfds': 'str',
|
||||
'*vhostforce': 'bool',
|
||||
'*queues': 'uint32'} }
|
||||
'*queues': 'uint32',
|
||||
'*poll-us': 'uint32'} }
|
||||
|
||||
##
|
||||
# @NetdevSocketOptions
|
||||
|
@ -1581,6 +1581,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
||||
"-netdev tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]\n"
|
||||
" [,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]\n"
|
||||
" [,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]\n"
|
||||
" [,poll-us=n]\n"
|
||||
" configure a host TAP network backend with ID 'str'\n"
|
||||
" use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n"
|
||||
" to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
|
||||
@ -1600,6 +1601,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
||||
" use 'vhostfd=h' to connect to an already opened vhost net device\n"
|
||||
" use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices\n"
|
||||
" use 'queues=n' to specify the number of queues to be created for multiqueue TAP\n"
|
||||
" use 'poll-us=n' to speciy the maximum number of microseconds that could be\n"
|
||||
" spent on busy polling for vhost net\n"
|
||||
"-netdev bridge,id=str[,br=bridge][,helper=helper]\n"
|
||||
" configure a host TAP network backend with ID 'str' that is\n"
|
||||
" connected to a bridge (default=" DEFAULT_BRIDGE_INTERFACE ")\n"
|
||||
|
Loading…
Reference in New Issue
Block a user