Skip to content

Commit 894fc4f

Browse files
committed
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Fri 11 Jun 2021 03:54:51 BST # gpg: using RSA key EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <[email protected]>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: Fixed calculation error of pkt->header_size in fill_pkt_tcp_info() Add the function of colo_compare_cleanup Add a function named packet_new_nocopy for COLO. Remove migrate_set_block_enabled in checkpoint Optimize the function of filter_send Fix the qemu crash when guest shutdown during checkpoint Remove some duplicate trace code. netdev: add more commands to preconfig mode vhost-vdpa: remove the unused vhost_vdpa_get_acked_features() vhost-vdpa: don't initialize backend_features vhost-vdpa: map virtqueue notification area if possible vhost-vdpa: skip ram device from the IOTLB mapping Signed-off-by: Peter Maydell <[email protected]>
2 parents 7fe7fae + 5a2d992 commit 894fc4f

16 files changed

+143
-59
lines changed

hmp-commands.hx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,7 @@ ERST
12691269
.help = "add host network device",
12701270
.cmd = hmp_netdev_add,
12711271
.command_completion = netdev_add_completion,
1272+
.flags = "p",
12721273
},
12731274

12741275
SRST
@@ -1283,6 +1284,7 @@ ERST
12831284
.help = "remove host network device",
12841285
.cmd = hmp_netdev_del,
12851286
.command_completion = netdev_del_completion,
1287+
.flags = "p",
12861288
},
12871289

12881290
SRST

hw/virtio/vhost-vdpa.c

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section)
2828
{
2929
return (!memory_region_is_ram(section->mr) &&
3030
!memory_region_is_iommu(section->mr)) ||
31+
/* vhost-vDPA doesn't allow MMIO to be mapped */
32+
memory_region_is_ram_device(section->mr) ||
3133
/*
3234
* Sizing an enabled 64-bit BAR can cause spurious mappings to
3335
* addresses in the upper part of the 64-bit address space. These
@@ -172,22 +174,12 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
172174
vaddr, section->readonly);
173175
if (ret) {
174176
error_report("vhost vdpa map fail!");
175-
if (memory_region_is_ram_device(section->mr)) {
176-
/* Allow unexpected mappings not to be fatal for RAM devices */
177-
error_report("map ram fail!");
178-
return ;
179-
}
180177
goto fail;
181178
}
182179

183180
return;
184181

