diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-03-20 09:51:49 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-03-20 09:51:49 +0000 |
commit | 4bdc24fa018901892bb8a5bd1808ebd605f4c64d (patch) | |
tree | a8697528cea1222bf38abddf88b5746773adfcea /include | |
parent | c26ef39204f3200efe89470f6b21ac783edadd29 (diff) | |
parent | 02e3092db3f9b84ed6aae54e3b71d4dc4196c7eb (diff) | |
download | qemu-4bdc24fa018901892bb8a5bd1808ebd605f4c64d.zip qemu-4bdc24fa018901892bb8a5bd1808ebd605f4c64d.tar.gz qemu-4bdc24fa018901892bb8a5bd1808ebd605f4c64d.tar.bz2 |
Merge remote-tracking branch 'remotes/ericb/tags/pull-qapi-2018-03-12-v4' into staging
qapi patches for 2018-03-12, 2.12 softfreeze
- Marc-André Lureau: 0/4 qapi: generate a literal qobject for introspection
- Max Reitz: 0/7 block: Handle null backing link
- Daniel P. Berrange: chardev: tcp: postpone TLS work until machine done
- Peter Xu: 00/23 QMP: out-of-band (OOB) execution support
- Vladimir Sementsov-Ogievskiy: 0/2 block latency histogram
- Eric Blake: qapi: Pass '-u' when doing non-silent diff
# gpg: Signature made Mon 19 Mar 2018 19:59:04 GMT
# gpg: using RSA key A7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>"
# gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>"
# gpg: aka "[jpeg image of size 6874]"
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A
* remotes/ericb/tags/pull-qapi-2018-03-12-v4: (38 commits)
qapi: Pass '-u' when doing non-silent diff
qapi: add block latency histogram interface
block/accounting: introduce latency histogram
tests: qmp-test: add oob test
tests: qmp-test: verify command batching
qmp: add command "x-oob-test"
monitor: enable IO thread for (qmp & !mux) typed
qmp: isolate responses into io thread
qmp: support out-of-band (oob) execution
qapi: introduce new cmd option "allow-oob"
monitor: send event when command queue full
qmp: add new event "command-dropped"
monitor: separate QMP parser and dispatcher
monitor: let suspend/resume work even with QMPs
monitor: let suspend_cnt be thread safe
monitor: introduce monitor_qmp_respond()
qmp: introduce QMPCapability
monitor: allow using IO thread for parsing
monitor: let mon_list be tail queue
monitor: unify global init
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/block/accounting.h | 35 | ||||
-rw-r--r-- | include/monitor/monitor.h | 2 | ||||
-rw-r--r-- | include/qapi/qmp/dispatch.h | 7 | ||||
-rw-r--r-- | include/qapi/qmp/qbool.h | 1 | ||||
-rw-r--r-- | include/qapi/qmp/qdict.h | 1 | ||||
-rw-r--r-- | include/qapi/qmp/qlist.h | 1 | ||||
-rw-r--r-- | include/qapi/qmp/qlit.h | 4 | ||||
-rw-r--r-- | include/qapi/qmp/qnum.h | 1 | ||||
-rw-r--r-- | include/qapi/qmp/qobject.h | 29 | ||||
-rw-r--r-- | include/qapi/qmp/qstring.h | 3 | ||||
-rw-r--r-- | include/qemu/compiler.h | 12 |
11 files changed, 84 insertions, 12 deletions
diff --git a/include/block/accounting.h b/include/block/accounting.h index b833d26..d1f67b1 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 diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index d1024d4..0cb0538 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); diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 1e694b5..ffb4652 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 @@ -47,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); diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h index 629c508..b9a44a1 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 7c6d844..2cc3e90 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 5fd976a..5c673ac 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/qlit.h b/include/qapi/qmp/qlit.h index 56f9d97..c0676d5 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; @@ -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 */ diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h index 15e3971..3e47475 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/qobject.h b/include/qapi/qmp/qobject.h index 012439a..e022707 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 */ diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 98070ef..30ae260 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -27,10 +27,11 @@ 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); +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); -QString *qobject_to_qstring(const QObject *obj); bool qstring_is_equal(const QObject *x, const QObject *y); void qstring_destroy_obj(QObject *obj); diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 2cbe6a4..9f76269 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))) |