2 * Multifd common functions
4 * Copyright (c) 2019-2020 Red Hat Inc
7 * Juan Quintela <quintela@redhat.com>
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.
13 #ifndef QEMU_MIGRATION_MULTIFD_H
14 #define QEMU_MIGRATION_MULTIFD_H
18 typedef struct MultiFDRecvData MultiFDRecvData
;
20 bool multifd_send_setup(void);
21 void multifd_send_shutdown(void);
22 void multifd_send_channel_created(void);
23 int multifd_recv_setup(Error
**errp
);
24 void multifd_recv_cleanup(void);
25 void multifd_recv_shutdown(void);
26 bool multifd_recv_all_channels_created(void);
27 void multifd_recv_new_channel(QIOChannel
*ioc
, Error
**errp
);
28 void multifd_recv_sync_main(void);
29 int multifd_send_sync_main(void);
30 bool multifd_queue_page(RAMBlock
*block
, ram_addr_t offset
);
31 bool multifd_recv(void);
32 MultiFDRecvData
*multifd_get_recv_data(void);
34 /* Multifd Compression flags */
35 #define MULTIFD_FLAG_SYNC (1 << 0)
37 /* We reserve 3 bits for compression methods */
38 #define MULTIFD_FLAG_COMPRESSION_MASK (7 << 1)
39 /* we need to be compatible. Before compression value was 0 */
40 #define MULTIFD_FLAG_NOCOMP (0 << 1)
41 #define MULTIFD_FLAG_ZLIB (1 << 1)
42 #define MULTIFD_FLAG_ZSTD (2 << 1)
44 /* This value needs to be a multiple of qemu_target_page_size() */
45 #define MULTIFD_PACKET_SIZE (512 * 1024)
51 /* maximum number of allocated pages */
54 uint32_t normal_pages
;
55 /* size of the next packet that contains pages */
56 uint32_t next_packet_size
;
58 uint64_t unused
[4]; /* Reserved for future use */
61 } __attribute__((packed
)) MultiFDPacket_t
;
64 /* number of used pages */
66 /* number of allocated pages */
68 /* offset of each page */
73 struct MultiFDRecvData
{
81 /* Fields are only written at creating/deletion time */
82 /* No lock required for them, they are read only */
86 /* channel thread name */
88 /* channel thread id */
91 QemuThread tls_thread
;
92 bool tls_thread_created
;
93 /* communication channel */
95 /* packet allocated len */
99 /* number of pages in a full packet */
101 /* multifd flags for sending ram */
104 /* sem where to wait for more work */
106 /* syncs main thread and channels */
107 QemuSemaphore sem_sync
;
109 /* multifd flags for each packet */
112 * The sender thread has work to do if either of below boolean is set.
114 * @pending_job: a job is pending
115 * @pending_sync: a sync request is pending
117 * For both of these fields, they're only set by the requesters, and
118 * cleared by the multifd sender threads.
122 /* array of pages to sent.
123 * The owner of 'pages' depends of 'pending_job' value:
124 * pending_job == 0 -> migration_thread can use it.
125 * pending_job != 0 -> multifd_channel can use it.
127 MultiFDPages_t
*pages
;
129 /* thread local variables. No locking required */
131 /* pointer to the packet */
132 MultiFDPacket_t
*packet
;
133 /* size of the next packet that contains pages */
134 uint32_t next_packet_size
;
135 /* packets sent through this channel */
136 uint64_t packets_sent
;
137 /* non zero pages sent through this channel */
138 uint64_t total_normal_pages
;
139 /* buffers to send */
141 /* number of iovs used */
143 /* used for compression methods */
148 /* Fields are only written at creating/deletion time */
149 /* No lock required for them, they are read only */
153 /* channel thread name */
155 /* channel thread id */
158 /* communication channel */
160 /* packet allocated len */
162 /* guest page size */
164 /* number of pages in a full packet */
167 /* syncs main thread and channels */
168 QemuSemaphore sem_sync
;
169 /* sem where to wait for more work */
172 /* this mutex protects the following parameters */
174 /* should this thread finish */
176 /* multifd flags for each packet */
178 /* global number of generated multifd packets */
181 MultiFDRecvData
*data
;
183 /* thread local variables. No locking required */
185 /* pointer to the packet */
186 MultiFDPacket_t
*packet
;
187 /* size of the next packet that contains pages */
188 uint32_t next_packet_size
;
189 /* packets received through this channel */
190 uint64_t packets_recved
;
193 /* ramblock host address */
195 /* non zero pages recv through this channel */
196 uint64_t total_normal_pages
;
197 /* buffers to recv */
199 /* Pages that are not zero */
201 /* num of non zero pages */
203 /* used for de-compression methods */
208 /* Setup for sending side */
209 int (*send_setup
)(MultiFDSendParams
*p
, Error
**errp
);
210 /* Cleanup for sending side */
211 void (*send_cleanup
)(MultiFDSendParams
*p
, Error
**errp
);
212 /* Prepare the send packet */
213 int (*send_prepare
)(MultiFDSendParams
*p
, Error
**errp
);
214 /* Setup for receiving side */
215 int (*recv_setup
)(MultiFDRecvParams
*p
, Error
**errp
);
216 /* Cleanup for receiving side */
217 void (*recv_cleanup
)(MultiFDRecvParams
*p
);
219 int (*recv
)(MultiFDRecvParams
*p
, Error
**errp
);
222 void multifd_register_ops(int method
, MultiFDMethods
*ops
);
223 void multifd_send_fill_packet(MultiFDSendParams
*p
);
225 static inline void multifd_send_prepare_header(MultiFDSendParams
*p
)
227 p
->iov
[0].iov_len
= p
->packet_len
;
228 p
->iov
[0].iov_base
= p
->packet
;
232 void multifd_channel_connect(MultiFDSendParams
*p
, QIOChannel
*ioc
);