[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 2/4] slirp: Fix queue walking in if_start
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v2 2/4] slirp: Fix queue walking in if_start |
Date: |
Fri, 2 Mar 2012 19:57:51 +0100 |
Another attempt to get this right: We need to carefully walk both the
fastq and the batchq in if_start while trying to send packets to
possibly not yet resolved hosts on the virtual network.
So far we just requeued a delayed packet where it was and then started
walking the queues from the top again - that couldn't work. Now we pre-
calculate the next packet in the queue so that the current one can
safely be removed if it was sent successfully. We also need to take into
account that the next packet can be from the same session if the current
one was sent and there are no other sessions.
CC: Fabien Chouteau <address@hidden>
CC: Zhi Yong Wu <address@hidden>
CC: Stefan Weil <address@hidden>
Signed-off-by: Jan Kiszka <address@hidden>
---
slirp/if.c | 46 +++++++++++++++++++++++++++-------------------
1 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/slirp/if.c b/slirp/if.c
index 14fdef1..6f59620 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -158,26 +158,35 @@ void if_start(Slirp *slirp)
{
uint64_t now = qemu_get_clock_ns(rt_clock);
int requeued = 0;
- bool from_batchq = false;
- struct mbuf *ifm, *ifqt;
+ struct mbuf *ifm, *ifm_next, *ifqt;
DEBUG_CALL("if_start");
- while (slirp->if_queued) {
+ if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
+ ifm_next = slirp->if_fastq.ifq_next;
+ } else if (slirp->next_m != &slirp->if_batchq) {
+ /* Nothing on fastq, pick up from batchq via next_m */
+ ifm_next = slirp->next_m;
+ } else {
+ ifm_next = NULL;
+ }
+
+ while (ifm_next) {
/* check if we can really output */
- if (!slirp_can_output(slirp->opaque))
+ if (!slirp_can_output(slirp->opaque)) {
return;
+ }
- /*
- * See which queue to get next packet from
- * If there's something in the fastq, select it immediately
- */
- if (slirp->if_fastq.ifq_next != &slirp->if_fastq) {
- ifm = slirp->if_fastq.ifq_next;
- } else {
- /* Nothing on fastq, pick up from batchq via next_m */
- ifm = slirp->next_m;
- from_batchq = true;
+ ifm = ifm_next;
+
+ ifm_next = ifm->ifq_next;
+ if (ifm_next == &slirp->if_fastq) {
+ /* No more packets in fastq, switch to batchq */
+ ifm_next = slirp->next_m;
+ }
+ if (ifm_next == &slirp->if_batchq) {
+ /* end of batchq */
+ ifm_next = NULL;
}
slirp->if_queued--;
@@ -189,7 +198,7 @@ void if_start(Slirp *slirp)
continue;
}
- if (from_batchq) {
+ if (ifm == slirp->next_m) {
/* Set which packet to send on next iteration */
slirp->next_m = ifm->ifq_next;
}
@@ -202,11 +211,11 @@ void if_start(Slirp *slirp)
if (ifm->ifs_next != ifm) {
insque(ifm->ifs_next, ifqt);
ifs_remque(ifm);
- /* Set next_m if the session packet is now the only one on
- * batchq */
+ /* Set next_m and ifm_next if the session packet is now the only
+ * one on batchq */
if (ifqt == &slirp->if_batchq &&
slirp->next_m == &slirp->if_batchq) {
- slirp->next_m = ifm->ifs_next;
+ slirp->next_m = ifm_next = ifm->ifs_next;
}
}
@@ -217,7 +226,6 @@ void if_start(Slirp *slirp)
}
m_free(ifm);
-
}
slirp->if_queued = requeued;
--
1.7.3.4
- [Qemu-devel] [PATCH v2 0/4] slirp: Fix for requeuing crash, cleanups, Jan Kiszka, 2012/03/02
- [Qemu-devel] [PATCH v2 3/4] slirp: Remove unneeded if_queued, Jan Kiszka, 2012/03/02
- [Qemu-devel] [PATCH v2 4/4] slirp: Cleanup resources on instance removal, Jan Kiszka, 2012/03/02
- [Qemu-devel] [PATCH v2 1/4] slirp: Keep next_m always valid, Jan Kiszka, 2012/03/02
- [Qemu-devel] [PATCH v2 2/4] slirp: Fix queue walking in if_start,
Jan Kiszka <=
- Re: [Qemu-devel] [PATCH v2 0/4] slirp: Fix for requeuing crash, cleanups, Stefan Weil, 2012/03/02