Obtain dirty bitmap via VM logging
cover Obtain dirty bitmap via VM logging
Hi,
This is the first part of my gsoc work.
Following patches add the support of dirty bitmap logging and dumping to a specified file. These patches provide the mechanism to get the dirty bitmap if the user wants to log the VM besides migration. This can be useful in case of learning about the writable working set of the VM even when it is not being migrated. I know that it will incur huge degradation but still, a user might want to do that. Besides this, this mechanism can also be useful in case of learning about the pages that can be stored in the cache while performing the xbzrle based live migration or even before the beginning of the hybrid (precopy + postcopy) live migration.
I have tried to provide both of the hmp and qmp commands interface to obtain the dirty bitmap. Besides dumping the dirty bitmap, one can also update the frequency with which the logging is taking place or even can cancel the ongoing logging process. Thus, there are 3 hmp and qmp commands interface provided to perform the task.
Sanidhya Kashyap (6):
split dirty bitmap into four for dumping the bitmaps bitmap dump code via QAPI framework
hmp interface for dirty bitmap dump
cancel mechanism for an already running dump bitmap process set the frequency of the dump bitmap process python script for extracting bitmap from a binary file
exec.c | 4 + hmp-commands.hx | 46 +++++++ hmp.c | 36 +++++ hmp.h | 3 + include/exec/memory.h | 3 +- include/exec/ram_addr.h | 16 ++- include/qapi/qmp/qerror.h | 3 + qapi-schema.json | 23 ++++ qmp-commands.hx | 77 +++++++++++ savevm.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/extract-bitmap.py | 68 +++++++++ 11 files changed, 621 insertions(+), 2 deletions(-) create mode 100755 scripts/extract-bitmap.py
Signature · 1 line
1.8.3.1
PATCH 1/6 split dirty bitmap into four for dumping the bitmaps
Added another flag - DIRTY_MEMORY_LOG_BITMAP for the purpose of logging the dirty bitmap. The dumping bitmap process will utilize this flag for dumping the data in the file.
--- exec.c | 4 ++++ include/exec/memory.h | 3 ++- include/exec/ram_addr.h | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-)
exec.c +4 -0
@@ -1551,6 +1551,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, }cpu_physical_memory_set_dirty_flag (ram_addr,DIRTY_MEMORY_MIGRATION );cpu_physical_memory_set_dirty_flag (ram_addr,DIRTY_MEMORY_VGA ); +cpu_physical_memory_set_dirty_flag (ram_addr,DIRTY_MEMORY_LOG_BITMAP );/* we remove the notdirty callback only if the code has been flushed */ if (!cpu_physical_memory_is_clean (ram_addr)) {
@@ -1959,6 +1960,7 @@ static void invalidate_and_set_dirty(hwaddr addr,/* set dirty bit */ cpu_physical_memory_set_dirty_flag (addr,DIRTY_MEMORY_VGA );cpu_physical_memory_set_dirty_flag (addr,DIRTY_MEMORY_MIGRATION ); +cpu_physical_memory_set_dirty_flag (addr,DIRTY_MEMORY_LOG_BITMAP ); }xen_modified_memory (addr, length); }
@@ -2563,6 +2565,8 @@ void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)cpu_physical_memory_set_dirty_flag (addr1,DIRTY_MEMORY_MIGRATION );cpu_physical_memory_set_dirty_flag (addr1,DIRTY_MEMORY_VGA ); +cpu_physical_memory_set_dirty_flag (addr1, +DIRTY_MEMORY_LOG_BITMAP ); } } }
include/exec/memory.h +2 -1
@@ -19,7 +19,8 @@#define DIRTY_MEMORY_VGA 0#define DIRTY_MEMORY_CODE 1#define DIRTY_MEMORY_MIGRATION 2 -#define DIRTY_MEMORY_NUM 3/* num of dirty bits */ +#define DIRTY_MEMORY_LOG_BITMAP 3 +#define DIRTY_MEMORY_NUM 4/* num of dirty bits */ #include <stdint.h> #include <stdbool.h>
include/exec/ram_addr.h +15 -1
@@ -56,7 +56,10 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr)bool code =cpu_physical_memory_get_dirty_flag (addr,DIRTY_MEMORY_CODE );bool migration =cpu_physical_memory_get_dirty_flag (addr,DIRTY_MEMORY_MIGRATION ); -return !(vga && code && migration); +bool bitmap_log = +cpu_physical_memory_get_dirty_flag (addr,DIRTY_MEMORY_LOG_BITMAP ); + +return !(vga && code && migration && bitmap_log); } static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
@@ -66,6 +69,13 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,set_bit (addr >>TARGET_PAGE_BITS , ram_list.dirty_memory[client]); } +static inline void cpu_physical_memory_clear_dirty_flag (ram_addr_t addr, +unsigned client) +{ +assert (client <DIRTY_MEMORY_NUM ); +clear_bit (addr >>TARGET_PAGE_BITS , ram_list.dirty_memory[client]); +} +static inline void cpu_physical_memory_set_dirty_range (ram_addr_t start,ram_addr_t length) {
@@ -76,6 +86,8 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,bitmap_set (ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION ], page, end - page);bitmap_set (ram_list.dirty_memory[DIRTY_MEMORY_VGA ], page, end - page);bitmap_set (ram_list.dirty_memory[DIRTY_MEMORY_CODE ], page, end - page); +bitmap_set (ram_list.dirty_memory[DIRTY_MEMORY_LOG_BITMAP ], page, + end - page);xen_modified_memory (start, length); }
@@ -105,6 +117,8 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap, ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION ][page + k] |= temp; ram_list.dirty_memory[DIRTY_MEMORY_VGA ][page + k] |= temp; ram_list.dirty_memory[DIRTY_MEMORY_CODE ][page + k] |= temp; + ram_list.dirty_memory[DIRTY_MEMORY_LOG_BITMAP ][page + k] |= + temp; } }xen_modified_memory (start, pages);
Signature · 1 line
1.8.3.1
PATCH 2/6 bitmap dump code via QAPI framework
In reply to Sanidhya KashyapThis patch introduces the mechanism of dumping the dirty bitmap either in an ascii format or binary format. The implementation is almost similar to the migration one. A separate thread is created for the dumping process.
The bitmap is obtained with the help of ramlist blocks. I have used almost similar functions that have been used in the migration mechanism (in arch_init.c file). The mechanism to save the dirty bitmap is based on RamBlock rather than MemoryRegion. After having a discussion with Juan, there are still some issues with MemoryRegion like
* memory regions can overlap as well as
* no port of TCG to MemoryRegion.
Another point to be noted is that other instance of the bitmap dump process will not execute if there is an already running process.
In this patch, I have introduced log-dirty-bitmap qmp interface to dump the bitmap array.
The logging process has four variables:
1) filename - To dump the data in the file.
2) epochs - It is the number of times, the bitmaps will be logged and dumped in the file. The default value is 3.
3) frequency - Time difference between each epochs. Currently, the default value is 40ms.
4) readable - Its a boolean variable whose default value is false. That is the data is save in human readable format. The first line is the total number of pages followed by size of the bitmap and then the hex dump of the bitmap array.
--- include/qapi/qmp/qerror.h | 3 + qapi-schema.json | 10 ++ qmp-commands.hx | 34 +++++ savevm.c | 318 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 365 insertions(+)
include/qapi/qmp/qerror.h +3 -0
@@ -118,6 +118,9 @@ void qerror_report_err(Error *err);#define QERR_MIGRATION_ACTIVE \ ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress" +#define QERR_LOG_DIRTY_BITMAP_ACTIVE \ + ERROR_CLASS_GENERIC_ERROR, "Dirty bitmap dump already in progress" +#define QERR_MISSING_PARAMETER \ ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
qapi-schema.json +10 -0
@@ -4700,3 +4700,13 @@ 'btn' : 'InputBtnEvent', 'rel' : 'InputMoveEvent', 'abs' : 'InputMoveEvent' } } +## +# @log-dirty-bitmap +# +# provides the dirty bitmap for time t if specified. +## +{ 'command' : 'log-dirty-bitmap', + 'data' : { 'filename' : 'str', + '*epochs' : 'int', + '*frequency' : 'int', + '*readable' : 'bool' } }
qmp-commands.hx +34 -0
@@ -3569,3 +3569,37 @@ Example: } } ] } EQMP + + { + .name = "log-dirty-bitmap", + .args_type = "filename:s,epochs:i?,frequency:i?,readable:-r?", + .mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap, + }, + +SQMP +log-dirty-bitmap +-------------------- + +start logging the memory of the VM for writable working set + +Arguments: + +- "filename": name of the file, in which the bitmap will be saved +- "epochs": number of times, the memory will be logged +- "frequency": time difference in milliseconds between each epoch +- "readable": dumps the bitmap in hex format (non-binary) + +Examples: +-> { "execute" : "log-dirty-bitmap", + "arguments" : { + "filename" : "/tmp/fileXXX", + "epochs" : 100, + "frequency" : 100 } } + +<- { "return": {} } + +Note: The epochs, frequency and readable are optional. epochs default +value is 3 while that of frequency is 40 and readable defaults to false. + +EQMP +
savevm.c +318 -0
330 lines not on this page · raw message
Signature · 1 line
1.8.3.1
Re: [Qemu-devel] [PATCH 2/6] bitmap dump code via QAPI framework
Quoted 17 lines · Sanidhya Kashyap
This patch introduces the mechanism of dumping the dirty bitmap either in an ascii format or binary format. The implementation is almost similar to the migration one. A separate thread is created for the dumping process.
The bitmap is obtained with the help of ramlist blocks. I have used almost similar functions that have been used in the migration mechanism (in
arch_init.cfile). The mechanism to save the dirty bitmap is based on RamBlock rather than MemoryRegion. After having a discussion with Juan, there are still some issues with MemoryRegion like
* memory regions can overlap as well as
* no port of TCG to MemoryRegion.+++
b/include/qapi/qmp/qerror.h
include/qapi/qmp/qerror.h void qerror_report_err(Error *err); · line 123
Quoted 6 lines
include/qapi/qmp/qerror.h +3
-0@@ -118,6 +118,9 @@ void qerror_report_err(Error *err);#define QERR_MIGRATION_ACTIVE \ ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress" +#define QERR_LOG_DIRTY_BITMAP_ACTIVE \ + ERROR_CLASS_GENERIC_ERROR, "Dirty bitmap dump already in progress" +
Please don't add new ERROR_CLASS macros. Instead, just use error_setg() and directly output the error message at the call site that produces the error.
qapi-schema.json line 4706
Quoted 9 lines
qapi-schema.json +5
-0+++ b/qapi-schema.json@@ -4700,3 +4700,13 @@ 'btn' : 'InputBtnEvent', 'rel' : 'InputMoveEvent', 'abs' : 'InputMoveEvent' } } +## +# @log-dirty-bitmap +# +# provides the dirty bitmap for time t if specified.
Too light on the specification. You should document all 4 parameters, and the default value for when the parameters are omitted.
'time t' isn't mentioned in any of the parameter names, so I'm assuming the docs should mention its significance.
Missing a 'Since: 2.1' designation.
qapi-schema.json line 4712
Quoted 6 lines
qapi-schema.json +6
-0+## +{ 'command' : 'log-dirty-bitmap', + 'data' : { 'filename' : 'str', + '*epochs' : 'int', + '*frequency' : 'int', + '*readable' : 'bool' } }
Seems okay. As long as you use qemu_open(), it should also allow management to pass in an fd with the add-fd mechanism.
qmp-commands.hx Example: · line 3588
Quoted 5 lines
qmp-commands.hx +5
-0+ +Arguments: + +- "filename": name of the file, in which the bitmap will be saved +- "epochs": number of times, the memory will be logged
s/times,/times/
Quoted 2 lines
+- "frequency": time difference in milliseconds between each epoch +- "readable": dumps the bitmap in hex format (non-binary)
Possibly a poor choice of naming (binary output IS machine-readable; in fact, programs prefer parsing binary output over decoding human-readable text); maybe 'pretty' or 'text' would have been better; or even invert the sense and have it be 'binary' and default to true. I also wonder if we even need it - I'd rather have the QMP command always output raw binary, and then rely on post-processing to turn it into whatever format the user wants to see (od works wonders), than to bloat qemu with having to generate a human-readable variant.
qmp-commands.hx Example: · line 3602
Quoted 12 lines
qmp-commands.hx +12
-0+ +Examples: +-> { "execute" : "log-dirty-bitmap", + "arguments" : { + "filename" : "/tmp/fileXXX", + "epochs" : 100, + "frequency" : 100 } } + +<- { "return": {} } + +Note: The epochs, frequency and readable are optional. epochs default +value is 3 while that of frequency is 40 and readable defaults to false.
Mention the defaults alongside the description of each parameter, not in a footnote.
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1087
Quoted 6 lines
savevm.c +6
-0+static inline void check_epochs_value (int64_t *epochs,Error **errp) +{ +if (*epochs <=0 ) { +error_setg (errp,"epoch size must be greater than 0, setting" +" a value of 3\n" ); + *epochs =3 ;
This error reporting won't work. Since this function returns void, if errp is set at all, the caller must assume failure, rather than hoping that you replaced the user's bad input with a saner default value. If it was worth reporting the error, then it is not worth trying to fix up the value.
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1126
Quoted 7 lines
savevm.c +7
-0+/* +* copied from arch_init.c file (below function) +*/ + +static void dirty_bitmap_logging_sync_range (ram_addr_t start, +ram_addr_t length) +{
Rather than copying a function, can you make the original non-static and share it between both callers? Otherwise, the two will get out of sync if a bug is fixed in one.
Quoted 14 lines
savevm.c +14
-0+void qmp_log_dirty_bitmap (const char *filename,bool has_epochs, +int64_t epochs,bool has_frequency, +int64_t frequency,bool has_readable, +bool readable,Error **errp) +{ +FILE *f; +BitmapLogState *b =logging_current_state (); + +if (b->state ==LOG_BITMAP_STATE_ACTIVE || + b->state ==LOG_BITMAP_STATE_SETUP || + b->state ==LOG_BITMAP_STATE_CANCELING ) { +error_set (errp,QERR_LOG_DIRTY_BITMAP_ACTIVE ); +return ; + }
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1293
Quoted 10 lines
savevm.c +10
-0+ +if (b->state ==LOG_BITMAP_STATE_COMPLETED ) { +logging_state_set_status (b,LOG_BITMAP_STATE_COMPLETED , +LOG_BITMAP_STATE_NONE ); + }else if (b->state ==LOG_BITMAP_STATE_CANCELLED ) { +logging_state_set_status (b,LOG_BITMAP_STATE_CANCELLED , +LOG_BITMAP_STATE_NONE ); + } + +if (readable) {
readable is undefined if has_readable is false. You are missing something like:
if (!has_readable) {
readable = false;
}savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1296
Quoted 3 lines
savevm.c +3
-0+ f =fopen (filename,"w" ); + }else { + f =fopen (filename,"wb" );
Ouch. You should be using qemu_open, not fopen, so that you can automatically support things like /dev/fdset/NNN when coupled with the 'add-fd' command for passing open file descriptors.
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1307
Quoted 5 lines
savevm.c +5
-0+if (!has_epochs) { + epochs =3 ; + } +if (!has_frequency) { + frequency =40 ;
Magic numbers; use a named constant.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH 2/6] bitmap dump code via QAPI framework
Quoted 8 lines
include/qapi/qmp/qerror.h void qerror_report_err(Error *err); · line 123
Quoted 3 lines
include/qapi/qmp/qerror.h +3
-0+#define QERR_LOG_DIRTY_BITMAP_ACTIVE \ + ERROR_CLASS_GENERIC_ERROR, "Dirty bitmap dump already in progress" +Please don't add new
ERROR_CLASSmacros. Instead, just useerror_setg()and directly output the error message at the call site that produces the error.
will keep in mind in my next version of the patch.
Quoted 13 lines
qapi-schema.json line 4706
Quoted 9 lines
+++
b/qapi-schema.jsonqapi-schema.json +4
-0@@ -4700,3 +4700,13 @@ 'btn' : 'InputBtnEvent', 'rel' : 'InputMoveEvent', 'abs' : 'InputMoveEvent' } } +## +# @log-dirty-bitmap +# +# provides the dirty bitmap for time t if specified.Too light on the specification. You should document all 4 parameters, and the default value for when the parameters are omitted.
Quoted 3 lines
'time t' isn't mentioned in any of the parameter names, so I'm assuming the docs should mention its significance.
ohh!, a bit messy statement, will rectify it.
Quoted 12 lines
Missing a 'Since: 2.1' designation.
qapi-schema.json line 4712
Quoted 6 lines
qapi-schema.json +6
-0+## +{ 'command' : 'log-dirty-bitmap', + 'data' : { 'filename' : 'str', + '*epochs' : 'int', + '*frequency' : 'int', + '*readable' : 'bool' } }Seems okay. As long as you use
qemu_open(), it should also allow management to pass in an fd with the add-fd mechanism.
haven't used qemu_open, will make appropriate changes.
Quoted 11 lines
qmp-commands.hx Example: · line 3588
Quoted 5 lines
qmp-commands.hx +5
-0+ +Arguments: + +- "filename": name of the file, in which the bitmap will be saved +- "epochs": number of times, the memory will be loggeds/times,/times/
Quoted 2 lines
+- "frequency": time difference in milliseconds between each epoch +- "readable": dumps the bitmap in hex format (non-binary)
Quoted 9 lines
Possibly a poor choice of naming (binary output IS machine-readable; in fact, programs prefer parsing binary output over decoding human-readable text); maybe 'pretty' or 'text' would have been better; or even invert the sense and have it be 'binary' and default to true. I also wonder if we even need it - I'd rather have the QMP command always output raw binary, and then rely on post-processing to turn it into whatever format the user wants to see (od works wonders), than to bloat qemu with having to generate a human-readable variant.
will remove the readable (poor naming convention) part from the code and will only dump the data in machine-readable format.
Quoted 14 lines
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1087
Quoted 7 lines
savevm.c +6
-0+static inline void check_epochs_value (int64_t *epochs,Error **errp) +{ +if (*epochs <=0 ) { +error_setg (errp,"epoch size must be greater than 0, setting" +" a value of 3\n" ); + *epochs =3 ;This error reporting won't work. Since this function returns void, if errp is set at all, the caller must assume failure, rather than hoping that you replaced the user's bad input with a saner default value. If it was worth reporting the error, then it is not worth trying to fix up the value.
will correct it.
Quoted 12 lines
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1126
Quoted 7 lines
savevm.c +7
-0+/* +* copied from arch_init.c file (below function) +*/ + +static void dirty_bitmap_logging_sync_range (ram_addr_t start, +ram_addr_t length) +{Rather than copying a function, can you make the original non-static and share it between both callers? Otherwise, the two will get out of sync if a bug is fixed in one.
will have to make certain changes in both files in order for the file to be generic. will do that.
Quoted 8 lines
Quoted 1 line
+ if (readable) {
readable is undefined if
has_readableis false. You are missing something like:if (!has_readable) { readable = false; }
missed it. will keep this in mind.
Quoted 6 lines
savevm.c void do_savevm(Monitor *mon, const QDict *qdict) · line 1307
Quoted 5 lines
savevm.c +5
-0+if (!has_epochs) { + epochs =3 ; + } +if (!has_frequency) { + frequency =40 ;
Quoted 6 lines
Magic numbers; use a named constant.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Thanks for the quick response. Will address all the above issues in my second version of the patch.
--
Sanidhya
PATCH 3/6 hmp interface for dirty bitmap dump
In reply to Sanidhya KashyapAdded the log-dirty-bitmap or ldb hmp interface.
--- hmp-commands.hx | 17 +++++++++++++++++ hmp.c | 19 +++++++++++++++++++ hmp.h | 1 + 3 files changed, 37 insertions(+)
hmp-commands.hx +17 -0
@@ -1774,6 +1774,23 @@ STEXI show available trace events and their state ETEXI + { + .name = "ldb|log-dirty-bitmap", + .args_type = "readable:-r,filename:s,epochs:i?,frequency:i?", + .params = "[-r] filename epochs frequency", + .help = "dumps the memory's dirty bitmap to file\n\t\t\t" + "filename: name of the file in which the bitmap will be saved\n\t\t\t" + "epochs: number of times, the memory will be logged\n\t\t\t" + "frequency: time difference in milliseconds between each epoch\n\t\t\t" + "-r: dumps the bitmap in hex format (non-binary)", + .mhandler.cmd = hmp_log_dirty_bitmap, + }, +STEXI +@item ldb or log-dirty-bitmap [-r] @var{filename} +@findex log-dirty-bitmap +umps the writable working set of the VM's memoryto a file +ETEXI + STEXI @end table ETEXI
hmp.c +19 -0
@@ -1309,6 +1309,25 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)hmp_handle_error (mon, &err); } +void hmp_log_dirty_bitmap (Monitor *mon,const QDict *qdict) +{ +printf ("called\n" ); +int readable =qdict_get_try_bool (qdict,"readable" ,0 ); +const char *filename =qdict_get_str (qdict,"filename" ); +int64_t epochs =qdict_get_try_int (qdict,"epochs" ,3 ); +int64_t frequency =qdict_get_try_int (qdict,"frequency" ,40 ); +Error *err =NULL ; + +printf ("%s %ld %ld %d\n" , filename, epochs, frequency, readable); +qmp_log_dirty_bitmap (filename, !!epochs, epochs, !!frequency, + frequency, !!readable, readable, &err); +if (err) { +monitor_printf (mon,"log-dirty-bitmap: %s\n" ,error_get_pretty (err)); +error_free (err); +return ; + } +} +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict) {Error *err =NULL ;
hmp.h +1 -0
@@ -93,6 +93,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict);void hmp_cpu_add (Monitor *mon,const QDict *qdict);void hmp_object_add (Monitor *mon,const QDict *qdict);void hmp_object_del (Monitor *mon,const QDict *qdict); +void hmp_log_dirty_bitmap (Monitor *mon,const QDict *qdict);void object_add_completion (ReadLineState *rs,int nb_args,const char *str);void object_del_completion (ReadLineState *rs,int nb_args,const char *str);void device_add_completion (ReadLineState *rs,int nb_args,const char *str);
Signature · 1 line
1.8.3.1
PATCH 4/6 cancel mechanism for an already running dump bitmap process
In reply to Sanidhya KashyapThis patch introduces both hmp and qmp (log-dirty-bitmap-cancel) interface to cancel an already executing dump process.
--- hmp-commands.hx | 14 ++++++++++++++ hmp.c | 5 +++++ hmp.h | 1 + qapi-schema.json | 5 +++++ qmp-commands.hx | 20 ++++++++++++++++++++ savevm.c | 19 +++++++++++++++++++ 6 files changed, 64 insertions(+)
hmp-commands.hx +14 -0
@@ -1791,6 +1791,20 @@ STEXI umps the writable working set of the VM's memoryto a file ETEXI + { + .name = "ldbc|log-dirty-bitmap-cancel", + .args_type = "", + .params = "", + .help = "cancel the current VM logging", + .mhandler.cmd = hmp_log_dirty_bitmap_cancel, +}, + +STEXI +@item ldbc or log-dirty-bitmap-cancel +@findex log-dirty-bitmap-cancel +Cancel the current VM migration. +ETEXI + STEXI @end table ETEXI
hmp.c +5 -0
@@ -1328,6 +1328,11 @@ void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict) } } +void hmp_log_dirty_bitmap_cancel (Monitor *mon,const QDict *qdict) +{ +qmp_log_dirty_bitmap_cancel (NULL ); +} +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict) {Error *err =NULL ;
hmp.h +1 -0
@@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);void hmp_object_add (Monitor *mon,const QDict *qdict);void hmp_object_del (Monitor *mon,const QDict *qdict);void hmp_log_dirty_bitmap (Monitor *mon,const QDict *qdict); +void hmp_log_dirty_bitmap_cancel (Monitor *mon,const QDict *qdict);void object_add_completion (ReadLineState *rs,int nb_args,const char *str);void object_del_completion (ReadLineState *rs,int nb_args,const char *str);void device_add_completion (ReadLineState *rs,int nb_args,const char *str);
qapi-schema.json +5 -0
@@ -4710,3 +4710,8 @@ '*epochs' : 'int', '*frequency' : 'int', '*readable' : 'bool' } } +## @log-dirty-bitmap-cancel +# +# cancel the dirty bitmap logging process +## +{ 'command': 'log-dirty-bitmap-cancel' }
qmp-commands.hx +20 -0
@@ -3603,3 +3603,23 @@ value is 3 while that of frequency is 40 and readable defaults to false. EQMP + { + .name = "log-dirty-bitmap-cancel", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_cancel, + }, + +SQMP +log_bitmap_cancel +-------------- + +Cancel the current logging of the dirty bitmap. + +Arguments: None. + +Example: + +-> { "execute": "log-bitmap-cancel" } +<- { "return": {} } + +EQMP
savevm.c +19 -0
@@ -1320,6 +1320,25 @@ void qmp_log_dirty_bitmap(const char *filename, bool has_epochs,return ; } +static void logging_bitmap_cancel (BitmapLogState *b) +{ +int old_state; +do { + old_state = b->state; +if (old_state !=LOG_BITMAP_STATE_SETUP && + old_state !=LOG_BITMAP_STATE_ACTIVE ) { +break ; + } +logging_state_set_status (b, old_state, +LOG_BITMAP_STATE_CANCELING ); + }while (b->state !=LOG_BITMAP_STATE_CANCELING ); +} + +void qmp_log_dirty_bitmap_cancel (Error **errp) +{ +logging_bitmap_cancel (logging_current_state ()); +} +void qmp_xen_save_devices_state (const char *filename,Error **errp) {QEMUFile *f;
Signature · 1 line
1.8.3.1
Re: [Qemu-devel] [PATCH 4/6] cancel mechanism for an already running dump bitmap process
Quoted 8 lines · Sanidhya Kashyap
This patch introduces both hmp and qmp (log-dirty-bitmap-cancel) interface to cancel an already executing dump process.
Signed-off-by Sanidhya Kashyap <[email protected]>---
+++
b/qapi-schema.json
qapi-schema.json line 4716
Quoted 7 lines
qapi-schema.json +4
-0@@ -4710,3 +4710,8 @@ '*epochs' : 'int', '*frequency' : 'int', '*readable' : 'bool' } } +## @log-dirty-bitmap-cancel +# +# cancel the dirty bitmap logging process +##
Missing 'Since: 2.1'; also, the formatting doesn't quite match other commands where ## is on a line by itself at the start.
Quoted 7 lines
qapi-schema.json +1
-0+{ 'command': 'log-dirty-bitmap-cancel' }qmp-commands.hx +0
-0@@ -3603,3 +3603,23 @@ value is 3 while that of frequency is 40 and readable defaults to false.
qmp-commands.hx value is 3 while that of frequency is 40 and readable defaults to false. · line 3613
Quoted 10 lines
qmp-commands.hx +8
-0EQMP + { + .name = "log-dirty-bitmap-cancel", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_cancel, + }, + +SQMP +log_bitmap_cancel
Incorrect command name.
qmp-commands.hx value is 3 while that of frequency is 40 and readable defaults to false. · line 3622
Quoted 9 lines
qmp-commands.hx +9
-0+-------------- + +Cancel the current logging of the dirty bitmap. + +Arguments: None. + +Example: + +-> { "execute": "log-bitmap-cancel" }
And yet another spelling of an incorrect command name.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH 5/6 set the frequency of the dump bitmap process
In reply to Sanidhya KashyapThis patch introduces both qmp and hmp (log-dirty-bitmap-set-frequency) interface to update the value of the frequency.
--- hmp-commands.hx | 15 +++++++++++++++ hmp.c | 12 ++++++++++++ hmp.h | 1 + qapi-schema.json | 8 ++++++++ qmp-commands.hx | 23 +++++++++++++++++++++++ savevm.c | 7 +++++++ 6 files changed, 66 insertions(+)
hmp-commands.hx +15 -0
@@ -1805,6 +1805,21 @@ STEXI Cancel the current VM migration. ETEXI + { + .name = "ldbsf|log-dirty-bitmap-set-frequency", + .args_type = "frequency:i", + .params = "frequency", + .help = "set the frequency for memory logging\n\t\t\t" + "frequency: the new frequency value to replace the existing", + .mhandler.cmd = hmp_log_dirty_bitmap_set_frequency, + }, + +STEXI +@item ldbsf or log-dirty-bitmap-set-frequency @var{frequency} +@findex log-dirty-bitmap-set-frequency +Set the frequency to @var{frequency} (int) for memory logging. +ETEXI + STEXI @end table ETEXI
hmp.c +12 -0
@@ -1333,6 +1333,18 @@ void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict)qmp_log_dirty_bitmap_cancel (NULL ); } +void hmp_log_dirty_bitmap_set_frequency (Monitor *mon,const QDict *qdict) +{ +int64_t frequency =qdict_get_int (qdict,"frequency" ); +Error *err =NULL ; +qmp_log_dirty_bitmap_set_frequency (frequency, &err); +if (err) { +monitor_printf (mon,"log-dirty-bitmap-set-frequency: %s\n" , +error_get_pretty (err)); +error_free (err); + } +} +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict) {Error *err =NULL ;
hmp.h +1 -0
@@ -95,6 +95,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);void hmp_object_del (Monitor *mon,const QDict *qdict);void hmp_log_dirty_bitmap (Monitor *mon,const QDict *qdict);void hmp_log_dirty_bitmap_cancel (Monitor *mon,const QDict *qdict); +void hmp_log_dirty_bitmap_set_frequency (Monitor *mon,const QDict *qdict);void object_add_completion (ReadLineState *rs,int nb_args,const char *str);void object_del_completion (ReadLineState *rs,int nb_args,const char *str);void device_add_completion (ReadLineState *rs,int nb_args,const char *str);
qapi-schema.json +8 -0
@@ -4715,3 +4715,11 @@ # cancel the dirty bitmap logging process ## { 'command': 'log-dirty-bitmap-cancel' } + +## @log-dirty-bitmap-set-frequency +# +# sets the frequency of the dirty bitmap logging process +## +{ 'command': 'log-dirty-bitmap-set-frequency', + 'data': {'frequency': 'int' } } +
qmp-commands.hx +23 -0
@@ -3623,3 +3623,26 @@ Example: <- { "return": {} } EQMP + + { + .name = "log-dirty-bitmap-set-frequency", + .args_type = "frequency:i", + .mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_set_frequency, + }, + +SQMP +log-dirty-bitmap-set-frequency +-------------------- + +Update the frequency for the remaining epochs. + +Arguments: + +- "frequency": the updated frequency (json-int) + +Example: + +-> { "execute": "log-dirty-bitmap-set-frequency", "arguments": { "value": 1024 } } +<- { "return": {} } + +EQMP
savevm.c +7 -0
@@ -1339,6 +1339,13 @@ void qmp_log_dirty_bitmap_cancel(Error **errp)logging_bitmap_cancel (logging_current_state ()); } +void qmp_log_dirty_bitmap_set_frequency (int64_t frequency,Error **errp) +{ +BitmapLogState *b =logging_current_state (); +check_frequency_value (&frequency, errp); + b->current_frequency = frequency; +} +void qmp_xen_save_devices_state (const char *filename,Error **errp) {QEMUFile *f;
Signature · 1 line
1.8.3.1
Re: [Qemu-devel] [PATCH 5/6] set the frequency of the dump bitmap process
Quoted 8 lines · Sanidhya Kashyap
This patch introduces both qmp and hmp (log-dirty-bitmap-set-frequency) interface to update the value of the frequency.
Signed-off-by Sanidhya Kashyap <[email protected]>---
+++
b/qapi-schema.json
qapi-schema.json line 4722
Quoted 8 lines
qapi-schema.json +5
-0@@ -4715,3 +4715,11 @@ # cancel the dirty bitmap logging process ## { 'command': 'log-dirty-bitmap-cancel' } + +## @log-dirty-bitmap-set-frequency +# +# sets the frequency of the dirty bitmap logging process +##
Same comments as in other patches about missing documentation.
qmp-commands.hx
Quoted 4 lines
qapi-schema.json +3
-0+{ 'command': 'log-dirty-bitmap-set-frequency', + 'data': {'frequency': 'int' } } +qmp-commands.hx +0
-0
Please don't end files with an extra blank line.
qmp-commands.hx Example: · line 3641
Quoted 3 lines
qmp-commands.hx +3
-0+Arguments: + +- "frequency": the updated frequency (json-int)
In what unit? I'm assuming milliseconds based on the rest of the series, but spelling it out will help readers.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
PATCH 6/6 python script for extracting bitmap from a binary file
In reply to Sanidhya KashyapThis script extracts the bitmap only from a binary file. It takes only a single input as file. This will be useful to users for exploring the writable working set for the VM.
--- scripts/extract-bitmap.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 scripts/extract-bitmap.py
scripts/extract-bitmap.py new file +68 -0
@@ -0,0 +1,68 @@ +#!/usr/bin/python +# This python script helps in extracting the dirty bitmap present +# in the file after executing the log-dirty-bitmap command either +# from the qmp or hmp interface. This file only processes binary +# file obtained via command. +# +# Copyright (C) Sanidhya Kashyap <[email protected]> +# +# Authors: +# Sanidhya Kashyap +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, see <http://www.gnu.org/licenses/>. +# + +import struct +import argparse +from functools import partial + +long_bytes = 8 +complete_bitmap_list = [] + +def get_unsigned_long_integer(value): + return struct.unpack('<Q', value)[0] + +def get_long_integer(value): + return struct.unpack('<q',value)[0] + +def dump_bitmap(infile, bitmap_length): + count = 1 + bitmap_list = [] + for value in iter(partial(infile.read, long_bytes), ''): + if (count % bitmap_length): + count += 1 + bitmap_list.append(hex(get_unsigned_long_integer(value))) + else: + complete_bitmap_list.append(bitmap_list) + count = 1 + bitmap_list = [] + # currently, the complete list is printed. It is up to the user to decide about + # the usage of the bitmap as the bitmap provides the writable working set of the + # VM for a particular duration. + print complete_bitmap_list + +def main(): + extracter = argparse.ArgumentParser(description='Extract dirty bitmap from binary file.') + extracter.add_argument('infile', help='Input file to extract the bitmap') + args = extracter.parse_args() + print 'The filename is {}'.format(args.infile) + + infile = open(format(args.infile), 'rb') + + ram_bitmap_pages = get_long_integer(infile.read(long_bytes)) + print ram_bitmap_pages + bitmap_length = get_long_integer(infile.read(long_bytes)) + print bitmap_length + + dump_bitmap(infile, bitmap_length); + + infile.close() + +if __name__ == '__main__': + main()
Signature · 1 line
1.8.3.1
Re: [Qemu-devel] [PATCH 6/6] python script for extracting bitmap from a binary file
Quoted 16 lines · Sanidhya Kashyap
This script extracts the bitmap only from a binary file. It takes only a single input as file. This will be useful to users for exploring the writable working set for the VM.
Signed-off-by Sanidhya Kashyap <[email protected]>--- scripts/extract-bitmap.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 scripts/extract-bitmap.pyscripts/extract-bitmap.py new file +0
-0
scripts/extract-bitmap.py line 7
Quoted 7 lines
scripts/extract-bitmap.py new file +7
-0@@ -0,0 +1,68 @@ +#!/usr/bin/python +# This python script helps in extracting the dirty bitmap present +# in the file after executing the log-dirty-bitmap command either +# from the qmp or hmp interface. This file only processes binary +# file obtained via command. +# +# Copyright (C) Sanidhya Kashyap <[email protected]>
Worth listing 2014?
scripts/extract-bitmap.py line 18
Quoted 11 lines
scripts/extract-bitmap.py new file +11
-0+# +# Authors: +# Sanidhya Kashyap +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, see <http://www.gnu.org/licenses/>.
You refer to the GPL, but didn't explicitly state what license this file is under. Did you mean for it to be GPLv2+?
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH 6/6] python script for extracting bitmap from a binary file
Quoted 10 lines · Eric Blake
Quoted 9 lines · Sanidhya Kashyap
This script extracts the bitmap only from a binary file. It takes only a single input as file. This will be useful to users for exploring the writable working set for the VM.
Signed-off-by Sanidhya Kashyap <[email protected]>--- scripts/extract-bitmap.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 scripts/extract-bitmap.py
Does this file need to be mentioned in any Makefile to ensure that it gets distributed as part of the qemu tarball?
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH 6/6] python script for extracting bitmap from a binary file
Quoted 9 lines
Quoted 5 lines
Quoted 5 lines
Signed-off-by Sanidhya Kashyap <[email protected]>--- scripts/extract-bitmap.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 scripts/extract-bitmap.pyDoes this file need to be mentioned in any
Makefileto ensure that it gets distributed as part of the qemu tarball?
No, the file does not need to be mentioned in nay Makefile.
I will add all the required changes in the next version.
Quoted 4 lines
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Signature · 1 line
Sanidhya
Hi,
Nice job. We should avoid running migration_thread and bitmap_logging_thread simultaneously.
Best regards:
ChenLiang
Quoted 44 lines
Hi,
This is the first part of my gsoc work.
Following patches add the support of dirty bitmap logging and dumping to a specified file. These patches provide the mechanism to get the dirty bitmap if the user wants to log the VM besides migration. This can be useful in case of learning about the writable working set of the VM even when it is not being migrated. I know that it will incur huge degradation but still, a user might want to do that. Besides this, this mechanism can also be useful in case of learning about the pages that can be stored in the cache while performing the xbzrle based live migration or even before the beginning of the hybrid (precopy + postcopy) live migration.
I have tried to provide both of the hmp and qmp commands interface to obtain the dirty bitmap. Besides dumping the dirty bitmap, one can also update the frequency with which the logging is taking place or even can cancel the ongoing logging process. Thus, there are 3 hmp and qmp commands interface provided to perform the task.
Sanidhya Kashyap (6):
split dirty bitmap into four for dumping the bitmaps bitmap dump code via QAPI framework
hmp interface for dirty bitmap dump
cancel mechanism for an already running dump bitmap process set the frequency of the dump bitmap process python script for extracting bitmap from a binary fileexec.c | 4 + hmp-commands.hx | 46 +++++++ hmp.c | 36 +++++ hmp.h | 3 + include/exec/memory.h | 3 +- include/exec/ram_addr.h | 16 ++- include/qapi/qmp/qerror.h | 3 + qapi-schema.json | 23 ++++ qmp-commands.hx | 77 +++++++++++ savevm.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++ scripts/extract-bitmap.py | 68 +++++++++ 11 files changed, 621 insertions(+), 2 deletions(-) create mode 100755 scripts/extract-bitmap.py
Quoted 3 lines · ChenLiang
Hi,
Nice job. We should avoid runningmigration_threadandbitmap_logging_threadsimultaneously.
Any particular suggestion to avoid running simultaneous execution of the threads?
--
Sanidhya
Quoted 11 lines · Sanidhya Kashyap
Quoted 3 lines · ChenLiang
Hi,
Nice job. We should avoid runningmigration_threadandbitmap_logging_threadsimultaneously.Any particular suggestion to avoid running simultaneous execution of the threads?
--
Sanidhya
We can do it like this:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02185.html
Quoted 4 lines
We can do it like this:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02185.html
Thanks.
If we are using only one of the threads, then I think we do not require the splitting of the dirty bitmap (
https://lists.gnu.org/archive/html/qemu-devel/2014-05/msg04041.html ). I can directly use the DIRTY_MEMORY_MIGRATION flag. What is your suggestion?
Signature · 1 line
Sanidhya Kashyap
Quoted 6 lines · ChenLiang
Quoted 4 lines · Sanidhya Kashyap
Quoted 3 lines · ChenLiang
Hi,
Nice job. We should avoid runningmigration_threadandbitmap_logging_threadsimultaneously.
Quoted 7 lines
Quoted 3 lines
Any particular suggestion to avoid running simultaneous execution of the threads?
We can do it like this:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02185.html
Hi Chen,
I have some questions which I wanted to get clarified before implementing the above part of avoiding the simultaneous execution.
As the migration process is going on, the RUN_STATE_RUNNING state is being used, which is the same case in bitmap dump process. In order to use the concept of RUN_STATE_* states, should I create two new states as RUN_STATE_LOGBITMAP AND RUN_STATE_OUTMIGRATE? The RUN_STATE_OUTMIGRATE state will have all the transitions that RUN_STATE_RUNNING supports except the ones being used by migration. Similarly, RUN_STATE_MIGRATE will support all the transitions of RUN_STATE_RUNNING except RUN_STATE_LOGBITMAP.
We might also have to update the runstate_is_running function, since RUN_STATE_LOGBITMAP and RUN_STATE_MIGRATE are almost similar in nature to the RUN_STATE_RUNNING. What is your opinion about that?
Is it the only approach to do it or are there any simple and efficient approaches?
Thanks,
Sanidhya
Quoted 33 lines · Sanidhya Kashyap
Quoted 6 lines · ChenLiang
Quoted 4 lines · Sanidhya Kashyap
Quoted 3 lines · ChenLiang
Hi,
Nice job. We should avoid runningmigration_threadandbitmap_logging_threadsimultaneously.Quoted 7 lines
Quoted 3 lines
Any particular suggestion to avoid running simultaneous execution of the threads?
We can do it like this:
https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02185.htmlHi Chen,
I have some questions which I wanted to get clarified before implementing the above part of avoiding the simultaneous execution.
As the migration process is going on, the
RUN_STATE_RUNNINGstate is being used, which is the same case in bitmap dump process. In order to use the concept of RUN_STATE_* states, should I create two new states asRUN_STATE_LOGBITMAPANDRUN_STATE_OUTMIGRATE? TheRUN_STATE_OUTMIGRATEstate will have all the transitions thatRUN_STATE_RUNNINGsupports except the ones being used by migration. Similarly,RUN_STATE_MIGRATEwill support all the transitions ofRUN_STATE_RUNNINGexceptRUN_STATE_LOGBITMAP.We might also have to update the
runstate_is_runningfunction, sinceRUN_STATE_LOGBITMAPandRUN_STATE_MIGRATEare almost similar in nature to theRUN_STATE_RUNNING. What is your opinion about that?
Quoted 7 lines
Is it the only approach to do it or are there any simple and efficient approaches?
Thanks,
Sanidhya
Hmm, I think we need the two flags. Although it is little hard to do it. Because the vm can't do something like hotplug vcpu or device during migrate. But for now qemu don't guarantee it(in my reading). So we should change the vm state RUN_STATE_RUNNING to RUN_STATE_MIGRATE when migrate. BTW, it is not your patches problem.
Best regards
ChenLiang
Quoted 5 lines
Hmm, I think we need the two flags. Although it is little hard to do it. Because the vm can't do something like hotplug vcpu or device during migrate. But for now qemu don't guarantee it(in my reading). So we should change the vm state
RUN_STATE_RUNNINGtoRUN_STATE_MIGRATEwhen migrate. BTW, it is not your patches problem.
Then, I'll go ahead and implement this part using two flags in my second version of the patches.
Quoted 5 lines
cc JuanBest regards
ChenLiang
Signature · 1 line
Sanidhya Kashyap