Message ID | 1443111741-4736-16-git-send-email-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote: > From: Thibaut Collet <thibaut.collet@6wind.com> > > A new vhost user message is added to allow QEMU to ask to vhost user backend to > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE > capability. > > This new message is sent only if the backend supports the new > VHOST_USER_PROTOCOL_F_RARP protocol feature. > The payload of this new message is the MAC address of the guest (not known by > the backend). The MAC address is copied in the first 6 bytes of a u64 to avoid > to create a new payload message type. > > This new message has no equivalent ioctl so a new callback is added in the > userOps structure to send the request. > > Upon reception of this new message the vhost user backend must generate and > broadcast a fake RARP request to notify the migration is terminated. > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com> > [Rebased and fixed checkpatch errors - Marc-André] > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > --- > docs/specs/vhost-user.txt | 15 +++++++++++++++ > hw/net/vhost_net.c | 17 +++++++++++++++++ > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++ > include/hw/virtio/vhost-backend.h | 3 +++ > include/net/vhost_net.h | 1 + > net/vhost-user.c | 24 ++++++++++++++++++++++-- > 6 files changed, 88 insertions(+), 2 deletions(-) > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt > index e0292a0..e0d71e2 100644 > --- a/docs/specs/vhost-user.txt > +++ b/docs/specs/vhost-user.txt > @@ -194,6 +194,7 @@ Protocol features > > #define VHOST_USER_PROTOCOL_F_MQ 0 > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > +#define VHOST_USER_PROTOCOL_F_RARP 2 > > Message types > ------------- > @@ -381,3 +382,17 @@ Message types > Master payload: vring state description > > Signal slave to enable or disable corresponding vring. > + > + * VHOST_USER_SEND_RARP > + > + Id: 19 > + Equivalent ioctl: N/A > + Master payload: u64 > + > + Ask vhost user backend to broadcast a fake RARP to notify the migration > + is terminated for guest that does not support GUEST_ANNOUNCE. > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present in > + VHOST_USER_GET_FEATURES and protocol feature bit VHOST_USER_PROTOCOL_F_RARP > + is present in VHOST_USER_GET_PROTOCOL_FEATURES. > + The first 6 bytes of the payload contain the mac address of the guest to > + allow the vhost user backend to construct and broadcast the fake RARP. > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > index 840f443..da66b64 100644 > --- a/hw/net/vhost_net.c > +++ b/hw/net/vhost_net.c > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) > g_free(net); > } > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) > +{ > + const VhostOps *vhost_ops = net->dev.vhost_ops; > + int r = -1; > + > + if (vhost_ops->vhost_migration_done) { > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); > + } > + > + return r; > +} > + > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) > { > return vhost_virtqueue_pending(&net->dev, idx); > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, > { > } > > +int vhost_net_notify_migration_done(struct vhost_net *net) > +{ > + return -1; > +} > + > VHostNetState *get_vhost_net(NetClientState *nc) > { > return 0; > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > index 455caba..b7f3699 100644 > --- a/hw/virtio/vhost-user.c > +++ b/hw/virtio/vhost-user.c > @@ -10,6 +10,7 @@ > > #include "hw/virtio/vhost.h" > #include "hw/virtio/vhost-backend.h" > +#include "hw/virtio/virtio-net.h" > #include "sysemu/char.h" > #include "sysemu/kvm.h" > #include "qemu/error-report.h" > @@ -30,6 +31,7 @@ > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL > #define VHOST_USER_PROTOCOL_F_MQ 0 > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > +#define VHOST_USER_PROTOCOL_F_RARP 2 The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL > > typedef enum VhostUserRequest { > VHOST_USER_NONE = 0, > @@ -51,6 +53,7 @@ typedef enum VhostUserRequest { > VHOST_USER_SET_PROTOCOL_FEATURES = 16, > VHOST_USER_GET_QUEUE_NUM = 17, > VHOST_USER_SET_VRING_ENABLE = 18, > + VHOST_USER_SEND_RARP = 19, > VHOST_USER_MAX > } VhostUserRequest; > > @@ -561,6 +564,32 @@ static bool vhost_user_requires_shm_log(struct vhost_dev *dev) > VHOST_USER_PROTOCOL_F_LOG_SHMFD); > } > > +static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr) > +{ > + VhostUserMsg msg = { 0 }; > + int err; > + > + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); > + > + /* If guest supports GUEST_ANNOUNCE do nothing */ > + if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) { > + return 0; > + } > + > + /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */ > + if (virtio_has_feature(dev->protocol_features, > + VHOST_USER_PROTOCOL_F_RARP)) { > + msg.request = VHOST_USER_SEND_RARP; > + msg.flags = VHOST_USER_VERSION; > + memcpy((char *)&msg.u64, mac_addr, 6); > + msg.size = sizeof(m.u64); > + > + err = vhost_user_write(dev, &msg, NULL, 0); > + return err; > + } > + return -1; > +} > + > const VhostOps user_ops = { > .backend_type = VHOST_BACKEND_TYPE_USER, > .vhost_backend_init = vhost_user_init, > @@ -582,4 +611,5 @@ const VhostOps user_ops = { > .vhost_get_vq_index = vhost_user_get_vq_index, > .vhost_set_vring_enable = vhost_user_set_vring_enable, > .vhost_requires_shm_log = vhost_user_requires_shm_log, > + .vhost_migration_done = vhost_user_migration_done, > }; > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h > index e07118c..5918c01 100644 > --- a/include/hw/virtio/vhost-backend.h > +++ b/include/hw/virtio/vhost-backend.h > @@ -67,6 +67,8 @@ typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx); > typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev, > int enable); > typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev); > +typedef int (*vhost_migration_done_op)(struct vhost_dev *dev, > + char *mac_addr); > > typedef struct VhostOps { > VhostBackendType backend_type; > @@ -94,6 +96,7 @@ typedef struct VhostOps { > vhost_get_vq_index_op vhost_get_vq_index; > vhost_set_vring_enable_op vhost_set_vring_enable; > vhost_requires_shm_log_op vhost_requires_shm_log; > + vhost_migration_done_op vhost_migration_done; > } VhostOps; > > extern const VhostOps user_ops; > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h > index 0188c4d..3389b41 100644 > --- a/include/net/vhost_net.h > +++ b/include/net/vhost_net.h > @@ -27,6 +27,7 @@ void vhost_net_ack_features(VHostNetState *net, uint64_t features); > bool vhost_net_virtqueue_pending(VHostNetState *net, int n); > void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, > int idx, bool mask); > +int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); > VHostNetState *get_vhost_net(NetClientState *nc); > > int vhost_set_vring_enable(NetClientState * nc, int enable); > diff --git a/net/vhost-user.c b/net/vhost-user.c > index 87917a5..cfe11b8 100644 > --- a/net/vhost-user.c > +++ b/net/vhost-user.c > @@ -106,9 +106,29 @@ err: > static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf, > size_t size) > { > - /* Discard the request that is received and managed by backend > - * by an other way. > + /* In case of RARP (message size is 60) notify backup to send a fake RARP. > + This fake RARP will be sent by backend only for guest > + without GUEST_ANNOUNCE capability. > */ > + if (size == 60) { > + VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc); > + int r; > + static int display_rarp_failure = 1; > + char mac_addr[6]; > + > + /* extract guest mac address from the RARP message */ > + memcpy(mac_addr, &buf[6], 6); > + > + r = vhost_net_notify_migration_done(s->vhost_net, mac_addr); > + > + if ((r != 0) && (display_rarp_failure)) { > + fprintf(stderr, > + "Vhost user backend fails to broadcast fake RARP\n"); > + fflush(stderr); > + display_rarp_failure = 0; > + } > + } > + > return size; > } > > -- > 2.4.3 >
Hi ----- Original Message ----- > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote: > > From: Thibaut Collet <thibaut.collet@6wind.com> > > > > A new vhost user message is added to allow QEMU to ask to vhost user > > backend to > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE > > capability. > > > > This new message is sent only if the backend supports the new > > VHOST_USER_PROTOCOL_F_RARP protocol feature. > > The payload of this new message is the MAC address of the guest (not known > > by > > the backend). The MAC address is copied in the first 6 bytes of a u64 to > > avoid > > to create a new payload message type. > > > > This new message has no equivalent ioctl so a new callback is added in the > > userOps structure to send the request. > > > > Upon reception of this new message the vhost user backend must generate and > > broadcast a fake RARP request to notify the migration is terminated. > > > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com> > > [Rebased and fixed checkpatch errors - Marc-André] > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > > --- > > docs/specs/vhost-user.txt | 15 +++++++++++++++ > > hw/net/vhost_net.c | 17 +++++++++++++++++ > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++ > > include/hw/virtio/vhost-backend.h | 3 +++ > > include/net/vhost_net.h | 1 + > > net/vhost-user.c | 24 ++++++++++++++++++++++-- > > 6 files changed, 88 insertions(+), 2 deletions(-) > > > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt > > index e0292a0..e0d71e2 100644 > > --- a/docs/specs/vhost-user.txt > > +++ b/docs/specs/vhost-user.txt > > @@ -194,6 +194,7 @@ Protocol features > > > > #define VHOST_USER_PROTOCOL_F_MQ 0 > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > > +#define VHOST_USER_PROTOCOL_F_RARP 2 > > > > Message types > > ------------- > > @@ -381,3 +382,17 @@ Message types > > Master payload: vring state description > > > > Signal slave to enable or disable corresponding vring. > > + > > + * VHOST_USER_SEND_RARP > > + > > + Id: 19 > > + Equivalent ioctl: N/A > > + Master payload: u64 > > + > > + Ask vhost user backend to broadcast a fake RARP to notify the > > migration > > + is terminated for guest that does not support GUEST_ANNOUNCE. > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present > > in > > + VHOST_USER_GET_FEATURES and protocol feature bit > > VHOST_USER_PROTOCOL_F_RARP > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES. > > + The first 6 bytes of the payload contain the mac address of the > > guest to > > + allow the vhost user backend to construct and broadcast the fake > > RARP. > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > > index 840f443..da66b64 100644 > > --- a/hw/net/vhost_net.c > > +++ b/hw/net/vhost_net.c > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) > > g_free(net); > > } > > > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) > > +{ > > + const VhostOps *vhost_ops = net->dev.vhost_ops; > > + int r = -1; > > + > > + if (vhost_ops->vhost_migration_done) { > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); > > + } > > + > > + return r; > > +} > > + > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) > > { > > return vhost_virtqueue_pending(&net->dev, idx); > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, > > VirtIODevice *dev, > > { > > } > > > > +int vhost_net_notify_migration_done(struct vhost_net *net) > > +{ > > + return -1; > > +} > > + > > VHostNetState *get_vhost_net(NetClientState *nc) > > { > > return 0; > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > > index 455caba..b7f3699 100644 > > --- a/hw/virtio/vhost-user.c > > +++ b/hw/virtio/vhost-user.c > > @@ -10,6 +10,7 @@ > > > > #include "hw/virtio/vhost.h" > > #include "hw/virtio/vhost-backend.h" > > +#include "hw/virtio/virtio-net.h" > > #include "sysemu/char.h" > > #include "sysemu/kvm.h" > > #include "qemu/error-report.h" > > @@ -30,6 +31,7 @@ > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL > > #define VHOST_USER_PROTOCOL_F_MQ 0 > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > > +#define VHOST_USER_PROTOCOL_F_RARP 2 > > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL > Good catch (too many rebases, having a test would help to prevent this kind of mistake) thanks
On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote: > Hi > > ----- Original Message ----- > > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote: > > > From: Thibaut Collet <thibaut.collet@6wind.com> > > > > > > A new vhost user message is added to allow QEMU to ask to vhost user > > > backend to > > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE > > > capability. > > > > > > This new message is sent only if the backend supports the new > > > VHOST_USER_PROTOCOL_F_RARP protocol feature. > > > The payload of this new message is the MAC address of the guest (not known > > > by > > > the backend). The MAC address is copied in the first 6 bytes of a u64 to > > > avoid > > > to create a new payload message type. > > > > > > This new message has no equivalent ioctl so a new callback is added in the > > > userOps structure to send the request. > > > > > > Upon reception of this new message the vhost user backend must generate and > > > broadcast a fake RARP request to notify the migration is terminated. > > > > > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com> > > > [Rebased and fixed checkpatch errors - Marc-André] > > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > > > --- > > > docs/specs/vhost-user.txt | 15 +++++++++++++++ > > > hw/net/vhost_net.c | 17 +++++++++++++++++ > > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++ > > > include/hw/virtio/vhost-backend.h | 3 +++ > > > include/net/vhost_net.h | 1 + > > > net/vhost-user.c | 24 ++++++++++++++++++++++-- > > > 6 files changed, 88 insertions(+), 2 deletions(-) > > > > > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt > > > index e0292a0..e0d71e2 100644 > > > --- a/docs/specs/vhost-user.txt > > > +++ b/docs/specs/vhost-user.txt > > > @@ -194,6 +194,7 @@ Protocol features > > > > > > #define VHOST_USER_PROTOCOL_F_MQ 0 > > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > > > +#define VHOST_USER_PROTOCOL_F_RARP 2 > > > > > > Message types > > > ------------- > > > @@ -381,3 +382,17 @@ Message types > > > Master payload: vring state description > > > > > > Signal slave to enable or disable corresponding vring. > > > + > > > + * VHOST_USER_SEND_RARP > > > + > > > + Id: 19 > > > + Equivalent ioctl: N/A > > > + Master payload: u64 > > > + > > > + Ask vhost user backend to broadcast a fake RARP to notify the > > > migration > > > + is terminated for guest that does not support GUEST_ANNOUNCE. > > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present > > > in > > > + VHOST_USER_GET_FEATURES and protocol feature bit > > > VHOST_USER_PROTOCOL_F_RARP > > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES. > > > + The first 6 bytes of the payload contain the mac address of the > > > guest to > > > + allow the vhost user backend to construct and broadcast the fake > > > RARP. > > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > > > index 840f443..da66b64 100644 > > > --- a/hw/net/vhost_net.c > > > +++ b/hw/net/vhost_net.c > > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) > > > g_free(net); > > > } > > > > > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) > > > +{ > > > + const VhostOps *vhost_ops = net->dev.vhost_ops; > > > + int r = -1; > > > + > > > + if (vhost_ops->vhost_migration_done) { > > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); > > > + } > > > + > > > + return r; > > > +} > > > + > > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) > > > { > > > return vhost_virtqueue_pending(&net->dev, idx); > > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, > > > VirtIODevice *dev, > > > { > > > } > > > > > > +int vhost_net_notify_migration_done(struct vhost_net *net) > > > +{ > > > + return -1; > > > +} > > > + > > > VHostNetState *get_vhost_net(NetClientState *nc) > > > { > > > return 0; > > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > > > index 455caba..b7f3699 100644 > > > --- a/hw/virtio/vhost-user.c > > > +++ b/hw/virtio/vhost-user.c > > > @@ -10,6 +10,7 @@ > > > > > > #include "hw/virtio/vhost.h" > > > #include "hw/virtio/vhost-backend.h" > > > +#include "hw/virtio/virtio-net.h" > > > #include "sysemu/char.h" > > > #include "sysemu/kvm.h" > > > #include "qemu/error-report.h" > > > @@ -30,6 +31,7 @@ > > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL > > > #define VHOST_USER_PROTOCOL_F_MQ 0 > > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > > > +#define VHOST_USER_PROTOCOL_F_RARP 2 > > > > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL > > Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be calculated based on other macros. > > Good catch (too many rebases, having a test would help to prevent this kind of mistake) > > thanks So there will be v6 with a fix?
Hi On Sun, Sep 27, 2015 at 3:12 PM, Michael S. Tsirkin <mst@redhat.com> wrote: > On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote: >> Hi >> >> ----- Original Message ----- >> > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote: >> > > From: Thibaut Collet <thibaut.collet@6wind.com> >> > > >> > > A new vhost user message is added to allow QEMU to ask to vhost user >> > > backend to >> > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE >> > > capability. >> > > >> > > This new message is sent only if the backend supports the new >> > > VHOST_USER_PROTOCOL_F_RARP protocol feature. >> > > The payload of this new message is the MAC address of the guest (not known >> > > by >> > > the backend). The MAC address is copied in the first 6 bytes of a u64 to >> > > avoid >> > > to create a new payload message type. >> > > >> > > This new message has no equivalent ioctl so a new callback is added in the >> > > userOps structure to send the request. >> > > >> > > Upon reception of this new message the vhost user backend must generate and >> > > broadcast a fake RARP request to notify the migration is terminated. >> > > >> > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com> >> > > [Rebased and fixed checkpatch errors - Marc-André] >> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> >> > > --- >> > > docs/specs/vhost-user.txt | 15 +++++++++++++++ >> > > hw/net/vhost_net.c | 17 +++++++++++++++++ >> > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++ >> > > include/hw/virtio/vhost-backend.h | 3 +++ >> > > include/net/vhost_net.h | 1 + >> > > net/vhost-user.c | 24 ++++++++++++++++++++++-- >> > > 6 files changed, 88 insertions(+), 2 deletions(-) >> > > >> > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt >> > > index e0292a0..e0d71e2 100644 >> > > --- a/docs/specs/vhost-user.txt >> > > +++ b/docs/specs/vhost-user.txt >> > > @@ -194,6 +194,7 @@ Protocol features >> > > >> > > #define VHOST_USER_PROTOCOL_F_MQ 0 >> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 >> > > +#define VHOST_USER_PROTOCOL_F_RARP 2 >> > > >> > > Message types >> > > ------------- >> > > @@ -381,3 +382,17 @@ Message types >> > > Master payload: vring state description >> > > >> > > Signal slave to enable or disable corresponding vring. >> > > + >> > > + * VHOST_USER_SEND_RARP >> > > + >> > > + Id: 19 >> > > + Equivalent ioctl: N/A >> > > + Master payload: u64 >> > > + >> > > + Ask vhost user backend to broadcast a fake RARP to notify the >> > > migration >> > > + is terminated for guest that does not support GUEST_ANNOUNCE. >> > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present >> > > in >> > > + VHOST_USER_GET_FEATURES and protocol feature bit >> > > VHOST_USER_PROTOCOL_F_RARP >> > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES. >> > > + The first 6 bytes of the payload contain the mac address of the >> > > guest to >> > > + allow the vhost user backend to construct and broadcast the fake >> > > RARP. >> > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c >> > > index 840f443..da66b64 100644 >> > > --- a/hw/net/vhost_net.c >> > > +++ b/hw/net/vhost_net.c >> > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) >> > > g_free(net); >> > > } >> > > >> > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) >> > > +{ >> > > + const VhostOps *vhost_ops = net->dev.vhost_ops; >> > > + int r = -1; >> > > + >> > > + if (vhost_ops->vhost_migration_done) { >> > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); >> > > + } >> > > + >> > > + return r; >> > > +} >> > > + >> > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) >> > > { >> > > return vhost_virtqueue_pending(&net->dev, idx); >> > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, >> > > VirtIODevice *dev, >> > > { >> > > } >> > > >> > > +int vhost_net_notify_migration_done(struct vhost_net *net) >> > > +{ >> > > + return -1; >> > > +} >> > > + >> > > VHostNetState *get_vhost_net(NetClientState *nc) >> > > { >> > > return 0; >> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c >> > > index 455caba..b7f3699 100644 >> > > --- a/hw/virtio/vhost-user.c >> > > +++ b/hw/virtio/vhost-user.c >> > > @@ -10,6 +10,7 @@ >> > > >> > > #include "hw/virtio/vhost.h" >> > > #include "hw/virtio/vhost-backend.h" >> > > +#include "hw/virtio/virtio-net.h" >> > > #include "sysemu/char.h" >> > > #include "sysemu/kvm.h" >> > > #include "qemu/error-report.h" >> > > @@ -30,6 +31,7 @@ >> > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL >> > > #define VHOST_USER_PROTOCOL_F_MQ 0 >> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 >> > > +#define VHOST_USER_PROTOCOL_F_RARP 2 >> > >> > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL >> > > Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be > calculated based on other macros. yeah, I actually thought about something like this a few days ago: https://github.com/elmarco/qemu/commit/b4e4ec2e4c78f6b12e34822d8a3f3a101d065d80 Is that what you have in mind or rather make a bit mask of all the features? Maybe the bitmask of all the features is simpler. > >> >> Good catch (too many rebases, having a test would help to prevent this kind of mistake) >> >> thanks > > So there will be v6 with a fix? If there is no further changes in the series, I guess you could fix it when cherry-picking. But if I have to send a v6, I'll include the fix. thanks
On Sun, Sep 27, 2015 at 5:13 PM, Marc-André Lureau <marcandre.lureau@gmail.com> wrote: > Hi > > On Sun, Sep 27, 2015 at 3:12 PM, Michael S. Tsirkin <mst@redhat.com> wrote: >> On Thu, Sep 24, 2015 at 05:53:05PM -0400, Marc-André Lureau wrote: >>> Hi >>> >>> ----- Original Message ----- >>> > On Thu, Sep 24, 2015 at 6:22 PM, <marcandre.lureau@redhat.com> wrote: >>> > > From: Thibaut Collet <thibaut.collet@6wind.com> >>> > > >>> > > A new vhost user message is added to allow QEMU to ask to vhost user >>> > > backend to >>> > > broadcast a fake RARP after live migration for guest without GUEST_ANNOUNCE >>> > > capability. >>> > > >>> > > This new message is sent only if the backend supports the new >>> > > VHOST_USER_PROTOCOL_F_RARP protocol feature. >>> > > The payload of this new message is the MAC address of the guest (not known >>> > > by >>> > > the backend). The MAC address is copied in the first 6 bytes of a u64 to >>> > > avoid >>> > > to create a new payload message type. >>> > > >>> > > This new message has no equivalent ioctl so a new callback is added in the >>> > > userOps structure to send the request. >>> > > >>> > > Upon reception of this new message the vhost user backend must generate and >>> > > broadcast a fake RARP request to notify the migration is terminated. >>> > > >>> > > Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com> >>> > > [Rebased and fixed checkpatch errors - Marc-André] >>> > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> >>> > > --- >>> > > docs/specs/vhost-user.txt | 15 +++++++++++++++ >>> > > hw/net/vhost_net.c | 17 +++++++++++++++++ >>> > > hw/virtio/vhost-user.c | 30 ++++++++++++++++++++++++++++++ >>> > > include/hw/virtio/vhost-backend.h | 3 +++ >>> > > include/net/vhost_net.h | 1 + >>> > > net/vhost-user.c | 24 ++++++++++++++++++++++-- >>> > > 6 files changed, 88 insertions(+), 2 deletions(-) >>> > > >>> > > diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt >>> > > index e0292a0..e0d71e2 100644 >>> > > --- a/docs/specs/vhost-user.txt >>> > > +++ b/docs/specs/vhost-user.txt >>> > > @@ -194,6 +194,7 @@ Protocol features >>> > > >>> > > #define VHOST_USER_PROTOCOL_F_MQ 0 >>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 >>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2 >>> > > >>> > > Message types >>> > > ------------- >>> > > @@ -381,3 +382,17 @@ Message types >>> > > Master payload: vring state description >>> > > >>> > > Signal slave to enable or disable corresponding vring. >>> > > + >>> > > + * VHOST_USER_SEND_RARP >>> > > + >>> > > + Id: 19 >>> > > + Equivalent ioctl: N/A >>> > > + Master payload: u64 >>> > > + >>> > > + Ask vhost user backend to broadcast a fake RARP to notify the >>> > > migration >>> > > + is terminated for guest that does not support GUEST_ANNOUNCE. >>> > > + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present >>> > > in >>> > > + VHOST_USER_GET_FEATURES and protocol feature bit >>> > > VHOST_USER_PROTOCOL_F_RARP >>> > > + is present in VHOST_USER_GET_PROTOCOL_FEATURES. >>> > > + The first 6 bytes of the payload contain the mac address of the >>> > > guest to >>> > > + allow the vhost user backend to construct and broadcast the fake >>> > > RARP. >>> > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c >>> > > index 840f443..da66b64 100644 >>> > > --- a/hw/net/vhost_net.c >>> > > +++ b/hw/net/vhost_net.c >>> > > @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) >>> > > g_free(net); >>> > > } >>> > > >>> > > +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) >>> > > +{ >>> > > + const VhostOps *vhost_ops = net->dev.vhost_ops; >>> > > + int r = -1; >>> > > + >>> > > + if (vhost_ops->vhost_migration_done) { >>> > > + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); >>> > > + } >>> > > + >>> > > + return r; >>> > > +} >>> > > + >>> > > bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) >>> > > { >>> > > return vhost_virtqueue_pending(&net->dev, idx); >>> > > @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, >>> > > VirtIODevice *dev, >>> > > { >>> > > } >>> > > >>> > > +int vhost_net_notify_migration_done(struct vhost_net *net) >>> > > +{ >>> > > + return -1; >>> > > +} >>> > > + >>> > > VHostNetState *get_vhost_net(NetClientState *nc) >>> > > { >>> > > return 0; >>> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c >>> > > index 455caba..b7f3699 100644 >>> > > --- a/hw/virtio/vhost-user.c >>> > > +++ b/hw/virtio/vhost-user.c >>> > > @@ -10,6 +10,7 @@ >>> > > >>> > > #include "hw/virtio/vhost.h" >>> > > #include "hw/virtio/vhost-backend.h" >>> > > +#include "hw/virtio/virtio-net.h" >>> > > #include "sysemu/char.h" >>> > > #include "sysemu/kvm.h" >>> > > #include "qemu/error-report.h" >>> > > @@ -30,6 +31,7 @@ >>> > > #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL >>> > > #define VHOST_USER_PROTOCOL_F_MQ 0 >>> > > #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 >>> > > +#define VHOST_USER_PROTOCOL_F_RARP 2 >>> > >>> > The VHOST_USER_PROTOCOL_FEATURE_MASK must be changed and set to 0x7ULL >>> > >> Better, change VHOST_USER_PROTOCOL_FEATURE_MASK to be >> calculated based on other macros. > > yeah, I actually thought about something like this a few days ago: > https://github.com/elmarco/qemu/commit/b4e4ec2e4c78f6b12e34822d8a3f3a101d065d80 > I agree an automatic computation of the FEATURE_MASK from the different protocol feature will avoid issues wiht rebase or merge operation. Maybe a solution like that is clearer ? -#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x7ULL -#define VHOST_USER_PROTOCOL_F_MQ 0 -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 -#define VHOST_USER_PROTOCOL_F_RARP 2 +typedef enum VhostUserProtocolFeature { +VHOST_USER_PROTOCOL_F_MQ = 0, +VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1, +VHOST_USER_PROTOCOL_F_RARP = 2, +VHOST_USER_PROTOCOL_F_MAX +} VhostUserProtocolFeature ; +#define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1) > Is that what you have in mind or rather make a bit mask of all the > features? Maybe the bitmask of all the features is simpler. > >> >>> >>> Good catch (too many rebases, having a test would help to prevent this kind of mistake) >>> >>> thanks >> >> So there will be v6 with a fix? > > If there is no further changes in the series, I guess you could fix it > when cherry-picking. But if I have to send a v6, I'll include the fix. > > thanks > > > > -- > Marc-André Lureau
hi On Sun, Sep 27, 2015 at 5:49 PM, Thibaut Collet <thibaut.collet@6wind.com> wrote: > Maybe a solution like that is clearer ? > > -#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x7ULL > -#define VHOST_USER_PROTOCOL_F_MQ 0 > -#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 > -#define VHOST_USER_PROTOCOL_F_RARP 2 > +typedef enum VhostUserProtocolFeature { > +VHOST_USER_PROTOCOL_F_MQ = 0, > +VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1, > +VHOST_USER_PROTOCOL_F_RARP = 2, > +VHOST_USER_PROTOCOL_F_MAX > +} VhostUserProtocolFeature ; > > +#define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1) I agree with that, I don't see a good reason to keep the defines.
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt index e0292a0..e0d71e2 100644 --- a/docs/specs/vhost-user.txt +++ b/docs/specs/vhost-user.txt @@ -194,6 +194,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_MQ 0 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 +#define VHOST_USER_PROTOCOL_F_RARP 2 Message types ------------- @@ -381,3 +382,17 @@ Message types Master payload: vring state description Signal slave to enable or disable corresponding vring. + + * VHOST_USER_SEND_RARP + + Id: 19 + Equivalent ioctl: N/A + Master payload: u64 + + Ask vhost user backend to broadcast a fake RARP to notify the migration + is terminated for guest that does not support GUEST_ANNOUNCE. + Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present in + VHOST_USER_GET_FEATURES and protocol feature bit VHOST_USER_PROTOCOL_F_RARP + is present in VHOST_USER_GET_PROTOCOL_FEATURES. + The first 6 bytes of the payload contain the mac address of the guest to + allow the vhost user backend to construct and broadcast the fake RARP. diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 840f443..da66b64 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -388,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net) g_free(net); } +int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) +{ + const VhostOps *vhost_ops = net->dev.vhost_ops; + int r = -1; + + if (vhost_ops->vhost_migration_done) { + r = vhost_ops->vhost_migration_done(&net->dev, mac_addr); + } + + return r; +} + bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) { return vhost_virtqueue_pending(&net->dev, idx); @@ -479,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, { } +int vhost_net_notify_migration_done(struct vhost_net *net) +{ + return -1; +} + VHostNetState *get_vhost_net(NetClientState *nc) { return 0; diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 455caba..b7f3699 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -10,6 +10,7 @@ #include "hw/virtio/vhost.h" #include "hw/virtio/vhost-backend.h" +#include "hw/virtio/virtio-net.h" #include "sysemu/char.h" #include "sysemu/kvm.h" #include "qemu/error-report.h" @@ -30,6 +31,7 @@ #define VHOST_USER_PROTOCOL_FEATURE_MASK 0x3ULL #define VHOST_USER_PROTOCOL_F_MQ 0 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 +#define VHOST_USER_PROTOCOL_F_RARP 2 typedef enum VhostUserRequest { VHOST_USER_NONE = 0, @@ -51,6 +53,7 @@ typedef enum VhostUserRequest { VHOST_USER_SET_PROTOCOL_FEATURES = 16, VHOST_USER_GET_QUEUE_NUM = 17, VHOST_USER_SET_VRING_ENABLE = 18, + VHOST_USER_SEND_RARP = 19, VHOST_USER_MAX } VhostUserRequest; @@ -561,6 +564,32 @@ static bool vhost_user_requires_shm_log(struct vhost_dev *dev) VHOST_USER_PROTOCOL_F_LOG_SHMFD); } +static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr) +{ + VhostUserMsg msg = { 0 }; + int err; + + assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); + + /* If guest supports GUEST_ANNOUNCE do nothing */ + if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) { + return 0; + } + + /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */ + if (virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_RARP)) { + msg.request = VHOST_USER_SEND_RARP; + msg.flags = VHOST_USER_VERSION; + memcpy((char *)&msg.u64, mac_addr, 6); + msg.size = sizeof(m.u64); + + err = vhost_user_write(dev, &msg, NULL, 0); + return err; + } + return -1; +} + const VhostOps user_ops = { .backend_type = VHOST_BACKEND_TYPE_USER, .vhost_backend_init = vhost_user_init, @@ -582,4 +611,5 @@ const VhostOps user_ops = { .vhost_get_vq_index = vhost_user_get_vq_index, .vhost_set_vring_enable = vhost_user_set_vring_enable, .vhost_requires_shm_log = vhost_user_requires_shm_log, + .vhost_migration_done = vhost_user_migration_done, }; diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index e07118c..5918c01 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -67,6 +67,8 @@ typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx); typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev, int enable); typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev); +typedef int (*vhost_migration_done_op)(struct vhost_dev *dev, + char *mac_addr); typedef struct VhostOps { VhostBackendType backend_type; @@ -94,6 +96,7 @@ typedef struct VhostOps { vhost_get_vq_index_op vhost_get_vq_index; vhost_set_vring_enable_op vhost_set_vring_enable; vhost_requires_shm_log_op vhost_requires_shm_log; + vhost_migration_done_op vhost_migration_done; } VhostOps; extern const VhostOps user_ops; diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 0188c4d..3389b41 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -27,6 +27,7 @@ void vhost_net_ack_features(VHostNetState *net, uint64_t features); bool vhost_net_virtqueue_pending(VHostNetState *net, int n); void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, int idx, bool mask); +int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); VHostNetState *get_vhost_net(NetClientState *nc); int vhost_set_vring_enable(NetClientState * nc, int enable); diff --git a/net/vhost-user.c b/net/vhost-user.c index 87917a5..cfe11b8 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -106,9 +106,29 @@ err: static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf, size_t size) { - /* Discard the request that is received and managed by backend - * by an other way. + /* In case of RARP (message size is 60) notify backup to send a fake RARP. + This fake RARP will be sent by backend only for guest + without GUEST_ANNOUNCE capability. */ + if (size == 60) { + VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc); + int r; + static int display_rarp_failure = 1; + char mac_addr[6]; + + /* extract guest mac address from the RARP message */ + memcpy(mac_addr, &buf[6], 6); + + r = vhost_net_notify_migration_done(s->vhost_net, mac_addr); + + if ((r != 0) && (display_rarp_failure)) { + fprintf(stderr, + "Vhost user backend fails to broadcast fake RARP\n"); + fflush(stderr); + display_rarp_failure = 0; + } + } + return size; }