vhost-user: keep vhost_net after a disconnection
Many code paths assume get_vhost_net() returns non-null. Keep VhostUserState.vhost_net after a successful vhost_net_init(), instead of freeing it in vhost_net_cleanup(). VhostUserState.vhost_net is thus freed before after being recreated or on final vhost_user_cleanup() and there is no need to save the acked features. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
c4843a45e3
commit
e6bcb1b617
@ -378,7 +378,6 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
|
||||
void vhost_net_cleanup(struct vhost_net *net)
|
||||
{
|
||||
vhost_dev_cleanup(&net->dev);
|
||||
g_free(net);
|
||||
}
|
||||
|
||||
int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
|
||||
|
@ -312,6 +312,7 @@ static void tap_cleanup(NetClientState *nc)
|
||||
|
||||
if (s->vhost_net) {
|
||||
vhost_net_cleanup(s->vhost_net);
|
||||
g_free(s->vhost_net);
|
||||
s->vhost_net = NULL;
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,6 @@ uint64_t vhost_user_get_acked_features(NetClientState *nc)
|
||||
return s->acked_features;
|
||||
}
|
||||
|
||||
static int vhost_user_running(VhostUserState *s)
|
||||
{
|
||||
return (s->vhost_net) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void vhost_user_stop(int queues, NetClientState *ncs[])
|
||||
{
|
||||
VhostUserState *s;
|
||||
@ -59,15 +54,14 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
|
||||
assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
|
||||
|
||||
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
||||
if (!vhost_user_running(s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->vhost_net) {
|
||||
/* save acked features */
|
||||
s->acked_features = vhost_net_get_acked_features(s->vhost_net);
|
||||
uint64_t features = vhost_net_get_acked_features(s->vhost_net);
|
||||
if (features) {
|
||||
s->acked_features = features;
|
||||
}
|
||||
vhost_net_cleanup(s->vhost_net);
|
||||
s->vhost_net = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,6 +69,7 @@ static void vhost_user_stop(int queues, NetClientState *ncs[])
|
||||
static int vhost_user_start(int queues, NetClientState *ncs[])
|
||||
{
|
||||
VhostNetOptions options;
|
||||
struct vhost_net *net = NULL;
|
||||
VhostUserState *s;
|
||||
int max_queues;
|
||||
int i;
|
||||
@ -85,33 +80,39 @@ static int vhost_user_start(int queues, NetClientState *ncs[])
|
||||
assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
|
||||
|
||||
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
||||
if (vhost_user_running(s)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
options.net_backend = ncs[i];
|
||||
options.opaque = s->chr;
|
||||
options.busyloop_timeout = 0;
|
||||
s->vhost_net = vhost_net_init(&options);
|
||||
if (!s->vhost_net) {
|
||||
net = vhost_net_init(&options);
|
||||
if (!net) {
|
||||
error_report("failed to init vhost_net for queue %d", i);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
max_queues = vhost_net_get_max_queues(s->vhost_net);
|
||||
max_queues = vhost_net_get_max_queues(net);
|
||||
if (queues > max_queues) {
|
||||
error_report("you are asking more queues than supported: %d",
|
||||
max_queues);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->vhost_net) {
|
||||
vhost_net_cleanup(s->vhost_net);
|
||||
g_free(s->vhost_net);
|
||||
}
|
||||
s->vhost_net = net;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
vhost_user_stop(i + 1, ncs);
|
||||
if (net) {
|
||||
vhost_net_cleanup(net);
|
||||
}
|
||||
vhost_user_stop(i, ncs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -150,6 +151,7 @@ static void vhost_user_cleanup(NetClientState *nc)
|
||||
|
||||
if (s->vhost_net) {
|
||||
vhost_net_cleanup(s->vhost_net);
|
||||
g_free(s->vhost_net);
|
||||
s->vhost_net = NULL;
|
||||
}
|
||||
if (s->chr) {
|
||||
|
Loading…
Reference in New Issue
Block a user