5d360b
From 082c19eeb7917a141bae4cf98d0ef941956adab6 Mon Sep 17 00:00:00 2001
5d360b
From: Xiao Wang <jasowang@redhat.com>
5d360b
Date: Mon, 27 Nov 2017 07:07:57 +0100
5d360b
Subject: [PATCH 6/9] slirp: fix clearing ifq_so from pending packets
5d360b
MIME-Version: 1.0
5d360b
Content-Type: text/plain; charset=UTF-8
5d360b
Content-Transfer-Encoding: 8bit
5d360b
5d360b
RH-Author: Xiao Wang <jasowang@redhat.com>
5d360b
Message-id: <1511766477-29559-5-git-send-email-jasowang@redhat.com>
5d360b
Patchwork-id: 77901
5d360b
O-Subject: [RHEL7.5 qemu-kvm PATCH 4/4] slirp: fix clearing ifq_so from pending packets
5d360b
Bugzilla: 1508745
5d360b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
5d360b
RH-Acked-by: wexu@redhat.com
5d360b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
5d360b
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
5d360b
5d360b
The if_fastq and if_batchq contain not only packets, but queues of packets
5d360b
for the same socket. When sofree frees a socket, it thus has to clear ifq_so
5d360b
from all the packets from the queues, not only the first.
5d360b
5d360b
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
5d360b
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5d360b
Cc: qemu-stable@nongnu.org
5d360b
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5d360b
(cherry picked from commit 1201d308519f1e915866d7583d5136d03cc1d384)
5d360b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
---
5d360b
 slirp/socket.c | 39 +++++++++++++++++++++++----------------
5d360b
 1 file changed, 23 insertions(+), 16 deletions(-)
5d360b
5d360b
diff --git a/slirp/socket.c b/slirp/socket.c
5d360b
index 09b5d3d..7837664 100644
5d360b
--- a/slirp/socket.c
5d360b
+++ b/slirp/socket.c
5d360b
@@ -57,29 +57,36 @@ socreate(Slirp *slirp)
5d360b
 }
5d360b
 
5d360b
 /*
5d360b
+ * Remove references to so from the given message queue.
5d360b
+ */
5d360b
+static void
5d360b
+soqfree(struct socket *so, struct quehead *qh)
5d360b
+{
5d360b
+    struct mbuf *ifq;
5d360b
+
5d360b
+    for (ifq = (struct mbuf *) qh->qh_link;
5d360b
+             (struct quehead *) ifq != qh;
5d360b
+             ifq = ifq->ifq_next) {
5d360b
+        if (ifq->ifq_so == so) {
5d360b
+            struct mbuf *ifm;
5d360b
+            ifq->ifq_so = NULL;
5d360b
+            for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
5d360b
+                ifm->ifq_so = NULL;
5d360b
+            }
5d360b
+        }
5d360b
+    }
5d360b
+}
5d360b
+
5d360b
+/*
5d360b
  * remque and free a socket, clobber cache
5d360b
  */
5d360b
 void
5d360b
 sofree(struct socket *so)
5d360b
 {
5d360b
   Slirp *slirp = so->slirp;
5d360b
-  struct mbuf *ifm;
5d360b
-
5d360b
-  for (ifm = (struct mbuf *) slirp->if_fastq.qh_link;
5d360b
-       (struct quehead *) ifm != &slirp->if_fastq;
5d360b
-       ifm = ifm->ifq_next) {
5d360b
-    if (ifm->ifq_so == so) {
5d360b
-      ifm->ifq_so = NULL;
5d360b
-    }
5d360b
-  }
5d360b
 
5d360b
-  for (ifm = (struct mbuf *) slirp->if_batchq.qh_link;
5d360b
-       (struct quehead *) ifm != &slirp->if_batchq;
5d360b
-       ifm = ifm->ifq_next) {
5d360b
-    if (ifm->ifq_so == so) {
5d360b
-      ifm->ifq_so = NULL;
5d360b
-    }
5d360b
-  }
5d360b
+  soqfree(so, &slirp->if_fastq);
5d360b
+  soqfree(so, &slirp->if_batchq);
5d360b
 
5d360b
   if (so->so_emu==EMU_RSH && so->extra) {
5d360b
 	sofree(so->extra);
5d360b
-- 
5d360b
1.8.3.1
5d360b