Add the hmp and qmp interface to drop vm's page cache, users can control the type of cache they want vm to drop. Signed-off-by: Liang Li <liang.z.li@xxxxxxxxx> --- balloon.c | 19 +++++++++++++++++++ hmp-commands.hx | 15 +++++++++++++++ hmp.c | 22 ++++++++++++++++++++++ hmp.h | 3 +++ monitor.c | 18 ++++++++++++++++++ qapi-schema.json | 35 +++++++++++++++++++++++++++++++++++ qmp-commands.hx | 23 +++++++++++++++++++++++ 7 files changed, 135 insertions(+) diff --git a/balloon.c b/balloon.c index 0fb34bf..3d96111 100644 --- a/balloon.c +++ b/balloon.c @@ -122,3 +122,22 @@ void qmp_balloon(int64_t target, Error **errp) trace_balloon_event(balloon_opaque, target); balloon_event_fn(balloon_opaque, target); } + +void qmp_balloon_drop_cache(DropCacheType type, Error **errp) +{ + if (!have_balloon(errp)) { + return; + } + + if (!balloon_drop_cache_fn) { + error_setg(errp, QERR_UNSUPPORTED); + return; + } + if (type < 0 && type >= DROP_CACHE_TYPE__MAX) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", + "a value in range[0, 3]"); + return; + } + + balloon_drop_cache_fn(balloon_opaque, type); +} diff --git a/hmp-commands.hx b/hmp-commands.hx index 98b4b1a..c73572c 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1378,6 +1378,21 @@ Request VM to change its memory allocation to @var{value} (in MB). ETEXI { + .name = "balloon_drop_cache", + .args_type = "type:s", + .params = "type", + .help = "request VM to drop its page caches", + .mhandler.cmd = hmp_balloon_drop_cache, + .command_completion = balloon_drop_cache_completion + }, + +STEXI +@item balloon_drop_cache @var{type} +@findex balloon_drop_cache +Request VM to dorp its page caches. +ETEXI + + { .name = "set_link", .args_type = "name:s,up:b", .params = "name on|off", diff --git a/hmp.c b/hmp.c index a4b1d3d..3aa1062 100644 --- a/hmp.c +++ b/hmp.c @@ -1061,6 +1061,28 @@ void hmp_balloon(Monitor *mon, const QDict *qdict) } } +void hmp_balloon_drop_cache(Monitor *mon, const QDict *qdict) +{ + const char *type = qdict_get_str(qdict, "type"); + Error *err = NULL; + int i; + + for (i = 0; i < DROP_CACHE_TYPE__MAX; i++) { + if (strcmp(type, DropCacheType_lookup[i]) == 0) { + qmp_balloon_drop_cache(1 + i, &err); + break; + } + } + + if (i == DROP_CACHE_TYPE__MAX) { + error_setg(&err, QERR_INVALID_PARAMETER, type); + } + + if (err) { + error_report_err(err); + } +} + void hmp_block_resize(Monitor *mon, const QDict *qdict) { const char *device = qdict_get_str(qdict, "device"); diff --git a/hmp.h b/hmp.h index 093d65f..6bb6499 100644 --- a/hmp.h +++ b/hmp.h @@ -55,6 +55,7 @@ void hmp_nmi(Monitor *mon, const QDict *qdict); void hmp_set_link(Monitor *mon, const QDict *qdict); void hmp_block_passwd(Monitor *mon, const QDict *qdict); void hmp_balloon(Monitor *mon, const QDict *qdict); +void hmp_balloon_drop_cache(Monitor *mon, const QDict *qdict); void hmp_block_resize(Monitor *mon, const QDict *qdict); void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict); void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict); @@ -120,6 +121,8 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str); void migrate_set_capability_completion(ReadLineState *rs, int nb_args, const char *str); +void balloon_drop_cache_completion(ReadLineState *rs, int nb_args, + const char *str); void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, const char *str); void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index a27e115..eefdf3d 100644 --- a/monitor.c +++ b/monitor.c @@ -3367,6 +3367,24 @@ void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, } } +void balloon_drop_cache_completion(ReadLineState *rs, int nb_args, + const char *str) +{ + size_t len; + + len = strlen(str); + readline_set_completion_index(rs, len); + if (nb_args == 2) { + int i; + for (i = 0; i < DROP_CACHE_TYPE__MAX; i++) { + const char *name = DropCacheType_lookup[i]; + if (!strncmp(str, name, len)) { + readline_add_completion(rs, name); + } + } + } +} + void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str) { int i; diff --git a/qapi-schema.json b/qapi-schema.json index 8483bdf..117f70a 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1655,6 +1655,41 @@ { 'command': 'balloon', 'data': {'value': 'int'} } ## +# @DropCacheType +# +# Cache types enumeration +# +# @clean: Drop the clean page cache. +# +# @slab: Drop the slab cache. +# +# @all: Drop both the clean and the slab cache. +# +# Since: 2.7 +## +{ 'enum': 'DropCacheType', 'data': ['clean', 'slab', 'all'] } + +## +# @balloon_drop_cache: +# +# Request the vm to drop its cache. +# +# @value: the type of cache want vm to drop +# +# Returns: Nothing on success +# If the balloon driver is enabled but not functional because the KVM +# kernel module cannot support it, KvmMissingCap +# If no balloon device is present, DeviceNotActive +# +# Notes: This command just issues a request to the guest. When it returns, +# the drop cache operation may not have completed. A guest can drop its +# cache independent of this command. +# +# Since: 2.7.0 +## +{ 'command': 'balloon_drop_cache', 'data': {'value': 'DropCacheType'} } + +## # @Abort # # This action can be used to test transaction failure. diff --git a/qmp-commands.hx b/qmp-commands.hx index 28801a2..6650ba0 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1802,6 +1802,29 @@ Example: EQMP { + .name = "balloon_drop_cache", + .args_type = "value:i", + .mhandler.cmd_new = qmp_marshal_balloon_drop_cache, + }, + +SQMP +balloon_drop_cache +------- + +Request VM to drop its cache. + +Arguments: + +- "value": cache type to drop (json-int) + +Example: + +-> { "execute": "balloon_drop_cache", "arguments": { "value": 1 } } +<- { "return": {} } + +EQMP + + { .name = "set_link", .args_type = "name:s,up:b", .mhandler.cmd_new = qmp_marshal_set_link, -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html