diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-02-22 17:36:27 +0100 |
---|---|---|
committer | Juan Quintela <quintela@redhat.com> | 2013-03-11 13:32:01 +0100 |
commit | 32c835ba3984728c22d4e73cdb595090a60f437e (patch) | |
tree | 48c53ef25b4ec19f1f006694294ca109ef3500f1 /include | |
parent | 8c8de19d93444536d3291e6ab83e2bcf61dd2d0c (diff) |
migration: run pending/iterate callbacks out of big lock
This makes it possible to do blocking writes directly to the socket,
with no buffer in the middle. For RAM, only the migration_bitmap_sync()
call needs the iothread lock. For block migration, it is needed by
the block layer (including bdrv_drain_all and dirty bitmap access),
but because some code is shared between iterate and complete, all of
mig_save_device_dirty is run with the lock taken.
In the savevm case, the iterate callback runs within the big lock.
This is annoying because it complicates the rules. Luckily we do not
need to do anything about it: the RAM iterate callback does not need
the iothread lock, and block migration never runs during savevm.
Reviewed-by: Orit Wasserman <owasserm@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/migration/vmstate.h | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index fdf4e651ad..a816ac3243 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -32,14 +32,25 @@ typedef void SaveStateHandler(QEMUFile *f, void *opaque); typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id); typedef struct SaveVMHandlers { + /* This runs inside the iothread lock. */ void (*set_params)(const MigrationParams *params, void * opaque); SaveStateHandler *save_state; int (*save_live_setup)(QEMUFile *f, void *opaque); void (*cancel)(void *opaque); int (*save_live_complete)(QEMUFile *f, void *opaque); + + /* This runs both outside and inside the iothread lock. */ bool (*is_active)(void *opaque); + + /* This runs outside the iothread lock in the migration case, and + * within the lock in the savevm case. The callback had better only + * use data that is local to the migration thread or protected + * by other locks. + */ int (*save_live_iterate)(QEMUFile *f, void *opaque); + + /* This runs outside the iothread lock! */ uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size); LoadStateHandler *load_state; |