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 #include "exec/target_page.h" 17 #include "ram.h" 18 19 typedef struct MultiFDRecvData MultiFDRecvData; 20 typedef struct MultiFDSendData MultiFDSendData; 21 22 typedef enum { 23 /* No sync request */ 24 MULTIFD_SYNC_NONE = 0, 25 /* Sync locally on the sender threads without pushing messages */ 26 MULTIFD_SYNC_LOCAL, 27 /* 28 * Sync not only on the sender threads, but also push MULTIFD_FLAG_SYNC 29 * message to the wire for each iochannel (which is for a remote sync). 30 * 31 * When remote sync is used, need to be paired with a follow up 32 * RAM_SAVE_FLAG_EOS / RAM_SAVE_FLAG_MULTIFD_FLUSH message on the main 33 * channel. 34 */ 35 MULTIFD_SYNC_ALL, 36 } MultiFDSyncReq; 37 38 bool multifd_send_setup(void); 39 void multifd_send_shutdown(void); 40 void multifd_send_channel_created(void); 41 int multifd_recv_setup(Error **errp); 42 void multifd_recv_cleanup(void); 43 void multifd_recv_shutdown(void); 44 bool multifd_recv_all_channels_created(void); 45 void multifd_recv_new_channel(QIOChannel *ioc, Error **errp); 46 void multifd_recv_sync_main(void); 47 int multifd_send_sync_main(MultiFDSyncReq req); 48 bool multifd_queue_page(RAMBlock *block, ram_addr_t offset); 49 bool multifd_recv(void); 50 MultiFDRecvData *multifd_get_recv_data(void); 51 52 /* Multifd Compression flags */ 53 #define MULTIFD_FLAG_SYNC (1 << 0) 54 55 /* We reserve 5 bits for compression methods */ 56 #define MULTIFD_FLAG_COMPRESSION_MASK (0x1f << 1) 57 /* we need to be compatible. Before compression value was 0 */ 58 #define MULTIFD_FLAG_NOCOMP (0 << 1) 59 #define MULTIFD_FLAG_ZLIB (1 << 1) 60 #define MULTIFD_FLAG_ZSTD (2 << 1) 61 #define MULTIFD_FLAG_QPL (4 << 1) 62 #define MULTIFD_FLAG_UADK (8 << 1) 63 #define MULTIFD_FLAG_QATZIP (16 << 1) 64 65 /* This value needs to be a multiple of qemu_target_page_size() */ 66 #define MULTIFD_PACKET_SIZE (512 * 1024) 67 68 typedef struct { 69 uint32_t magic; 70 uint32_t version; 71 uint32_t flags; 72 /* maximum number of allocated pages */ 73 uint32_t pages_alloc; 74 /* non zero pages */ 75 uint32_t normal_pages; 76 /* size of the next packet that contains pages */ 77 uint32_t next_packet_size; 78 uint64_t packet_num; 79 /* zero pages */ 80 uint32_t zero_pages; 81 uint32_t unused32[1]; /* Reserved for future use */ 82 uint64_t unused64[3]; /* Reserved for future use */ 83 char ramblock[256]; 84 /* 85 * This array contains the pointers to: 86 * - normal pages (initial normal_pages entries) 87 * - zero pages (following zero_pages entries) 88 */ 89 uint64_t offset[]; 90 } __attribute__((packed)) MultiFDPacket_t; 91 92 typedef struct { 93 /* number of used pages */ 94 uint32_t num; 95 /* number of normal pages */ 96 uint32_t normal_num; 97 RAMBlock *block; 98 /* offset of each page */ 99 ram_addr_t offset[]; 100 } MultiFDPages_t; 101 102 struct MultiFDRecvData { 103 void *opaque; 104 size_t size; 105 /* for preadv */ 106 off_t file_offset; 107 }; 108 109 typedef enum { 110 MULTIFD_PAYLOAD_NONE, 111 MULTIFD_PAYLOAD_RAM, 112 } MultiFDPayloadType; 113 114 typedef union MultiFDPayload { 115 MultiFDPages_t ram; 116 } MultiFDPayload; 117 118 struct MultiFDSendData { 119 MultiFDPayloadType type; 120 MultiFDPayload u; 121 }; 122 123 static inline bool multifd_payload_empty(MultiFDSendData *data) 124 { 125 return data->type == MULTIFD_PAYLOAD_NONE; 126 } 127 128 static inline void multifd_set_payload_type(MultiFDSendData *data, 129 MultiFDPayloadType type) 130 { 131 data->type = type; 132 } 133 134 typedef struct { 135 /* Fields are only written at creating/deletion time */ 136 /* No lock required for them, they are read only */ 137 138 /* channel number */ 139 uint8_t id; 140 /* channel thread name */ 141 char *name; 142 /* channel thread id */ 143 QemuThread thread; 144 bool thread_created; 145 QemuThread tls_thread; 146 bool tls_thread_created; 147 /* communication channel */ 148 QIOChannel *c; 149 /* packet allocated len */ 150 uint32_t packet_len; 151 /* multifd flags for sending ram */ 152 int write_flags; 153 154 /* sem where to wait for more work */ 155 QemuSemaphore sem; 156 /* syncs main thread and channels */ 157 QemuSemaphore sem_sync; 158 159 /* multifd flags for each packet */ 160 uint32_t flags; 161 /* 162 * The sender thread has work to do if either of below field is set. 163 * 164 * @pending_job: a job is pending 165 * @pending_sync: a sync request is pending 166 * 167 * For both of these fields, they're only set by the requesters, and 168 * cleared by the multifd sender threads. 169 */ 170 bool pending_job; 171 MultiFDSyncReq pending_sync; 172 173 MultiFDSendData *data; 174 175 /* thread local variables. No locking required */ 176 177 /* pointer to the packet */ 178 MultiFDPacket_t *packet; 179 /* size of the next packet that contains pages */ 180 uint32_t next_packet_size; 181 /* packets sent through this channel */ 182 uint64_t packets_sent; 183 /* buffers to send */ 184 struct iovec *iov; 185 /* number of iovs used */ 186 uint32_t iovs_num; 187 /* used for compression methods */ 188 void *compress_data; 189 } MultiFDSendParams; 190 191 typedef struct { 192 /* Fields are only written at creating/deletion time */ 193 /* No lock required for them, they are read only */ 194 195 /* channel number */ 196 uint8_t id; 197 /* channel thread name */ 198 char *name; 199 /* channel thread id */ 200 QemuThread thread; 201 bool thread_created; 202 /* communication channel */ 203 QIOChannel *c; 204 /* packet allocated len */ 205 uint32_t packet_len; 206 207 /* syncs main thread and channels */ 208 QemuSemaphore sem_sync; 209 /* sem where to wait for more work */ 210 QemuSemaphore sem; 211 212 /* this mutex protects the following parameters */ 213 QemuMutex mutex; 214 /* should this thread finish */ 215 bool quit; 216 /* multifd flags for each packet */ 217 uint32_t flags; 218 /* global number of generated multifd packets */ 219 uint64_t packet_num; 220 int pending_job; 221 MultiFDRecvData *data; 222 223 /* thread local variables. No locking required */ 224 225 /* pointer to the packet */ 226 MultiFDPacket_t *packet; 227 /* size of the next packet that contains pages */ 228 uint32_t next_packet_size; 229 /* packets received through this channel */ 230 uint64_t packets_recved; 231 /* ramblock */ 232 RAMBlock *block; 233 /* ramblock host address */ 234 uint8_t *host; 235 /* buffers to recv */ 236 struct iovec *iov; 237 /* Pages that are not zero */ 238 ram_addr_t *normal; 239 /* num of non zero pages */ 240 uint32_t normal_num; 241 /* Pages that are zero */ 242 ram_addr_t *zero; 243 /* num of zero pages */ 244 uint32_t zero_num; 245 /* used for de-compression methods */ 246 void *compress_data; 247 /* Flags for the QIOChannel */ 248 int read_flags; 249 } MultiFDRecvParams; 250 251 typedef struct { 252 /* 253 * The send_setup, send_cleanup, send_prepare are only called on 254 * the QEMU instance at the migration source. 255 */ 256 257 /* 258 * Setup for sending side. Called once per channel during channel 259 * setup phase. 260 * 261 * Must allocate p->iov. If packets are in use (default), one 262 * extra iovec must be allocated for the packet header. Any memory 263 * allocated in this hook must be released at send_cleanup. 264 * 265 * p->write_flags may be used for passing flags to the QIOChannel. 266 * 267 * p->compression_data may be used by compression methods to store 268 * compression data. 269 */ 270 int (*send_setup)(MultiFDSendParams *p, Error **errp); 271 272 /* 273 * Cleanup for sending side. Called once per channel during 274 * channel cleanup phase. 275 */ 276 void (*send_cleanup)(MultiFDSendParams *p, Error **errp); 277 278 /* 279 * Prepare the send packet. Called as a result of multifd_send() 280 * on the client side, with p pointing to the MultiFDSendParams of 281 * a channel that is currently idle. 282 * 283 * Must populate p->iov with the data to be sent, increment 284 * p->iovs_num to match the amount of iovecs used and set 285 * p->next_packet_size with the amount of data currently present 286 * in p->iov. 287 * 288 * Must indicate whether this is a compression packet by setting 289 * p->flags. 290 * 291 * As a last step, if packets are in use (default), must prepare 292 * the packet by calling multifd_send_fill_packet(). 293 */ 294 int (*send_prepare)(MultiFDSendParams *p, Error **errp); 295 296 /* 297 * The recv_setup, recv_cleanup, recv are only called on the QEMU 298 * instance at the migration destination. 299 */ 300 301 /* 302 * Setup for receiving side. Called once per channel during 303 * channel setup phase. May be empty. 304 * 305 * May allocate data structures for the receiving of data. May use 306 * p->iov. Compression methods may use p->compress_data. 307 */ 308 int (*recv_setup)(MultiFDRecvParams *p, Error **errp); 309 310 /* 311 * Cleanup for receiving side. Called once per channel during 312 * channel cleanup phase. May be empty. 313 */ 314 void (*recv_cleanup)(MultiFDRecvParams *p); 315 316 /* 317 * Data receive method. Called as a result of multifd_recv() on 318 * the client side, with p pointing to the MultiFDRecvParams of a 319 * channel that is currently idle. Only called if there is data 320 * available to receive. 321 * 322 * Must validate p->flags according to what was set at 323 * send_prepare. 324 * 325 * Must read the data from the QIOChannel p->c. 326 */ 327 int (*recv)(MultiFDRecvParams *p, Error **errp); 328 } MultiFDMethods; 329 330 void multifd_register_ops(int method, const MultiFDMethods *ops); 331 void multifd_send_fill_packet(MultiFDSendParams *p); 332 bool multifd_send_prepare_common(MultiFDSendParams *p); 333 void multifd_send_zero_page_detect(MultiFDSendParams *p); 334 void multifd_recv_zero_page_process(MultiFDRecvParams *p); 335 336 static inline void multifd_send_prepare_header(MultiFDSendParams *p) 337 { 338 p->iov[0].iov_len = p->packet_len; 339 p->iov[0].iov_base = p->packet; 340 p->iovs_num++; 341 } 342 343 void multifd_channel_connect(MultiFDSendParams *p, QIOChannel *ioc); 344 bool multifd_send(MultiFDSendData **send_data); 345 MultiFDSendData *multifd_send_data_alloc(void); 346 347 static inline uint32_t multifd_ram_page_size(void) 348 { 349 return qemu_target_page_size(); 350 } 351 352 static inline uint32_t multifd_ram_page_count(void) 353 { 354 return MULTIFD_PACKET_SIZE / qemu_target_page_size(); 355 } 356 357 void multifd_ram_save_setup(void); 358 void multifd_ram_save_cleanup(void); 359 int multifd_ram_flush_and_sync(QEMUFile *f); 360 bool multifd_ram_sync_per_round(void); 361 bool multifd_ram_sync_per_section(void); 362 size_t multifd_ram_payload_size(void); 363 void multifd_ram_fill_packet(MultiFDSendParams *p); 364 int multifd_ram_unfill_packet(MultiFDRecvParams *p, Error **errp); 365 #endif 366