From 50510ea2c2960cc48e9cc1676dde88b849933b6e Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 27 Feb 2019 13:24:05 +0000 Subject: [PATCH] net: Introduce announce timer The 'announce timer' will be used by migration, and explicit requests for qemu to perform network announces. Based on the work by Germano Veit Michel and Vlad Yasevich Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/announce.h | 39 +++++++++++++++++++++++++++ include/qemu/typedefs.h | 1 + migration/migration.c | 1 + net/Makefile.objs | 1 + net/announce.c | 60 +++++++++++++++++++++++++++++++++++++++++ qapi/net.json | 23 ++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 include/net/announce.h create mode 100644 net/announce.c diff --git a/include/net/announce.h b/include/net/announce.h new file mode 100644 index 0000000000..b89f1c28b5 --- /dev/null +++ b/include/net/announce.h @@ -0,0 +1,39 @@ +/* + * Self-announce facility + * (c) 2017-2019 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef QEMU_NET_ANNOUNCE_H +#define QEMU_NET_ANNOUNCE_H + +#include "qemu-common.h" +#include "qapi/qapi-types-net.h" +#include "qemu/timer.h" + +struct AnnounceTimer { + QEMUTimer *tm; + AnnounceParameters params; + QEMUClockType type; + int round; +}; + +/* Returns: update the timer to the next time point */ +int64_t qemu_announce_timer_step(AnnounceTimer *timer); + +/* Delete the underlying timer */ +void qemu_announce_timer_del(AnnounceTimer *timer); + +/* + * Under BQL/main thread + * Reset the timer to the given parameters/type/notifier. + */ +void qemu_announce_timer_reset(AnnounceTimer *timer, + AnnounceParameters *params, + QEMUClockType type, + QEMUTimerCB *cb, + void *opaque); + +#endif diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 5d1a2d8329..e4a0a656d1 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -8,6 +8,7 @@ typedef struct AdapterInfo AdapterInfo; typedef struct AddressSpace AddressSpace; typedef struct AioContext AioContext; +typedef struct AnnounceTimer AnnounceTimer; typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; typedef struct BdrvDirtyBitmapIter BdrvDirtyBitmapIter; typedef struct BlockBackend BlockBackend; diff --git a/migration/migration.c b/migration/migration.c index 37e06b76dc..a9c4c6f01d 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -45,6 +45,7 @@ #include "migration/colo.h" #include "hw/boards.h" #include "monitor/monitor.h" +#include "net/announce.h" #define MAX_THROTTLE (32 << 20) /* Migration transfer speed throttling */ diff --git a/net/Makefile.objs b/net/Makefile.objs index df2b409066..8262f033b9 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -2,6 +2,7 @@ common-obj-y = net.o queue.o checksum.o util.o hub.o common-obj-y += socket.o common-obj-y += dump.o common-obj-y += eth.o +common-obj-y += announce.o common-obj-$(CONFIG_L2TPV3) += l2tpv3.o common-obj-$(call land,$(CONFIG_VIRTIO_NET),$(CONFIG_VHOST_NET_USER)) += vhost-user.o common-obj-$(call land,$(call lnot,$(CONFIG_VIRTIO_NET)),$(CONFIG_VHOST_NET_USER)) += vhost-user-stub.o diff --git a/net/announce.c b/net/announce.c new file mode 100644 index 0000000000..8876eb62b6 --- /dev/null +++ b/net/announce.c @@ -0,0 +1,60 @@ +/* + * Self-announce + * (c) 2017-2019 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "net/announce.h" +#include "qapi/clone-visitor.h" +#include "qapi/qapi-visit-net.h" + +int64_t qemu_announce_timer_step(AnnounceTimer *timer) +{ + int64_t step; + + step = timer->params.initial + + (timer->params.rounds - timer->round - 1) * + timer->params.step; + + if (step < 0 || step > timer->params.max) { + step = timer->params.max; + } + timer_mod(timer->tm, qemu_clock_get_ms(timer->type) + step); + + return step; +} + +void qemu_announce_timer_del(AnnounceTimer *timer) +{ + if (timer->tm) { + timer_del(timer->tm); + timer_free(timer->tm); + timer->tm = NULL; + } +} + +/* + * Under BQL/main thread + * Reset the timer to the given parameters/type/notifier. + */ +void qemu_announce_timer_reset(AnnounceTimer *timer, + AnnounceParameters *params, + QEMUClockType type, + QEMUTimerCB *cb, + void *opaque) +{ + /* + * We're under the BQL, so the current timer can't + * be firing, so we should be able to delete it. + */ + qemu_announce_timer_del(timer); + + QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params); + timer->round = params->rounds; + timer->type = type; + timer->tm = timer_new_ms(type, cb, opaque); +} diff --git a/qapi/net.json b/qapi/net.json index a1a0f39f74..5face0c14b 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -684,3 +684,26 @@ ## { 'event': 'NIC_RX_FILTER_CHANGED', 'data': { '*name': 'str', 'path': 'str' } } + +## +# @AnnounceParameters: +# +# Parameters for self-announce timers +# +# @initial: Initial delay (in ms) before sending the first GARP/RARP +# announcement +# +# @max: Maximum delay (in ms) between GARP/RARP announcement packets +# +# @rounds: Number of self-announcement attempts +# +# @step: Delay increase (in ms) after each self-announcement attempt +# +# Since: 4.0 +## + +{ 'struct': 'AnnounceParameters', + 'data': { 'initial': 'int', + 'max': 'int', + 'rounds': 'int', + 'step': 'int' } }