1 /* 2 * Multifd common functions 3 * 4 * Copyright (c) 2019-2020 Red Hat Inc 5 * 6 * Authors: 7 * Juan Quintela <quintela@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #ifndef QEMU_MIGRATION_MULTIFD_H 14 #define QEMU_MIGRATION_MULTIFD_H 15 16 int multifd_save_setup(Error **errp); 17 void multifd_save_cleanup(void); 18 int multifd_load_setup(Error **errp); 19 int multifd_load_cleanup(Error **errp); 20 bool multifd_recv_all_channels_created(void); 21 bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp); 22 void multifd_recv_sync_main(void); 23 void multifd_send_sync_main(QEMUFile *f); 24 int multifd_queue_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset); 25 26 /* Multifd Compression flags */ 27 #define MULTIFD_FLAG_SYNC (1 << 0) 28 29 /* We reserve 3 bits for compression methods */ 30 #define MULTIFD_FLAG_COMPRESSION_MASK (7 << 1) 31 /* we need to be compatible. Before compression value was 0 */ 32 #define MULTIFD_FLAG_NOCOMP (0 << 1) 33 #define MULTIFD_FLAG_ZLIB (1 << 1) 34 #define MULTIFD_FLAG_ZSTD (2 << 1) 35 36 /* This value needs to be a multiple of qemu_target_page_size() */ 37 #define MULTIFD_PACKET_SIZE (512 * 1024) 38 39 typedef struct { 40 uint32_t magic; 41 uint32_t version; 42 uint32_t flags; 43 /* maximum number of allocated pages */ 44 uint32_t pages_alloc; 45 uint32_t pages_used; 46 /* size of the next packet that contains pages */ 47 uint32_t next_packet_size; 48 uint64_t packet_num; 49 uint64_t unused[4]; /* Reserved for future use */ 50 char ramblock[256]; 51 uint64_t offset[]; 52 } __attribute__((packed)) MultiFDPacket_t; 53 54 typedef struct { 55 /* number of used pages */ 56 uint32_t used; 57 /* number of allocated pages */ 58 uint32_t allocated; 59 /* global number of generated multifd packets */ 60 uint64_t packet_num; 61 /* offset of each page */ 62 ram_addr_t *offset; 63 /* pointer to each page */ 64 struct iovec *iov; 65 RAMBlock *block; 66 } MultiFDPages_t; 67 68 typedef struct { 69 /* this fields are not changed once the thread is created */ 70 /* channel number */ 71 uint8_t id; 72 /* channel thread name */ 73 char *name; 74 /* tls hostname */ 75 char *tls_hostname; 76 /* channel thread id */ 77 QemuThread thread; 78 /* communication channel */ 79 QIOChannel *c; 80 /* sem where to wait for more work */ 81 QemuSemaphore sem; 82 /* this mutex protects the following parameters */ 83 QemuMutex mutex; 84 /* is this channel thread running */ 85 bool running; 86 /* should this thread finish */ 87 bool quit; 88 /* thread has work to do */ 89 int pending_job; 90 /* array of pages to sent */ 91 MultiFDPages_t *pages; 92 /* packet allocated len */ 93 uint32_t packet_len; 94 /* pointer to the packet */ 95 MultiFDPacket_t *packet; 96 /* multifd flags for each packet */ 97 uint32_t flags; 98 /* size of the next packet that contains pages */ 99 uint32_t next_packet_size; 100 /* global number of generated multifd packets */ 101 uint64_t packet_num; 102 /* thread local variables */ 103 /* packets sent through this channel */ 104 uint64_t num_packets; 105 /* pages sent through this channel */ 106 uint64_t num_pages; 107 /* syncs main thread and channels */ 108 QemuSemaphore sem_sync; 109 /* used for compression methods */ 110 void *data; 111 } MultiFDSendParams; 112 113 typedef struct { 114 /* this fields are not changed once the thread is created */ 115 /* channel number */ 116 uint8_t id; 117 /* channel thread name */ 118 char *name; 119 /* channel thread id */ 120 QemuThread thread; 121 /* communication channel */ 122 QIOChannel *c; 123 /* this mutex protects the following parameters */ 124 QemuMutex mutex; 125 /* is this channel thread running */ 126 bool running; 127 /* should this thread finish */ 128 bool quit; 129 /* array of pages to receive */ 130 MultiFDPages_t *pages; 131 /* packet allocated len */ 132 uint32_t packet_len; 133 /* pointer to the packet */ 134 MultiFDPacket_t *packet; 135 /* multifd flags for each packet */ 136 uint32_t flags; 137 /* global number of generated multifd packets */ 138 uint64_t packet_num; 139 /* thread local variables */ 140 /* size of the next packet that contains pages */ 141 uint32_t next_packet_size; 142 /* packets sent through this channel */ 143 uint64_t num_packets; 144 /* pages sent through this channel */ 145 uint64_t num_pages; 146 /* syncs main thread and channels */ 147 QemuSemaphore sem_sync; 148 /* used for de-compression methods */ 149 void *data; 150 } MultiFDRecvParams; 151 152 typedef struct { 153 /* Setup for sending side */ 154 int (*send_setup)(MultiFDSendParams *p, Error **errp); 155 /* Cleanup for sending side */ 156 void (*send_cleanup)(MultiFDSendParams *p, Error **errp); 157 /* Prepare the send packet */ 158 int (*send_prepare)(MultiFDSendParams *p, uint32_t used, Error **errp); 159 /* Write the send packet */ 160 int (*send_write)(MultiFDSendParams *p, uint32_t used, Error **errp); 161 /* Setup for receiving side */ 162 int (*recv_setup)(MultiFDRecvParams *p, Error **errp); 163 /* Cleanup for receiving side */ 164 void (*recv_cleanup)(MultiFDRecvParams *p); 165 /* Read all pages */ 166 int (*recv_pages)(MultiFDRecvParams *p, uint32_t used, Error **errp); 167 } MultiFDMethods; 168 169 void multifd_register_ops(int method, MultiFDMethods *ops); 170 171 #endif 172 173