blob: a835643b48c85ccbfc20d705eb67af5b09323d17 [file] [log] [blame]
Juan Quintelad32ca5a2020-01-22 16:16:07 +01001/*
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
16int multifd_save_setup(Error **errp);
17void multifd_save_cleanup(void);
18int multifd_load_setup(Error **errp);
Leonardo Brase5bac1f2023-02-10 03:36:28 -030019void multifd_load_cleanup(void);
Leonardo Brascfc3bcf2023-02-10 03:36:31 -030020void multifd_load_shutdown(void);
Juan Quintelad32ca5a2020-01-22 16:16:07 +010021bool multifd_recv_all_channels_created(void);
manish.mishra6720c2b2022-12-20 18:44:18 +000022void multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
Juan Quintelad32ca5a2020-01-22 16:16:07 +010023void multifd_recv_sync_main(void);
Leonardo Bras33d70972022-05-13 03:28:35 -030024int multifd_send_sync_main(QEMUFile *f);
Juan Quintelad32ca5a2020-01-22 16:16:07 +010025int multifd_queue_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset);
26
Juan Quintela7ec2c2b2019-01-04 15:30:06 +010027/* Multifd Compression flags */
Juan Quintelad32ca5a2020-01-22 16:16:07 +010028#define MULTIFD_FLAG_SYNC (1 << 0)
29
Juan Quintelaab7cbb02019-05-15 13:37:46 +020030/* We reserve 3 bits for compression methods */
31#define MULTIFD_FLAG_COMPRESSION_MASK (7 << 1)
32/* we need to be compatible. Before compression value was 0 */
33#define MULTIFD_FLAG_NOCOMP (0 << 1)
Juan Quintela7ec2c2b2019-01-04 15:30:06 +010034#define MULTIFD_FLAG_ZLIB (1 << 1)
Juan Quintela87dc6f52019-12-13 13:47:14 +010035#define MULTIFD_FLAG_ZSTD (2 << 1)
Juan Quintelaab7cbb02019-05-15 13:37:46 +020036
Juan Quintelad32ca5a2020-01-22 16:16:07 +010037/* This value needs to be a multiple of qemu_target_page_size() */
38#define MULTIFD_PACKET_SIZE (512 * 1024)
39
40typedef struct {
41 uint32_t magic;
42 uint32_t version;
43 uint32_t flags;
44 /* maximum number of allocated pages */
45 uint32_t pages_alloc;
Juan Quintela8c0ec0b2021-11-22 14:13:51 +010046 /* non zero pages */
47 uint32_t normal_pages;
Juan Quintelad32ca5a2020-01-22 16:16:07 +010048 /* size of the next packet that contains pages */
49 uint32_t next_packet_size;
50 uint64_t packet_num;
51 uint64_t unused[4]; /* Reserved for future use */
52 char ramblock[256];
53 uint64_t offset[];
54} __attribute__((packed)) MultiFDPacket_t;
55
56typedef struct {
57 /* number of used pages */
Juan Quintela90a3d2f2021-11-22 11:51:40 +010058 uint32_t num;
Juan Quintelad32ca5a2020-01-22 16:16:07 +010059 /* number of allocated pages */
60 uint32_t allocated;
61 /* global number of generated multifd packets */
62 uint64_t packet_num;
63 /* offset of each page */
64 ram_addr_t *offset;
Juan Quintelad32ca5a2020-01-22 16:16:07 +010065 RAMBlock *block;
66} MultiFDPages_t;
67
68typedef struct {
Juan Quintela4a8f19c2022-05-31 12:43:06 +020069 /* Fields are only written at creating/deletion time */
70 /* No lock required for them, they are read only */
71
Juan Quintelad32ca5a2020-01-22 16:16:07 +010072 /* channel number */
73 uint8_t id;
74 /* channel thread name */
75 char *name;
76 /* channel thread id */
77 QemuThread thread;
78 /* communication channel */
79 QIOChannel *c;
Juan Quintela4a8f19c2022-05-31 12:43:06 +020080 /* is the yank function registered */
81 bool registered_yank;
82 /* packet allocated len */
83 uint32_t packet_len;
Juan Quinteladdec20f2022-05-02 16:45:35 +020084 /* guest page size */
85 uint32_t page_size;
Juan Quintelad6f45eb2022-05-02 16:53:12 +020086 /* number of pages in a full packet */
87 uint32_t page_count;
Juan Quintela4a8f19c2022-05-31 12:43:06 +020088 /* multifd flags for sending ram */
89 int write_flags;
90
Juan Quintelad32ca5a2020-01-22 16:16:07 +010091 /* sem where to wait for more work */
92 QemuSemaphore sem;
Juan Quintela4a8f19c2022-05-31 12:43:06 +020093 /* syncs main thread and channels */
94 QemuSemaphore sem_sync;
95
Juan Quintelad32ca5a2020-01-22 16:16:07 +010096 /* this mutex protects the following parameters */
97 QemuMutex mutex;
98 /* is this channel thread running */
99 bool running;
100 /* should this thread finish */
101 bool quit;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100102 /* multifd flags for each packet */
103 uint32_t flags;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100104 /* global number of generated multifd packets */
105 uint64_t packet_num;
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200106 /* thread has work to do */
107 int pending_job;
108 /* array of pages to sent.
109 * The owner of 'pages' depends of 'pending_job' value:
110 * pending_job == 0 -> migration_thread can use it.
111 * pending_job != 0 -> multifd_channel can use it.
112 */
113 MultiFDPages_t *pages;
114
115 /* thread local variables. No locking required */
116
117 /* pointer to the packet */
118 MultiFDPacket_t *packet;
119 /* size of the next packet that contains pages */
120 uint32_t next_packet_size;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100121 /* packets sent through this channel */
122 uint64_t num_packets;
Juan Quintela815956f2021-11-22 13:26:18 +0100123 /* non zero pages sent through this channel */
124 uint64_t total_normal_pages;
Juan Quintela226468b2021-11-19 12:06:05 +0100125 /* buffers to send */
126 struct iovec *iov;
127 /* number of iovs used */
128 uint32_t iovs_num;
Juan Quintela815956f2021-11-22 13:26:18 +0100129 /* Pages that are not zero */
130 ram_addr_t *normal;
131 /* num of non zero pages */
132 uint32_t normal_num;
Juan Quintelaab7cbb02019-05-15 13:37:46 +0200133 /* used for compression methods */
134 void *data;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100135} MultiFDSendParams;
136
137typedef struct {
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200138 /* Fields are only written at creating/deletion time */
139 /* No lock required for them, they are read only */
140
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100141 /* channel number */
142 uint8_t id;
143 /* channel thread name */
144 char *name;
145 /* channel thread id */
146 QemuThread thread;
147 /* communication channel */
148 QIOChannel *c;
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200149 /* packet allocated len */
150 uint32_t packet_len;
Juan Quinteladdec20f2022-05-02 16:45:35 +0200151 /* guest page size */
152 uint32_t page_size;
Juan Quintelad6f45eb2022-05-02 16:53:12 +0200153 /* number of pages in a full packet */
154 uint32_t page_count;
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200155
156 /* syncs main thread and channels */
157 QemuSemaphore sem_sync;
158
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100159 /* this mutex protects the following parameters */
160 QemuMutex mutex;
161 /* is this channel thread running */
162 bool running;
163 /* should this thread finish */
164 bool quit;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100165 /* multifd flags for each packet */
166 uint32_t flags;
167 /* global number of generated multifd packets */
168 uint64_t packet_num;
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200169
170 /* thread local variables. No locking required */
171
172 /* pointer to the packet */
173 MultiFDPacket_t *packet;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100174 /* size of the next packet that contains pages */
175 uint32_t next_packet_size;
176 /* packets sent through this channel */
177 uint64_t num_packets;
Lukas Straub5d1d1fc2023-05-08 21:11:07 +0200178 /* ramblock */
179 RAMBlock *block;
Juan Quintela4a8f19c2022-05-31 12:43:06 +0200180 /* ramblock host address */
181 uint8_t *host;
Juan Quintelacf2d4aa2021-11-22 13:41:06 +0100182 /* non zero pages recv through this channel */
183 uint64_t total_normal_pages;
Juan Quintela226468b2021-11-19 12:06:05 +0100184 /* buffers to recv */
185 struct iovec *iov;
Juan Quintelacf2d4aa2021-11-22 13:41:06 +0100186 /* Pages that are not zero */
187 ram_addr_t *normal;
188 /* num of non zero pages */
189 uint32_t normal_num;
Juan Quintelaab7cbb02019-05-15 13:37:46 +0200190 /* used for de-compression methods */
191 void *data;
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100192} MultiFDRecvParams;
193
Juan Quintelaab7cbb02019-05-15 13:37:46 +0200194typedef struct {
195 /* Setup for sending side */
196 int (*send_setup)(MultiFDSendParams *p, Error **errp);
197 /* Cleanup for sending side */
198 void (*send_cleanup)(MultiFDSendParams *p, Error **errp);
199 /* Prepare the send packet */
Juan Quintela02fb8102021-11-22 12:08:08 +0100200 int (*send_prepare)(MultiFDSendParams *p, Error **errp);
Juan Quintelaab7cbb02019-05-15 13:37:46 +0200201 /* Setup for receiving side */
202 int (*recv_setup)(MultiFDRecvParams *p, Error **errp);
203 /* Cleanup for receiving side */
204 void (*recv_cleanup)(MultiFDRecvParams *p);
205 /* Read all pages */
Juan Quintela40a4bfe2021-11-22 12:49:43 +0100206 int (*recv_pages)(MultiFDRecvParams *p, Error **errp);
Juan Quintelaab7cbb02019-05-15 13:37:46 +0200207} MultiFDMethods;
208
Juan Quintela7ec2c2b2019-01-04 15:30:06 +0100209void multifd_register_ops(int method, MultiFDMethods *ops);
210
Juan Quintelad32ca5a2020-01-22 16:16:07 +0100211#endif
212