185182
fail:
186-
if (memory_region_is_ram_device(section->mr)) {
187-
error_report("failed to vdpa_dma_map. pci p2p may not work");
188-
return;
189-
190-
}
191183
/*
192184
* On the initfn path, store the first error in the container so we
193185
* can gracefully fail. Runtime, there's not much we can do other
@@ -276,15 +268,12 @@ static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
276268
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
277269
{
278270
struct vhost_vdpa *v;
279-
uint64_t features;
280271
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
281272
trace_vhost_vdpa_init(dev, opaque);
282273

283274
v = opaque;
284275
v->dev = dev;
285276
dev->opaque = opaque ;
286-
vhost_vdpa_call(dev, VHOST_GET_FEATURES, &features);
287-
dev->backend_features = features;
288277
v->listener = vhost_vdpa_memory_listener;
289278
v->msg_type = VHOST_IOTLB_MSG_V2;
290279

@@ -294,12 +283,95 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
294283
return 0;
295284
}
296285

286+
static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev,
287+
int queue_index)
288+
{
289+
size_t page_size = qemu_real_host_page_size;
290+
struct vhost_vdpa *v = dev->opaque;
291+
VirtIODevice *vdev = dev->vdev;
292+
VhostVDPAHostNotifier *n;
293+
294+
n = &v->notifier[queue_index];
295+
296+
if (n->addr) {
297+
virtio_queue_set_host_notifier_mr(vdev, queue_index, &n->mr, false);
298+
object_unparent(OBJECT(&n->mr));
299+
munmap(n->addr, page_size);
300+
n->addr = NULL;
301+
}
302+
}
303+
304+
static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n)
305+
{
306+
int i;
307+
308+
for (i = 0; i < n; i++) {
309+
vhost_vdpa_host_notifier_uninit(dev, i);
310+
}
311+
}
312+
313+
static int vhost_vdpa_host_notifier_init(struct vhost_dev *dev, int queue_index)
314+
{
315+
size_t page_size = qemu_real_host_page_size;
316+
struct vhost_vdpa *v = dev->opaque;
317+
VirtIODevice *vdev = dev->vdev;
318+
VhostVDPAHostNotifier *n;
319+
int fd = v->device_fd;
320+
void *addr;
321+
char *name;
322+
323+
vhost_vdpa_host_notifier_uninit(dev, queue_index);
324+
325+
n = &v->notifier[queue_index];
326+
327+
addr = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED, fd,
328+
queue_index * page_size);
329+
if (addr == MAP_FAILED) {
330+
goto err;
331+
}
332+
333+
name = g_strdup_printf("vhost-vdpa/host-notifier@%p mmaps[%d]",
334+
v, queue_index);
335+
memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name,
336+
page_size, addr);
337+
g_free(name);
338+
339+
if (virtio_queue_set_host_notifier_mr(vdev, queue_index, &n->mr, true)) {
340+
munmap(addr, page_size);
341+
goto err;
342+
}
343+
n->addr = addr;
344+
345+
return 0;
346+
347+
err:
348+
return -1;
349+
}
350+
351+
static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
352+
{
353+
int i;
354+
355+
for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
356+
if (vhost_vdpa_host_notifier_init(dev, i)) {
357+
goto err;
358+
}
359+
}
360+
361+
return;
362+
363+
err:
364+
vhost_vdpa_host_notifiers_uninit(dev, i);
365+
return;
366+
}
367+
297368
static int vhost_vdpa_cleanup(struct vhost_dev *dev)
298369
{
299370
struct vhost_vdpa *v;
300371
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
301372
v = dev->opaque;
302373
trace_vhost_vdpa_cleanup(dev, v);
374+
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
303375
memory_listener_unregister(&v->listener);
304376

305377
dev->opaque = NULL;
@@ -476,6 +548,7 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
476548
if (started) {
477549
uint8_t status = 0;
478550
memory_listener_register(&v->listener, &address_space_memory);
551+
vhost_vdpa_host_notifiers_init(dev);
479552
vhost_vdpa_set_vring_ready(dev);
480553
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
481554
vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
@@ -485,6 +558,7 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
485558
vhost_vdpa_reset_device(dev);
486559
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
487560
VIRTIO_CONFIG_S_DRIVER);
561+
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
488562
memory_listener_unregister(&v->listener);
489563

490564
return 0;

include/hw/virtio/vhost-vdpa.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@
1414

1515
#include "hw/virtio/virtio.h"
1616

17+
typedef struct VhostVDPAHostNotifier {
18+
MemoryRegion mr;
19+
void *addr;
20+
} VhostVDPAHostNotifier;
21+
1722
typedef struct vhost_vdpa {
1823
int device_fd;
1924
uint32_t msg_type;
2025
MemoryListener listener;
2126
struct vhost_dev *dev;
27+
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
2228
} VhostVDPA;
2329

2430
#endif

include/net/vhost-vdpa.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#define TYPE_VHOST_VDPA "vhost-vdpa"
1616

1717
struct vhost_net *vhost_vdpa_get_vhost_net(NetClientState *nc);
18-
uint64_t vhost_vdpa_get_acked_features(NetClientState *nc);
1918

2019
extern const int vdpa_feature_bits[];
2120

migration/colo.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,6 @@ static int colo_do_checkpoint_transaction(MigrationState *s,
435435
if (failover_get_state() != FAILOVER_STATUS_NONE) {
436436
goto out;
437437
}
438-
439-
/* Disable block migration */
440-
migrate_set_block_enabled(false, &local_err);
441-
if (local_err) {
442-
goto out;
443-
}
444438
qemu_mutex_lock_iothread();
445439

446440
#ifdef CONFIG_REPLICATION

migration/migration.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,10 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
22172217
}
22182218

22192219
if (blk || blk_inc) {
2220+
if (migrate_colo_enabled()) {
2221+
error_setg(errp, "No disk migration is required in COLO mode");
2222+
return false;
2223+
}
22202224
if (migrate_use_block() || migrate_use_block_incremental()) {
22212225
error_setg(errp, "Command options are incompatible with "
22222226
"current migration capabilities");

net/colo-compare.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
211211
pkt->tcp_ack = ntohl(tcphd->th_ack);
212212
*max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
213213
pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
214-
+ (tcphd->th_off << 2) - pkt->vnet_hdr_len;
214+
+ (tcphd->th_off << 2);
215215
pkt->payload_size = pkt->size - pkt->header_size;
216216
pkt->seq_end = pkt->tcp_seq + pkt->payload_size;
217217
pkt->flags = tcphd->th_flags;
@@ -590,19 +590,6 @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
590590
uint16_t offset = ppkt->vnet_hdr_len;
591591

592592
trace_colo_compare_main("compare other");
593-
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_IP_INFO)) {
594-
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
595-
596-
strcpy(pri_ip_src, inet_ntoa(ppkt->ip->ip_src));
597-
strcpy(pri_ip_dst, inet_ntoa(ppkt->ip->ip_dst));
598-
strcpy(sec_ip_src, inet_ntoa(spkt->ip->ip_src));
599-
strcpy(sec_ip_dst, inet_ntoa(spkt->ip->ip_dst));
600-
601-
trace_colo_compare_ip_info(ppkt->size, pri_ip_src,
602-
pri_ip_dst, spkt->size,
603-
sec_ip_src, sec_ip_dst);
604-
}
605-
606593
if (ppkt->size != spkt->size) {
607594
trace_colo_compare_main("Other: payload size of packets are different");
608595
return -1;
@@ -1415,6 +1402,16 @@ static void colo_compare_init(Object *obj)
14151402
compare_set_vnet_hdr);
14161403
}
14171404

