net/colo-compare.c: Optimize compare order for performance

COLO-compare use the glib function g_queue_find_custom to dump
another VM's networking packet to compare. But this function always
start find from the queue->head(here is the newest packet), It will
reduce the success rate of comparison. So this patch reversed
the order of the queues for performance.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Reported-by: leirao <lei.rao@intel.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
Zhang Chen 2022-01-14 13:09:00 +08:00 committed by Jason Wang
parent e29919c93d
commit a5f038e2c5

View File

@ -197,7 +197,7 @@ static void colo_compare_inconsistency_notify(CompareState *s)
/* Use restricted to colo_insert_packet() */ /* Use restricted to colo_insert_packet() */
static gint seq_sorter(Packet *a, Packet *b, gpointer data) static gint seq_sorter(Packet *a, Packet *b, gpointer data)
{ {
return a->tcp_seq - b->tcp_seq; return b->tcp_seq - a->tcp_seq;
} }
static void fill_pkt_tcp_info(void *data, uint32_t *max_ack) static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
@ -421,13 +421,13 @@ pri:
if (g_queue_is_empty(&conn->primary_list)) { if (g_queue_is_empty(&conn->primary_list)) {
return; return;
} }
ppkt = g_queue_pop_head(&conn->primary_list); ppkt = g_queue_pop_tail(&conn->primary_list);
sec: sec:
if (g_queue_is_empty(&conn->secondary_list)) { if (g_queue_is_empty(&conn->secondary_list)) {
g_queue_push_head(&conn->primary_list, ppkt); g_queue_push_tail(&conn->primary_list, ppkt);
return; return;
} }
spkt = g_queue_pop_head(&conn->secondary_list); spkt = g_queue_pop_tail(&conn->secondary_list);
if (ppkt->tcp_seq == ppkt->seq_end) { if (ppkt->tcp_seq == ppkt->seq_end) {
colo_release_primary_pkt(s, ppkt); colo_release_primary_pkt(s, ppkt);
@ -458,7 +458,7 @@ sec:
} }
} }
if (!ppkt) { if (!ppkt) {
g_queue_push_head(&conn->secondary_list, spkt); g_queue_push_tail(&conn->secondary_list, spkt);
goto pri; goto pri;
} }
} }
@ -477,7 +477,7 @@ sec:
if (mark == COLO_COMPARE_FREE_PRIMARY) { if (mark == COLO_COMPARE_FREE_PRIMARY) {
conn->compare_seq = ppkt->seq_end; conn->compare_seq = ppkt->seq_end;
colo_release_primary_pkt(s, ppkt); colo_release_primary_pkt(s, ppkt);
g_queue_push_head(&conn->secondary_list, spkt); g_queue_push_tail(&conn->secondary_list, spkt);
goto pri; goto pri;
} else if (mark == COLO_COMPARE_FREE_SECONDARY) { } else if (mark == COLO_COMPARE_FREE_SECONDARY) {
conn->compare_seq = spkt->seq_end; conn->compare_seq = spkt->seq_end;
@ -490,8 +490,8 @@ sec:
goto pri; goto pri;
} }
} else { } else {
g_queue_push_head(&conn->primary_list, ppkt); g_queue_push_tail(&conn->primary_list, ppkt);
g_queue_push_head(&conn->secondary_list, spkt); g_queue_push_tail(&conn->secondary_list, spkt);
#ifdef DEBUG_COLO_PACKETS #ifdef DEBUG_COLO_PACKETS
qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size); qemu_hexdump(stderr, "colo-compare ppkt", ppkt->data, ppkt->size);
@ -673,7 +673,7 @@ static void colo_compare_packet(CompareState *s, Connection *conn,
while (!g_queue_is_empty(&conn->primary_list) && while (!g_queue_is_empty(&conn->primary_list) &&
!g_queue_is_empty(&conn->secondary_list)) { !g_queue_is_empty(&conn->secondary_list)) {
pkt = g_queue_pop_head(&conn->primary_list); pkt = g_queue_pop_tail(&conn->primary_list);
result = g_queue_find_custom(&conn->secondary_list, result = g_queue_find_custom(&conn->secondary_list,
pkt, (GCompareFunc)HandlePacket); pkt, (GCompareFunc)HandlePacket);
@ -689,7 +689,7 @@ static void colo_compare_packet(CompareState *s, Connection *conn,
* timeout, it will trigger a checkpoint request. * timeout, it will trigger a checkpoint request.
*/ */
trace_colo_compare_main("packet different"); trace_colo_compare_main("packet different");
g_queue_push_head(&conn->primary_list, pkt); g_queue_push_tail(&conn->primary_list, pkt);
colo_compare_inconsistency_notify(s); colo_compare_inconsistency_notify(s);
break; break;
@ -819,7 +819,7 @@ static int compare_chr_send(CompareState *s,
entry->buf = g_malloc(size); entry->buf = g_malloc(size);
memcpy(entry->buf, buf, size); memcpy(entry->buf, buf, size);
} }
g_queue_push_head(&sendco->send_list, entry); g_queue_push_tail(&sendco->send_list, entry);
if (sendco->done) { if (sendco->done) {
sendco->co = qemu_coroutine_create(_compare_chr_send, sendco); sendco->co = qemu_coroutine_create(_compare_chr_send, sendco);
@ -1347,7 +1347,7 @@ static void colo_flush_packets(void *opaque, void *user_data)
Packet *pkt = NULL; Packet *pkt = NULL;
while (!g_queue_is_empty(&conn->primary_list)) { while (!g_queue_is_empty(&conn->primary_list)) {
pkt = g_queue_pop_head(&conn->primary_list); pkt = g_queue_pop_tail(&conn->primary_list);
compare_chr_send(s, compare_chr_send(s,
pkt->data, pkt->data,
pkt->size, pkt->size,
@ -1357,7 +1357,7 @@ static void colo_flush_packets(void *opaque, void *user_data)
packet_destroy_partial(pkt, NULL); packet_destroy_partial(pkt, NULL);
} }
while (!g_queue_is_empty(&conn->secondary_list)) { while (!g_queue_is_empty(&conn->secondary_list)) {
pkt = g_queue_pop_head(&conn->secondary_list); pkt = g_queue_pop_tail(&conn->secondary_list);
packet_destroy(pkt, NULL); packet_destroy(pkt, NULL);
} }
} }