xref: /qemu/migration/multifd.h (revision c5955f4f)
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 bool migrate_multifd_is_allowed(void);
17 void migrate_protocol_allow_multifd(bool allow);
18 int multifd_save_setup(Error **errp);
19 void multifd_save_cleanup(void);
20 int multifd_load_setup(Error **errp);
21 int multifd_load_cleanup(Error **errp);
22 bool multifd_recv_all_channels_created(void);
23 bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
24 void multifd_recv_sync_main(void);
25 void multifd_send_sync_main(QEMUFile *f);
26 int multifd_queue_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset);
27 
28 /* Multifd Compression flags */
29 #define MULTIFD_FLAG_SYNC (1 << 0)
30 
31 /* We reserve 3 bits for compression methods */
32 #define MULTIFD_FLAG_COMPRESSION_MASK (7 << 1)
33 /* we need to be compatible. Before compression value was 0 */
34 #define MULTIFD_FLAG_NOCOMP (0 << 1)
35 #define MULTIFD_FLAG_ZLIB (1 << 1)
36 #define MULTIFD_FLAG_ZSTD (2 << 1)
37 
38 /* This value needs to be a multiple of qemu_target_page_size() */
39 #define MULTIFD_PACKET_SIZE (512 * 1024)
40 
41 typedef struct {
42     uint32_t magic;
43     uint32_t version;
44     uint32_t flags;
45     /* maximum number of allocated pages */
46     uint32_t pages_alloc;
47     /* non zero pages */
48     uint32_t normal_pages;
49     /* size of the next packet that contains pages */
50     uint32_t next_packet_size;
51     uint64_t packet_num;
52     uint64_t unused[4];    /* Reserved for future use */
53     char ramblock[256];
54     uint64_t offset[];
55 } __attribute__((packed)) MultiFDPacket_t;
56 
57 typedef struct {
58     /* number of used pages */
59     uint32_t num;
60     /* number of allocated pages */
61     uint32_t allocated;
62     /* global number of generated multifd packets */
63     uint64_t packet_num;
64     /* offset of each page */
65     ram_addr_t *offset;
66     RAMBlock *block;
67 } MultiFDPages_t;
68 
69 typedef struct {
70     /* this fields are not changed once the thread is created */
71     /* channel number */
72     uint8_t id;
73     /* channel thread name */
74     char *name;
75     /* tls hostname */
76     char *tls_hostname;
77     /* channel thread id */
78     QemuThread thread;
79     /* communication channel */
80     QIOChannel *c;
81     /* sem where to wait for more work */
82     QemuSemaphore sem;
83     /* this mutex protects the following parameters */
84     QemuMutex mutex;
85     /* is this channel thread running */
86     bool running;
87     /* should this thread finish */
88     bool quit;
89     /* is the yank function registered */
90     bool registered_yank;
91     /* thread has work to do */
92     int pending_job;
93     /* array of pages to sent */
94     MultiFDPages_t *pages;
95     /* packet allocated len */
96     uint32_t packet_len;
97     /* pointer to the packet */
98     MultiFDPacket_t *packet;
99     /* multifd flags for each packet */
100     uint32_t flags;
101     /* size of the next packet that contains pages */
102     uint32_t next_packet_size;
103     /* global number of generated multifd packets */
104     uint64_t packet_num;
105     /* thread local variables */
106     /* packets sent through this channel */
107     uint64_t num_packets;
108     /* non zero pages sent through this channel */
109     uint64_t total_normal_pages;
110     /* syncs main thread and channels */
111     QemuSemaphore sem_sync;
112     /* buffers to send */
113     struct iovec *iov;
114     /* number of iovs used */
115     uint32_t iovs_num;
116     /* Pages that are not zero */
117     ram_addr_t *normal;
118     /* num of non zero pages */
119     uint32_t normal_num;
120     /* used for compression methods */
121     void *data;
122 }  MultiFDSendParams;
123 
124 typedef struct {
125     /* this fields are not changed once the thread is created */
126     /* channel number */
127     uint8_t id;
128     /* channel thread name */
129     char *name;
130     /* channel thread id */
131     QemuThread thread;
132     /* communication channel */
133     QIOChannel *c;
134     /* this mutex protects the following parameters */
135     QemuMutex mutex;
136     /* is this channel thread running */
137     bool running;
138     /* should this thread finish */
139     bool quit;
140     /* ramblock host address */
141     uint8_t *host;
142     /* packet allocated len */
143     uint32_t packet_len;
144     /* pointer to the packet */
145     MultiFDPacket_t *packet;
146     /* multifd flags for each packet */
147     uint32_t flags;
148     /* global number of generated multifd packets */
149     uint64_t packet_num;
150     /* thread local variables */
151     /* size of the next packet that contains pages */
152     uint32_t next_packet_size;
153     /* packets sent through this channel */
154     uint64_t num_packets;
155     /* non zero pages recv through this channel */
156     uint64_t total_normal_pages;
157     /* syncs main thread and channels */
158     QemuSemaphore sem_sync;
159     /* buffers to recv */
160     struct iovec *iov;
161     /* Pages that are not zero */
162     ram_addr_t *normal;
163     /* num of non zero pages */
164     uint32_t normal_num;
165     /* used for de-compression methods */
166     void *data;
167 } MultiFDRecvParams;
168 
169 typedef struct {
170     /* Setup for sending side */
171     int (*send_setup)(MultiFDSendParams *p, Error **errp);
172     /* Cleanup for sending side */
173     void (*send_cleanup)(MultiFDSendParams *p, Error **errp);
174     /* Prepare the send packet */
175     int (*send_prepare)(MultiFDSendParams *p, Error **errp);
176     /* Setup for receiving side */
177     int (*recv_setup)(MultiFDRecvParams *p, Error **errp);
178     /* Cleanup for receiving side */
179     void (*recv_cleanup)(MultiFDRecvParams *p);
180     /* Read all pages */
181     int (*recv_pages)(MultiFDRecvParams *p, Error **errp);
182 } MultiFDMethods;
183 
184 void multifd_register_ops(int method, MultiFDMethods *ops);
185 
186 #endif
187 
188