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)
|
void vhost_net_cleanup(struct vhost_net *net)
|
||||||
{
|
{
|
||||||
vhost_dev_cleanup(&net->dev);
|
vhost_dev_cleanup(&net->dev);
|
||||||
g_free(net);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
|
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) {
|
if (s->vhost_net) {
|
||||||
vhost_net_cleanup(s->vhost_net);
|
vhost_net_cleanup(s->vhost_net);
|
||||||
|
g_free(s->vhost_net);
|
||||||
s->vhost_net = NULL;
|
s->vhost_net = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +45,6 @@ uint64_t vhost_user_get_acked_features(NetClientState *nc)
|
|||||||
return s->acked_features;
|
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[])
|
static void vhost_user_stop(int queues, NetClientState *ncs[])
|
||||||
{
|
{
|
||||||
VhostUserState *s;
|
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);
|
assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
|
||||||
|
|
||||||
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
||||||
if (!vhost_user_running(s)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->vhost_net) {
|
if (s->vhost_net) {
|
||||||
/* save acked features */
|
/* 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);
|
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[])
|
static int vhost_user_start(int queues, NetClientState *ncs[])
|
||||||
{
|
{
|
||||||
VhostNetOptions options;
|
VhostNetOptions options;
|
||||||
|
struct vhost_net *net = NULL;
|
||||||
VhostUserState *s;
|
VhostUserState *s;
|
||||||
int max_queues;
|
int max_queues;
|
||||||
int i;
|
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);
|
assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER);
|
||||||
|
|
||||||
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
s = DO_UPCAST(VhostUserState, nc, ncs[i]);
|
||||||
if (vhost_user_running(s)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
options.net_backend = ncs[i];
|
options.net_backend = ncs[i];
|
||||||
options.opaque = s->chr;
|
options.opaque = s->chr;
|
||||||
options.busyloop_timeout = 0;
|
options.busyloop_timeout = 0;
|
||||||
s->vhost_net = vhost_net_init(&options);
|
net = vhost_net_init(&options);
|
||||||
if (!s->vhost_net) {
|
if (!net) {
|
||||||
error_report("failed to init vhost_net for queue %d", i);
|
error_report("failed to init vhost_net for queue %d", i);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0) {
|
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) {
|
if (queues > max_queues) {
|
||||||
error_report("you are asking more queues than supported: %d",
|
error_report("you are asking more queues than supported: %d",
|
||||||
max_queues);
|
max_queues);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->vhost_net) {
|
||||||
|
vhost_net_cleanup(s->vhost_net);
|
||||||
|
g_free(s->vhost_net);
|
||||||
|
}
|
||||||
|
s->vhost_net = net;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
vhost_user_stop(i + 1, ncs);
|
if (net) {
|
||||||
|
vhost_net_cleanup(net);
|
||||||
|
}
|
||||||
|
vhost_user_stop(i, ncs);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +151,7 @@ static void vhost_user_cleanup(NetClientState *nc)
|
|||||||
|
|
||||||
if (s->vhost_net) {
|
if (s->vhost_net) {
|
||||||
vhost_net_cleanup(s->vhost_net);
|
vhost_net_cleanup(s->vhost_net);
|
||||||
|
g_free(s->vhost_net);
|
||||||
s->vhost_net = NULL;
|
s->vhost_net = NULL;
|
||||||
}
|
}
|
||||||
if (s->chr) {
|
if (s->chr) {
|
||||||
|
Loading…
Reference in New Issue
Block a user