From 3d96ea44d4dde442094b7d9e5b71ef61b4c4ae39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 5 Mar 2018 18:29:49 +0100 Subject: qlit: use QType instead of int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Markus Armbruster Signed-off-by: Marc-André Lureau Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20180305172951.2150-3-marcandre.lureau@redhat.com> Signed-off-by: Eric Blake --- include/qapi/qmp/qlit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index 56f9d97bd9..f1ed082df8 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -20,7 +20,7 @@ typedef struct QLitDictEntry QLitDictEntry; typedef struct QLitObject QLitObject; struct QLitObject { - int type; + QType type; union { bool qbool; int64_t qnum; -- cgit v1.2.3 From 3cf42b8b3af1bd61e736a9ca0f94806c7931ae56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 5 Mar 2018 18:29:50 +0100 Subject: qlit: add qobject_from_qlit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instantiate a QObject* from a literal QLitObject. LitObject only supports int64_t for now. uint64_t and double aren't implemented. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20180305172951.2150-4-marcandre.lureau@redhat.com> Signed-off-by: Eric Blake --- include/qapi/qmp/qlit.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h index f1ed082df8..c0676d5daf 100644 --- a/include/qapi/qmp/qlit.h +++ b/include/qapi/qmp/qlit.h @@ -50,4 +50,6 @@ struct QLitDictEntry { bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs); +QObject *qobject_from_qlit(const QLitObject *qlit); + #endif /* QLIT_H */ -- cgit v1.2.3 From 9139b5672360aaa263da1d96cdfdbe16accb6e3b Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Sat, 24 Feb 2018 16:40:27 +0100 Subject: compiler: Add QEMU_BUILD_BUG_MSG() macro _Static_assert() allows us to specify messages, and that may come in handy. Even without _Static_assert(), encouraging developers to put a helpful message next to the QEMU_BUILD_BUG_* may make debugging easier whenever it breaks. Signed-off-by: Max Reitz Message-Id: <20180224154033.29559-2-mreitz@redhat.com> Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Signed-off-by: Eric Blake --- include/qemu/compiler.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 2cbe6a4f16..9f762695d1 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -82,15 +82,21 @@ int:(x) ? -1 : 1; \ } +/* QEMU_BUILD_BUG_MSG() emits the message given if _Static_assert is + * supported; otherwise, it will be omitted from the compiler error + * message (but as it remains present in the source code, it can still + * be useful when debugging). */ #if defined(CONFIG_STATIC_ASSERT) -#define QEMU_BUILD_BUG_ON(x) _Static_assert(!(x), "not expecting: " #x) +#define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg) #elif defined(__COUNTER__) -#define QEMU_BUILD_BUG_ON(x) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \ +#define QEMU_BUILD_BUG_MSG(x, msg) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \ glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused)) #else -#define QEMU_BUILD_BUG_ON(x) +#define QEMU_BUILD_BUG_MSG(x, msg) #endif +#define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x) + #define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \ sizeof(QEMU_BUILD_BUG_ON_STRUCT(x))) -- cgit v1.2.3 From 1a56b1e2ab5e9d6d89386ca953b4afb419e15abe Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Sat, 24 Feb 2018 16:40:28 +0100 Subject: qapi: Add qobject_to() This is a dynamic casting macro that, given a QObject type, returns an object as that type or NULL if the object is of a different type (or NULL itself). The macro uses lower-case letters because: 1. There does not seem to be a hard rule on whether qemu macros have to be upper-cased, 2. The current situation in qapi/qmp is inconsistent (compare e.g. QINCREF() vs. qdict_put()), 3. qobject_to() will evaluate its @obj parameter only once, thus it is generally not important to the caller whether it is a macro or not, 4. I prefer it aesthetically. The macro parameter order is chosen with typename first for consistency with other QAPI macros like QAPI_CLONE(), as well as for legibility (read it as "qobject to" type "applied to" obj). Signed-off-by: Max Reitz Message-Id: <20180224154033.29559-3-mreitz@redhat.com> Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia [eblake: swap parameter order to list type first, avoid clang ubsan warning on QOBJECT(NULL) and container_of(NULL,type,base)] Signed-off-by: Eric Blake --- include/qapi/qmp/qobject.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'include') diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index 012439a2e3..e022707578 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -50,6 +50,21 @@ struct QObject { #define QDECREF(obj) \ qobject_decref(obj ? QOBJECT(obj) : NULL) +/* Required for qobject_to() */ +#define QTYPE_CAST_TO_QNull QTYPE_QNULL +#define QTYPE_CAST_TO_QNum QTYPE_QNUM +#define QTYPE_CAST_TO_QString QTYPE_QSTRING +#define QTYPE_CAST_TO_QDict QTYPE_QDICT +#define QTYPE_CAST_TO_QList QTYPE_QLIST +#define QTYPE_CAST_TO_QBool QTYPE_QBOOL + +QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7, + "The QTYPE_CAST_TO_* list needs to be extended"); + +#define qobject_to(type, obj) ({ \ + QObject *_tmp = qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)); \ + _tmp ? container_of(_tmp, type, base) : (type *)NULL; }) + /* Initialize an object to default values */ static inline void qobject_init(QObject *obj, QType type) { @@ -102,4 +117,18 @@ static inline QType qobject_type(const QObject *obj) return obj->type; } +/** + * qobject_check_type(): Helper function for the qobject_to() macro. + * Return @obj, but only if @obj is not NULL and @type is equal to + * @obj's type. Return NULL otherwise. + */ +static inline QObject *qobject_check_type(const QObject *obj, QType type) +{ + if (obj && qobject_type(obj) == type) { + return (QObject *)obj; + } else { + return NULL; + } +} + #endif /* QOBJECT_H */ -- cgit v1.2.3 From cb51b976babf7ee16dc5eda4f2189d65b8b700a3 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Sat, 24 Feb 2018 16:40:30 +0100 Subject: qapi: Remove qobject_to_X() functions They are no longer needed now. Signed-off-by: Max Reitz Reviewed-by: Alberto Garcia Message-Id: <20180224154033.29559-5-mreitz@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- include/qapi/qmp/qbool.h | 1 - include/qapi/qmp/qdict.h | 1 - include/qapi/qmp/qlist.h | 1 - include/qapi/qmp/qnum.h | 1 - include/qapi/qmp/qstring.h | 1 - 5 files changed, 5 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h index 629c508d34..b9a44a1bfe 100644 --- a/include/qapi/qmp/qbool.h +++ b/include/qapi/qmp/qbool.h @@ -23,7 +23,6 @@ struct QBool { QBool *qbool_from_bool(bool value); bool qbool_get_bool(const QBool *qb); -QBool *qobject_to_qbool(const QObject *obj); bool qbool_is_equal(const QObject *x, const QObject *y); void qbool_destroy_obj(QObject *obj); diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 7c6d844549..2cc3e906f7 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -39,7 +39,6 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value); void qdict_del(QDict *qdict, const char *key); int qdict_haskey(const QDict *qdict, const char *key); QObject *qdict_get(const QDict *qdict, const char *key); -QDict *qobject_to_qdict(const QObject *obj); bool qdict_is_equal(const QObject *x, const QObject *y); void qdict_iter(const QDict *qdict, void (*iter)(const char *key, QObject *obj, void *opaque), diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index 5fd976a398..5c673acb06 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -53,7 +53,6 @@ QObject *qlist_pop(QList *qlist); QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); size_t qlist_size(const QList *qlist); -QList *qobject_to_qlist(const QObject *obj); bool qlist_is_equal(const QObject *x, const QObject *y); void qlist_destroy_obj(QObject *obj); diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h index 15e3971c7f..3e47475b2c 100644 --- a/include/qapi/qmp/qnum.h +++ b/include/qapi/qmp/qnum.h @@ -68,7 +68,6 @@ double qnum_get_double(QNum *qn); char *qnum_to_string(QNum *qn); -QNum *qobject_to_qnum(const QObject *obj); bool qnum_is_equal(const QObject *x, const QObject *y); void qnum_destroy_obj(QObject *obj); diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 98070ef3d6..b72843fc1b 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -30,7 +30,6 @@ const char *qstring_get_str(const QString *qstring); void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); -QString *qobject_to_qstring(const QObject *obj); bool qstring_is_equal(const QObject *x, const QObject *y); void qstring_destroy_obj(QObject *obj); -- cgit v1.2.3 From 775932020dd6bd7e9c1acc0d7779677d8b4c094c Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 9 Mar 2018 16:59:45 +0800 Subject: qobject: introduce qstring_get_try_str() The only difference from qstring_get_str() is that it allows the qstring to be NULL. If so, NULL is returned. CC: Eric Blake CC: Markus Armbruster Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Peter Xu Message-Id: <20180309090006.10018-3-peterx@redhat.com> Signed-off-by: Eric Blake --- include/qapi/qmp/qstring.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index b72843fc1b..38c680b718 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -27,6 +27,7 @@ QString *qstring_from_str(const char *str); QString *qstring_from_substr(const char *str, int start, int end); size_t qstring_get_length(const QString *qstring); const char *qstring_get_str(const QString *qstring); +const char *qstring_get_try_str(const QString *qstring); void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); -- cgit v1.2.3 From b26ae1cb8eb0756524e322169138830b9b542311 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 9 Mar 2018 16:59:46 +0800 Subject: qobject: introduce qobject_get_try_str() A quick way to fetch string from qobject when it's a QString. Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Signed-off-by: Peter Xu Message-Id: <20180309090006.10018-4-peterx@redhat.com> Reviewed-by: Eric Blake [eblake: rebase to qobject_to() macro] Signed-off-by: Eric Blake --- include/qapi/qmp/qstring.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 38c680b718..30ae260a7f 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -28,6 +28,7 @@ QString *qstring_from_substr(const char *str, int start, int end); size_t qstring_get_length(const QString *qstring); const char *qstring_get_str(const QString *qstring); const char *qstring_get_try_str(const QString *qstring); +const char *qobject_get_try_str(const QObject *qstring); void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); -- cgit v1.2.3 From 6adf08dd42929542426b055a4b66a5bc0b8e20ba Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 9 Mar 2018 16:59:50 +0800 Subject: monitor: unify global init There are many places where the monitor initializes its globals: - monitor_init_qmp_commands() at the very beginning - single function to init monitor_lock - in the first entry of monitor_init() using "is_first_init" Unify them a bit. monitor_lock is not used before monitor_init() (as confirmed by code analysis and gdb watchpoints); so we are safe delaying what was a constructor-time initialization of the mutex into the later first call to monitor_init(). Reviewed-by: Fam Zheng Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Peter Xu Message-Id: <20180309090006.10018-8-peterx@redhat.com> Signed-off-by: Eric Blake --- include/monitor/monitor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index d1024d4bdc..0cb0538a31 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -16,7 +16,7 @@ extern Monitor *cur_mon; bool monitor_cur_is_qmp(void); -void monitor_init_qmp_commands(void); +void monitor_init_globals(void); void monitor_init(Chardev *chr, int flags); void monitor_cleanup(void); -- cgit v1.2.3 From 876c67512e2af8c05686faa9f9ff49b38d7a392c Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 9 Mar 2018 17:00:00 +0800 Subject: qapi: introduce new cmd option "allow-oob" Here "oob" stands for "Out-Of-Band". When "allow-oob" is set, it means the command allows out-of-band execution. The "oob" idea is proposed by Markus Armbruster in following thread: https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg02057.html This new "allow-oob" boolean will be exposed by "query-qmp-schema" as well for command entries, so that QMP clients can know which commands can be used in out-of-band calls. For example the command "migrate" originally looks like: {"name": "migrate", "ret-type": "17", "meta-type": "command", "arg-type": "86"} And it'll be changed into: {"name": "migrate", "ret-type": "17", "allow-oob": false, "meta-type": "command", "arg-type": "86"} This patch only provides the QMP interface level changes. It does not contain the real out-of-band execution implementation yet. Suggested-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Reviewed-by: Fam Zheng Signed-off-by: Peter Xu Message-Id: <20180309090006.10018-18-peterx@redhat.com> Reviewed-by: Eric Blake [eblake: rebase on introspection done by qlit] Signed-off-by: Eric Blake --- include/qapi/qmp/dispatch.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 1e694b5ecf..26eb13ff41 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -20,8 +20,9 @@ typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); typedef enum QmpCommandOptions { - QCO_NO_OPTIONS = 0x0, - QCO_NO_SUCCESS_RESP = 0x1, + QCO_NO_OPTIONS = 0x0, + QCO_NO_SUCCESS_RESP = (1U << 0), + QCO_ALLOW_OOB = (1U << 1), } QmpCommandOptions; typedef struct QmpCommand -- cgit v1.2.3 From cf869d53172920536a14180a83292b240e9d0545 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Sat, 10 Mar 2018 20:38:05 -0600 Subject: qmp: support out-of-band (oob) execution Having "allow-oob":true for a command does not mean that this command will always be run in out-of-band mode. The out-of-band quick path will only be executed if we specify the extra "run-oob" flag when sending the QMP request: { "execute": "command-that-allows-oob", "arguments": { ... }, "control": { "run-oob": true } } The "control" key is introduced to store this extra flag. "control" field is used to store arguments that are shared by all the commands, rather than command specific arguments. Let "run-oob" be the first. Note that in the patch I exported qmp_dispatch_check_obj() to be used to check the request earlier, and at the same time allowed "id" field to be there since actually we always allow that. Reviewed-by: Stefan Hajnoczi Signed-off-by: Peter Xu Message-Id: <20180309090006.10018-19-peterx@redhat.com> Reviewed-by: Eric Blake [eblake: rebase to qobject_to(), spelling fix] Signed-off-by: Eric Blake --- include/qapi/qmp/dispatch.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 26eb13ff41..ffb4652f71 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -48,6 +48,8 @@ bool qmp_command_is_enabled(const QmpCommand *cmd); const char *qmp_command_name(const QmpCommand *cmd); bool qmp_has_success_response(const QmpCommand *cmd); QObject *qmp_build_error_object(Error *err); +QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp); +bool qmp_is_oob(QDict *dict); typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque); -- cgit v1.2.3 From b741ae74170643de0fec3005c717e3a397c3e034 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Fri, 9 Mar 2018 19:52:11 +0300 Subject: block/accounting: introduce latency histogram Introduce latency histogram statics for block devices. For each accounted operation type, the latency region [0, +inf) is divided into subregions by several points. Then, calculate hits for each subregion. Signed-off-by: Vladimir Sementsov-Ogievskiy Message-Id: <20180309165212.97144-2-vsementsov@virtuozzo.com> Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Eric Blake --- include/block/accounting.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'include') diff --git a/include/block/accounting.h b/include/block/accounting.h index b833d26d6c..d1f67b10dd 100644 --- a/include/block/accounting.h +++ b/include/block/accounting.h @@ -27,6 +27,7 @@ #include "qemu/timed-average.h" #include "qemu/thread.h" +#include "qapi/qapi-builtin-types.h" typedef struct BlockAcctTimedStats BlockAcctTimedStats; typedef struct BlockAcctStats BlockAcctStats; @@ -45,6 +46,36 @@ struct BlockAcctTimedStats { QSLIST_ENTRY(BlockAcctTimedStats) entries; }; +typedef struct BlockLatencyHistogram { + /* The following histogram is represented like this: + * + * 5| * + * 4| * + * 3| * * + * 2| * * * + * 1| * * * * + * +------------------ + * 10 50 100 + * + * BlockLatencyHistogram histogram = { + * .nbins = 4, + * .boundaries = {10, 50, 100}, + * .bins = {3, 1, 5, 2}, + * }; + * + * @boundaries array define histogram intervals as follows: + * [0, boundaries[0]), [boundaries[0], boundaries[1]), ... + * [boundaries[nbins-2], +inf) + * + * So, for example above, histogram intervals are: + * [0, 10), [10, 50), [50, 100), [100, +inf) + */ + int nbins; + uint64_t *boundaries; /* @nbins-1 numbers here + (all boundaries, except 0 and +inf) */ + uint64_t *bins; +} BlockLatencyHistogram; + struct BlockAcctStats { QemuMutex lock; uint64_t nr_bytes[BLOCK_MAX_IOTYPE]; @@ -57,6 +88,7 @@ struct BlockAcctStats { QSLIST_HEAD(, BlockAcctTimedStats) intervals; bool account_invalid; bool account_failed; + BlockLatencyHistogram latency_histogram[BLOCK_MAX_IOTYPE]; }; typedef struct BlockAcctCookie { @@ -82,5 +114,8 @@ void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type, int64_t block_acct_idle_time_ns(BlockAcctStats *stats); double block_acct_queue_depth(BlockAcctTimedStats *stats, enum BlockAcctType type); +int block_latency_histogram_set(BlockAcctStats *stats, enum BlockAcctType type, + uint64List *boundaries); +void block_latency_histograms_clear(BlockAcctStats *stats); #endif -- cgit v1.2.3