From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Subject: [Qemu-devel] [PULL 03/48] qemu-timer: introduce timer attributes
Date: Thu, 18 Oct 2018 22:31:30 +0200 [thread overview]
Message-ID: <1539894735-14232-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1539894735-14232-1-git-send-email-pbonzini@redhat.com>
From: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Attributes are simple flags, associated with individual timers for their
whole lifetime. They intended to be used to mark individual timers for
special handling when they fire.
New/init functions family in timer interface updated and refactored (new
'attribute' argument added, timer_list replaced with timer_list_group+type
combinations, comments improved to avoid info duplication). Also existing
aio interface extended with attribute-enabled variants of functions,
which create/initialize timers.
Signed-off-by: Artem Pisarenko <artem.k.pisarenko@gmail.com>
Message-Id: <f47b81dbce734e9806f9516eba8ca588e6321c2f.1539764043.git.artem.k.pisarenko@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/block/aio.h | 59 ++++++++++++++++++++++---
include/qemu/timer.h | 109 +++++++++++++++++++++++-----------------------
tests/ptimer-test-stubs.c | 13 ++++--
util/qemu-timer.c | 13 ++++--
4 files changed, 124 insertions(+), 70 deletions(-)
diff --git a/include/block/aio.h b/include/block/aio.h
index f08630c..0ca25df 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -388,18 +388,41 @@ struct LinuxAioState *aio_setup_linux_aio(AioContext *ctx, Error **errp);
struct LinuxAioState *aio_get_linux_aio(AioContext *ctx);
/**
- * aio_timer_new:
+ * aio_timer_new_with_attrs:
* @ctx: the aio context
* @type: the clock type
* @scale: the scale
+ * @attributes: 0, or one to multiple OR'ed QEMU_TIMER_ATTR_<id> values
+ * to assign
* @cb: the callback to call on timer expiry
* @opaque: the opaque pointer to pass to the callback
*
- * Allocate a new timer attached to the context @ctx.
+ * Allocate a new timer (with attributes) attached to the context @ctx.
* The function is responsible for memory allocation.
*
- * The preferred interface is aio_timer_init. Use that
- * unless you really need dynamic memory allocation.
+ * The preferred interface is aio_timer_init or aio_timer_init_with_attrs.
+ * Use that unless you really need dynamic memory allocation.
+ *
+ * Returns: a pointer to the new timer
+ */
+static inline QEMUTimer *aio_timer_new_with_attrs(AioContext *ctx,
+ QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque)
+{
+ return timer_new_full(&ctx->tlg, type, scale, attributes, cb, opaque);
+}
+
+/**
+ * aio_timer_new:
+ * @ctx: the aio context
+ * @type: the clock type
+ * @scale: the scale
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Allocate a new timer attached to the context @ctx.
+ * See aio_timer_new_with_attrs for details.
*
* Returns: a pointer to the new timer
*/
@@ -407,7 +430,29 @@ static inline QEMUTimer *aio_timer_new(AioContext *ctx, QEMUClockType type,
int scale,
QEMUTimerCB *cb, void *opaque)
{
- return timer_new_tl(ctx->tlg.tl[type], scale, cb, opaque);
+ return timer_new_full(&ctx->tlg, type, scale, 0, cb, opaque);
+}
+
+/**
+ * aio_timer_init_with_attrs:
+ * @ctx: the aio context
+ * @ts: the timer
+ * @type: the clock type
+ * @scale: the scale
+ * @attributes: 0, or one to multiple OR'ed QEMU_TIMER_ATTR_<id> values
+ * to assign
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialise a new timer (with attributes) attached to the context @ctx.
+ * The caller is responsible for memory allocation.
+ */
+static inline void aio_timer_init_with_attrs(AioContext *ctx,
+ QEMUTimer *ts, QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque)
+{
+ timer_init_full(ts, &ctx->tlg, type, scale, attributes, cb, opaque);
}
/**
@@ -420,14 +465,14 @@ static inline QEMUTimer *aio_timer_new(AioContext *ctx, QEMUClockType type,
* @opaque: the opaque pointer to pass to the callback
*
* Initialise a new timer attached to the context @ctx.
- * The caller is responsible for memory allocation.
+ * See aio_timer_init_with_attrs for details.
*/
static inline void aio_timer_init(AioContext *ctx,
QEMUTimer *ts, QEMUClockType type,
int scale,
QEMUTimerCB *cb, void *opaque)
{
- timer_init_tl(ts, ctx->tlg.tl[type], scale, cb, opaque);
+ timer_init_full(ts, &ctx->tlg, type, scale, 0, cb, opaque);
}
/**
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 39ea907..8ff1092 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -2,6 +2,7 @@
#define QEMU_TIMER_H
#include "qemu-common.h"
+#include "qemu/bitops.h"
#include "qemu/notify.h"
#include "qemu/host-utils.h"
@@ -52,6 +53,16 @@ typedef enum {
QEMU_CLOCK_MAX
} QEMUClockType;
+/**
+ * QEMU Timer attributes:
+ *
+ * An individual timer may be given one or multiple attributes when initialized.
+ * Each attribute corresponds to one bit. Attributes modify the processing
+ * of timers when they fire.
+ *
+ * No attributes defined currently.
+ */
+
typedef struct QEMUTimerList QEMUTimerList;
struct QEMUTimerListGroup {
@@ -67,6 +78,7 @@ struct QEMUTimer {
QEMUTimerCB *cb;
void *opaque;
QEMUTimer *next;
+ int attributes;
int scale;
};
@@ -418,22 +430,27 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
*/
/**
- * timer_init_tl:
+ * timer_init_full:
* @ts: the timer to be initialised
- * @timer_list: the timer list to attach the timer to
+ * @timer_list_group: (optional) the timer list group to attach the timer to
+ * @type: the clock type to use
* @scale: the scale value for the timer
+ * @attributes: 0, or one or more OR'ed QEMU_TIMER_ATTR_<id> values
* @cb: the callback to be called when the timer expires
* @opaque: the opaque pointer to be passed to the callback
*
- * Initialise a new timer and associate it with @timer_list.
+ * Initialise a timer with the given scale and attributes,
+ * and associate it with timer list for given clock @type in @timer_list_group
+ * (or default timer list group, if NULL).
* The caller is responsible for allocating the memory.
*
* You need not call an explicit deinit call. Simply make
* sure it is not on a list with timer_del.
*/
-void timer_init_tl(QEMUTimer *ts,
- QEMUTimerList *timer_list, int scale,
- QEMUTimerCB *cb, void *opaque);
+void timer_init_full(QEMUTimer *ts,
+ QEMUTimerListGroup *timer_list_group, QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque);
/**
* timer_init:
@@ -445,14 +462,12 @@ void timer_init_tl(QEMUTimer *ts,
*
* Initialize a timer with the given scale on the default timer list
* associated with the clock.
- *
- * You need not call an explicit deinit call. Simply make
- * sure it is not on a list with timer_del.
+ * See timer_init_full for details.
*/
static inline void timer_init(QEMUTimer *ts, QEMUClockType type, int scale,
QEMUTimerCB *cb, void *opaque)
{
- timer_init_tl(ts, main_loop_tlg.tl[type], scale, cb, opaque);
+ timer_init_full(ts, NULL, type, scale, 0, cb, opaque);
}
/**
@@ -464,9 +479,7 @@ static inline void timer_init(QEMUTimer *ts, QEMUClockType type, int scale,
*
* Initialize a timer with nanosecond scale on the default timer list
* associated with the clock.
- *
- * You need not call an explicit deinit call. Simply make
- * sure it is not on a list with timer_del.
+ * See timer_init_full for details.
*/
static inline void timer_init_ns(QEMUTimer *ts, QEMUClockType type,
QEMUTimerCB *cb, void *opaque)
@@ -483,9 +496,7 @@ static inline void timer_init_ns(QEMUTimer *ts, QEMUClockType type,
*
* Initialize a timer with microsecond scale on the default timer list
* associated with the clock.
- *
- * You need not call an explicit deinit call. Simply make
- * sure it is not on a list with timer_del.
+ * See timer_init_full for details.
*/
static inline void timer_init_us(QEMUTimer *ts, QEMUClockType type,
QEMUTimerCB *cb, void *opaque)
@@ -502,9 +513,7 @@ static inline void timer_init_us(QEMUTimer *ts, QEMUClockType type,
*
* Initialize a timer with millisecond scale on the default timer list
* associated with the clock.
- *
- * You need not call an explicit deinit call. Simply make
- * sure it is not on a list with timer_del.
+ * See timer_init_full for details.
*/
static inline void timer_init_ms(QEMUTimer *ts, QEMUClockType type,
QEMUTimerCB *cb, void *opaque)
@@ -513,27 +522,37 @@ static inline void timer_init_ms(QEMUTimer *ts, QEMUClockType type,
}
/**
- * timer_new_tl:
- * @timer_list: the timer list to attach the timer to
+ * timer_new_full:
+ * @timer_list_group: (optional) the timer list group to attach the timer to
+ * @type: the clock type to use
* @scale: the scale value for the timer
+ * @attributes: 0, or one or more OR'ed QEMU_TIMER_ATTR_<id> values
* @cb: the callback to be called when the timer expires
* @opaque: the opaque pointer to be passed to the callback
*
- * Create a new timer and associate it with @timer_list.
+ * Create a new timer with the given scale and attributes,
+ * and associate it with timer list for given clock @type in @timer_list_group
+ * (or default timer list group, if NULL).
* The memory is allocated by the function.
*
* This is not the preferred interface unless you know you
- * are going to call timer_free. Use timer_init instead.
+ * are going to call timer_free. Use timer_init or timer_init_full instead.
+ *
+ * The default timer list has one special feature: in icount mode,
+ * %QEMU_CLOCK_VIRTUAL timers are run in the vCPU thread. This is
+ * not true of other timer lists, which are typically associated
+ * with an AioContext---each of them runs its timer callbacks in its own
+ * AioContext thread.
*
* Returns: a pointer to the timer
*/
-static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
- int scale,
- QEMUTimerCB *cb,
- void *opaque)
+static inline QEMUTimer *timer_new_full(QEMUTimerListGroup *timer_list_group,
+ QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque)
{
QEMUTimer *ts = g_malloc0(sizeof(QEMUTimer));
- timer_init_tl(ts, timer_list, scale, cb, opaque);
+ timer_init_full(ts, timer_list_group, type, scale, attributes, cb, opaque);
return ts;
}
@@ -544,21 +563,16 @@ static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
* @cb: the callback to be called when the timer expires
* @opaque: the opaque pointer to be passed to the callback
*
- * Create a new timer and associate it with the default
- * timer list for the clock type @type.
- *
- * The default timer list has one special feature: in icount mode,
- * %QEMU_CLOCK_VIRTUAL timers are run in the vCPU thread. This is
- * not true of other timer lists, which are typically associated
- * with an AioContext---each of them runs its timer callbacks in its own
- * AioContext thread.
+ * Create a new timer with the given scale,
+ * and associate it with the default timer list for the clock type @type.
+ * See timer_new_full for details.
*
* Returns: a pointer to the timer
*/
static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
QEMUTimerCB *cb, void *opaque)
{
- return timer_new_tl(main_loop_tlg.tl[type], scale, cb, opaque);
+ return timer_new_full(NULL, type, scale, 0, cb, opaque);
}
/**
@@ -569,12 +583,7 @@ static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
*
* Create a new timer with nanosecond scale on the default timer list
* associated with the clock.
- *
- * The default timer list has one special feature: in icount mode,
- * %QEMU_CLOCK_VIRTUAL timers are run in the vCPU thread. This is
- * not true of other timer lists, which are typically associated
- * with an AioContext---each of them runs its timer callbacks in its own
- * AioContext thread.
+ * See timer_new_full for details.
*
* Returns: a pointer to the newly created timer
*/
@@ -590,14 +599,9 @@ static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
* @cb: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
- * The default timer list has one special feature: in icount mode,
- * %QEMU_CLOCK_VIRTUAL timers are run in the vCPU thread. This is
- * not true of other timer lists, which are typically associated
- * with an AioContext---each of them runs its timer callbacks in its own
- * AioContext thread.
- *
* Create a new timer with microsecond scale on the default timer list
* associated with the clock.
+ * See timer_new_full for details.
*
* Returns: a pointer to the newly created timer
*/
@@ -613,14 +617,9 @@ static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
* @cb: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
- * The default timer list has one special feature: in icount mode,
- * %QEMU_CLOCK_VIRTUAL timers are run in the vCPU thread. This is
- * not true of other timer lists, which are typically associated
- * with an AioContext---each of them runs its timer callbacks in its own
- * AioContext thread.
- *
* Create a new timer with millisecond scale on the default timer list
* associated with the clock.
+ * See timer_new_full for details.
*
* Returns: a pointer to the newly created timer
*/
diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c
index ca5cc3b..54b3fd2 100644
--- a/tests/ptimer-test-stubs.c
+++ b/tests/ptimer-test-stubs.c
@@ -34,14 +34,19 @@ int64_t ptimer_test_time_ns;
int use_icount = 1;
bool qtest_allowed;
-void timer_init_tl(QEMUTimer *ts,
- QEMUTimerList *timer_list, int scale,
- QEMUTimerCB *cb, void *opaque)
+void timer_init_full(QEMUTimer *ts,
+ QEMUTimerListGroup *timer_list_group, QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque)
{
- ts->timer_list = timer_list;
+ if (!timer_list_group) {
+ timer_list_group = &main_loop_tlg;
+ }
+ ts->timer_list = timer_list_group->tl[type];
ts->cb = cb;
ts->opaque = opaque;
ts->scale = scale;
+ ts->attributes = attributes;
ts->expire_time = -1;
}
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index 86bfe84..04527a3 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -339,14 +339,19 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
}
-void timer_init_tl(QEMUTimer *ts,
- QEMUTimerList *timer_list, int scale,
- QEMUTimerCB *cb, void *opaque)
+void timer_init_full(QEMUTimer *ts,
+ QEMUTimerListGroup *timer_list_group, QEMUClockType type,
+ int scale, int attributes,
+ QEMUTimerCB *cb, void *opaque)
{
- ts->timer_list = timer_list;
+ if (!timer_list_group) {
+ timer_list_group = &main_loop_tlg;
+ }
+ ts->timer_list = timer_list_group->tl[type];
ts->cb = cb;
ts->opaque = opaque;
ts->scale = scale;
+ ts->attributes = attributes;
ts->expire_time = -1;
}
--
1.8.3.1
next prev parent reply other threads:[~2018-10-18 20:32 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-18 20:31 [Qemu-devel] [PULL 00/48] Miscellaneous patches for 2018-10-18 Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 01/48] es1370: more fixes for ADC_FRAMEADR and ADC_FRAMECNT Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 02/48] Revert some patches from recent [PATCH v6] "Fixing record/replay and adding reverse debugging" Paolo Bonzini
2018-10-18 20:31 ` Paolo Bonzini [this message]
2018-11-05 23:16 ` [Qemu-devel] [PULL 03/48] qemu-timer: introduce timer attributes Eric Blake
2018-11-06 5:01 ` Artem Pisarenko
2018-11-06 9:45 ` Paolo Bonzini
2018-11-07 20:21 ` Eric Blake
2018-11-08 9:37 ` Peter Maydell
2018-10-18 20:31 ` [Qemu-devel] [PULL 04/48] qemu-timer: avoid checkpoints for virtual clock timers in external subsystems Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 05/48] qemu-timer: optimize record/replay checkpointing for all clocks Paolo Bonzini
2018-10-19 6:59 ` Artem Pisarenko
2018-10-18 20:31 ` [Qemu-devel] [PULL 06/48] target-i386: kvm: do not initialize padding fields Paolo Bonzini
2018-10-19 9:03 ` Peter Maydell
2018-10-19 11:44 ` Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 07/48] linux-headers: update to 4.20-rc1 Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 08/48] target-i386 : add coalesced_pio API Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 09/48] target-i386: add rtc 0x70 port as coalesced_pio Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 10/48] target-i386: add i440fx 0xcf8 " Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 11/48] target-i386: add q35 " Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 12/48] replay: don't process events at virtual clock checkpoint Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 13/48] i386/kvm: add support for Hyper-V IPI send Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 14/48] i386: hvf: Fix register refs if REX is present Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 15/48] i386: hvf: Remove hvf_disabled Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 16/48] vl: improve/fix documentation related to RTC function Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 17/48] vl: refactor -rtc option references Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 18/48] Fixes RTC bug with base datetime shifts in clock=vm Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 19/48] vl, qapi: offset calculation in RTC_CHANGE event reverted Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 20/48] call HotplugHandler->plug() as the last step in device realization Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 21/48] hw: edu: drop DO_UPCAST Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 22/48] scsi-disk: fix double completion of failing passthrough requests Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 23/48] scsi-disk: fix rerror/werror=ignore Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 24/48] hyperv_testdev: refactor for better maintainability Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 25/48] hyperv_testdev: drop unnecessary includes Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 26/48] hyperv: cosmetic: g_malloc -> g_new Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 27/48] hyperv: synic: only setup ack notifier if there's a callback Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 28/48] hyperv: allow passing arbitrary data to sint ack callback Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 29/48] hyperv: address HvSintRoute by X86CPU pointer Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 30/48] hyperv: make HvSintRoute reference-counted Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 31/48] hyperv: rename kvm_hv_sint_route_set_sint Paolo Bonzini
2018-10-18 20:31 ` [Qemu-devel] [PULL 32/48] hyperv: split hyperv-proto.h into x86 and arch-independent parts Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 33/48] hyperv: make hyperv_vp_index inline Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 34/48] hyperv: factor out arch-independent API into hw/hyperv Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 35/48] default-configs: collect CONFIG_HYPERV* in hyperv.mak Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 36/48] i386: add hyperv-stub for CONFIG_HYPERV=n Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 37/48] hyperv:synic: split capability testing and setting Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 39/48] hyperv: only add SynIC in compatible configurations Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 40/48] hyperv: make overlay pages for SynIC Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 41/48] hyperv: add synic message delivery Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 42/48] hyperv: add synic event flag signaling Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 43/48] hyperv: process SIGNAL_EVENT hypercall Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 44/48] hyperv: add support for KVM_HYPERV_EVENTFD Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 45/48] hyperv: process POST_MESSAGE hypercall Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 46/48] hyperv_testdev: add SynIC message and event testmodes Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 47/48] target/i386: kvm: just return after migrate_add_blocker failed Paolo Bonzini
2018-10-18 20:32 ` [Qemu-devel] [PULL 48/48] replay: pass raw icount value to replay_save_clock Paolo Bonzini
2018-10-19 7:32 ` [Qemu-devel] [PULL 00/48] Miscellaneous patches for 2018-10-18 Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1539894735-14232-4-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=artem.k.pisarenko@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).