1405+
void colo_compare_cleanup(void)
1406+
{
1407+
CompareState *tmp = NULL;
1408+
CompareState *n = NULL;
1409+
1410+
QTAILQ_FOREACH_SAFE(tmp, &net_compares, next, n) {
1411+
object_unparent(OBJECT(tmp));
1412+
}
1413+
}
1414+
14181415
static void colo_compare_finalize(Object *obj)
14191416
{
14201417
CompareState *s = COLO_COMPARE(obj);

net/colo-compare.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
void colo_notify_compares_event(void *opaque, int event, Error **errp);
2121
void colo_compare_register_notifier(Notifier *notify);
2222
void colo_compare_unregister_notifier(Notifier *notify);
23+
void colo_compare_cleanup(void);
2324

2425
#endif /* QEMU_COLO_COMPARE_H */

net/colo.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,28 @@ void connection_destroy(void *opaque)
157157

158158
Packet *packet_new(const void *data, int size, int vnet_hdr_len)
159159
{
160-
Packet *pkt = g_slice_new(Packet);
160+
Packet *pkt = g_slice_new0(Packet);
161161

162162
pkt->data = g_memdup(data, size);
163163
pkt->size = size;
164164
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
165165
pkt->vnet_hdr_len = vnet_hdr_len;
166-
pkt->tcp_seq = 0;
167-
pkt->tcp_ack = 0;
168-
pkt->seq_end = 0;
169-
pkt->header_size = 0;
170-
pkt->payload_size = 0;
171-
pkt->offset = 0;
172-
pkt->flags = 0;
166+
167+
return pkt;
168+
}
169+
170+
/*
171+
* packet_new_nocopy will not copy data, so the caller can't release
172+
* the data. And it will be released in packet_destroy.
173+
*/
174+
Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len)
175+
{
176+
Packet *pkt = g_slice_new0(Packet);
177+
178+
pkt->data = data;
179+
pkt->size = size;
180+
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
181+
pkt->vnet_hdr_len = vnet_hdr_len;
173182

174183
return pkt;
175184
}

net/colo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ bool connection_has_tracked(GHashTable *connection_track_table,
101101
ConnectionKey *key);
102102
void connection_hashtable_reset(GHashTable *connection_track_table);
103103
Packet *packet_new(const void *data, int size, int vnet_hdr_len);
104+
Packet *packet_new_nocopy(void *data, int size, int vnet_hdr_len);
104105
void packet_destroy(void *opaque, void *user_data);
105106
void packet_destroy_partial(void *opaque, void *user_data);
106107

net/filter-mirror.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static int filter_send(MirrorState *s,
8888
goto err;
8989
}
9090

91-
return 0;
91+
return size;
9292

9393
err:
9494
return ret < 0 ? ret : -EIO;
@@ -159,7 +159,7 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
159159
int ret;
160160

161161
ret = filter_send(s, iov, iovcnt);
162-
if (ret) {
162+
if (ret < 0) {
163163
error_report("filter mirror send failed(%s)", strerror(-ret));
164164
}
165165

@@ -182,10 +182,10 @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
182182

183183
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
184184
ret = filter_send(s, iov, iovcnt);
185-
if (ret) {
185+
if (ret < 0) {
186186
error_report("filter redirector send failed(%s)", strerror(-ret));
187187
}
188-
return iov_size(iov, iovcnt);
188+
return ret;
189189
} else {
190190
return 0;
191191
}

net/filter-rewriter.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
270270
vnet_hdr_len = nf->netdev->vnet_hdr_len;
271271
}
272272

273-
pkt = packet_new(buf, size, vnet_hdr_len);
274-
g_free(buf);
273+
pkt = packet_new_nocopy(buf, size, vnet_hdr_len);
275274

276275
/*
277276
* if we get tcp packet

net/net.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "qapi/error.h"
5353
#include "qapi/opts-visitor.h"
5454
#include "sysemu/runstate.h"
55+
#include "net/colo-compare.h"
5556
#include "net/filter.h"
5657
#include "qapi/string-output-visitor.h"
5758

@@ -1402,6 +1403,9 @@ void net_cleanup(void)
14021403
{
14031404
NetClientState *nc;
14041405

1406+
/*cleanup colo compare module for COLO*/
1407+
colo_compare_cleanup();
1408+
14051409
/* We may del multiple entries during qemu_del_net_client(),
14061410
* so QTAILQ_FOREACH_SAFE() is also not safe here.
14071411
*/

net/vhost-vdpa.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,6 @@ VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
6868
return s->vhost_net;
6969
}
7070

71-
uint64_t vhost_vdpa_get_acked_features(NetClientState *nc)
72-
{
73-
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
74-
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
75-
s->acked_features = vhost_net_get_acked_features(s->vhost_net);
76-
77-
return s->acked_features;
78-
}
79-
8071
static int vhost_vdpa_net_check_device_id(struct vhost_net *net)
8172
{
8273
uint32_t device_id;

0 commit comments

Comments
 (0)