1. Move function higher. (we anyway want to split it into two functions, and change the code a lot, so take an opportunity to get rid of extra declaration).
2. Split into _set_options() and _init_vhost(): we'll need it later to implement TAP local migration feature. 3. Split requires to store options somewhere, and to be able to call _init_vhost() later (from migriation _load() in later commit), store options in the TAPState. 4. So, take an opportunity to zero-initialize options: - be safe (avoid uninitialized options) - don't care to initialize half of the options to zero by hand 5. Also, don't worry too much about poll_us: absent option should be zero-initialized anyway. Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]> --- net/tap.c | 124 +++++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/net/tap.c b/net/tap.c index 4f3512a831..cf7f704a92 100644 --- a/net/tap.c +++ b/net/tap.c @@ -78,6 +78,7 @@ typedef struct TAPState { bool has_ufo; bool has_uso; bool enabled; + VhostNetOptions *vhost_options; VHostNetState *vhost_net; unsigned host_vnet_hdr_len; Notifier exit; @@ -95,8 +96,6 @@ static int net_tap_fd_init_common(const Netdev *netdev, NetClientState *peer, const char *downscript, const char *vhostfdname, int vnet_hdr, int fd, Error **errp); -static int net_tap_setup_vhost(TAPState *s, const NetdevTapOptions *tap, - const char *vhostfdname, Error **errp); static void tap_update_fd_handler(TAPState *s) { @@ -334,6 +333,8 @@ static void tap_cleanup(NetClientState *nc) s->vhost_net = NULL; } + g_free(s->vhost_options); + qemu_purge_queued_packets(nc); if (s->exit.notify) { @@ -697,6 +698,64 @@ static int net_tap_open_one(const Netdev *netdev, #define MAX_TAP_QUEUES 1024 +static int net_tap_set_vhost_options(TAPState *s, const NetdevTapOptions *tap, + const char *vhostfdname, Error **errp) +{ + int vhostfd; + bool vhost_on = tap->has_vhost ? tap->vhost : + vhostfdname || (tap->has_vhostforce && tap->vhostforce); + + if (!vhost_on) { + return 0; + } + + if (vhostfdname) { + vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, errp); + if (vhostfd == -1) { + return -1; + } + } else { + vhostfd = open("/dev/vhost-net", O_RDWR); + if (vhostfd < 0) { + error_setg_errno(errp, errno, + "tap: open vhost char device failed"); + return -1; + } + } + + if (!qemu_set_blocking(vhostfd, false, errp)) { + return -1; + } + + s->vhost_options = g_new(VhostNetOptions, 1); + *s->vhost_options = (VhostNetOptions) { + .backend_type = VHOST_BACKEND_TYPE_KERNEL, + .net_backend = &s->nc, + .busyloop_timeout = tap->poll_us, + .opaque = (void *)(uintptr_t)vhostfd, + .nvqs = 2, + .feature_bits = kernel_feature_bits, + }; + + return 0; +} + +static int net_tap_init_vhost(TAPState *s, Error **errp) +{ + if (!s->vhost_options) { + return 0; + } + + s->vhost_net = vhost_net_init(s->vhost_options); + if (!s->vhost_net) { + error_setg(errp, + "vhost-net requested but could not be initialized"); + return -1; + } + + return 0; +} + static int net_tap_fd_init_common(const Netdev *netdev, NetClientState *peer, const char *model, const char *name, const char *ifname, const char *script, @@ -762,7 +821,12 @@ static int net_tap_fd_init_common(const Netdev *netdev, NetClientState *peer, } } - ret = net_tap_setup_vhost(s, tap, vhostfdname, errp); + ret = net_tap_set_vhost_options(s, tap, vhostfdname, errp); + if (ret < 0) { + goto failed; + } + + ret = net_tap_init_vhost(s, errp); if (ret < 0) { goto failed; } @@ -774,60 +838,6 @@ failed: return -1; } -static int net_tap_setup_vhost(TAPState *s, const NetdevTapOptions *tap, - const char *vhostfdname, Error **errp) -{ - if (tap->has_vhost ? tap->vhost : - vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { - VhostNetOptions options; - int vhostfd; - - 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(monitor_cur(), vhostfdname, errp); - if (vhostfd == -1) { - return -1; - } - if (!qemu_set_blocking(vhostfd, false, errp)) { - return -1; - } - } else { - vhostfd = open("/dev/vhost-net", O_RDWR); - if (vhostfd < 0) { - error_setg_errno(errp, errno, - "tap: open vhost char device failed"); - return -1; - } - if (!qemu_set_blocking(vhostfd, false, errp)) { - return -1; - } - } - options.opaque = (void *)(uintptr_t)vhostfd; - options.nvqs = 2; - options.feature_bits = kernel_feature_bits; - options.get_acked_features = NULL; - options.save_acked_features = NULL; - options.max_tx_queue_size = 0; - options.is_vhost_user = false; - - s->vhost_net = vhost_net_init(&options); - if (!s->vhost_net) { - error_setg(errp, - "vhost-net requested but could not be initialized"); - return -1; - } - } - - return 0; -} - static int net_tap_from_monitor_fd(const Netdev *netdev, NetClientState *peer, const char *name, const char *vhostfdname, int *pvnet_hdr, const char *fdname, -- 2.48.1
