From: Jan Kiszka <jan.kiszka@web.de>
To: zwu.kernel@gmail.com
Cc: aliguori@us.ibm.com, Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>,
qemu-devel@nongnu.org, stefanha@linux.vnet.ibm.com,
mst@redhat.com
Subject: Re: [Qemu-devel] [PATCH 2/2] slirp: fix packet requeue issue in batchq
Date: Wed, 15 Feb 2012 09:30:46 +0100 [thread overview]
Message-ID: <4F3B6D36.1030808@web.de> (raw)
In-Reply-To: <1329293587-16246-1-git-send-email-zwu.kernel@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3762 bytes --]
On 2012-02-15 09:13, zwu.kernel@gmail.com wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> This patch fixes the slirp crash in current QEMU upstream.
>
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> ---
> slirp/if.c | 37 ++++++++++++++++++++++++++++++-------
> slirp/mbuf.c | 3 +--
> 2 files changed, 31 insertions(+), 9 deletions(-)
>
> diff --git a/slirp/if.c b/slirp/if.c
> index 8e0cac2..f7f8577 100644
> --- a/slirp/if.c
> +++ b/slirp/if.c
> @@ -20,8 +20,15 @@ ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
> static void
> ifs_remque(struct mbuf *ifm)
> {
> - ifm->ifs_prev->ifs_next = ifm->ifs_next;
> - ifm->ifs_next->ifs_prev = ifm->ifs_prev;
> + if (ifm->ifs_next->ifs_next == ifm
> + && ifm->ifs_next->ifs_prev == ifm) {
> + ifs_init(ifm->ifs_next);
> + } else {
> + ifm->ifs_prev->ifs_next = ifm->ifs_next;
> + ifm->ifs_next->ifs_prev = ifm->ifs_prev;
> + }
> +
> + ifs_init(ifm);
This looks, well, interesting. Can you explain the logic? We really need
to document the queuing mechanics.
> }
>
> void
> @@ -154,14 +161,18 @@ if_start(Slirp *slirp)
> {
> uint64_t now = qemu_get_clock_ns(rt_clock);
> int requeued = 0;
> - struct mbuf *ifm, *ifqt;
> + struct mbuf *ifm, *ifqt, *ifm_next;
>
> - DEBUG_CALL("if_start");
> + DEBUG_CALL("if_start");
>
> - if (slirp->if_queued == 0)
> - return; /* Nothing to do */
> + if (slirp->if_queued == 0)
> + return; /* Nothing to do */
Even if the result looks funny, let's not touch lines just for indention
(and braces would be missing anyway).
> +
> + slirp->next_m = &slirp->if_batchq;
Have you understood the difference between the natural order of
if_batchq and next_m? I still wonder what the latter is good for.
>
> again:
> + ifm_next = NULL;
> +
> /* check if we can really output */
> if (!slirp_can_output(slirp->opaque))
> return;
> @@ -190,6 +201,7 @@ if_start(Slirp *slirp)
> /* If there are more packets for this session, re-queue them */
> if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
> insque(ifm->ifs_next, ifqt);
> + ifm_next = ifm->ifs_next;
> ifs_remque(ifm);
> }
>
> @@ -209,7 +221,18 @@ if_start(Slirp *slirp)
> m_free(ifm);
> } else {
> /* re-queue */
> - insque(ifm, ifqt);
> + if (ifm_next) {
> + /*restore the original state of bachq*/
> + remque(ifm_next);
> + insque(ifm, ifqt);
> + ifm_next->ifs_prev->ifs_next = ifm;
> + ifm->ifs_prev = ifm_next->ifs_prev;
> + ifm->ifs_next = ifm_next;
> + ifm_next->ifs_prev = ifm;
So is this only about the correct ordering or also about pointer
correctness?
> + } else {
> + insque(ifm, ifqt);
> + }
> +
> requeued++;
> }
> }
> diff --git a/slirp/mbuf.c b/slirp/mbuf.c
> index c699c75..f429c0a 100644
> --- a/slirp/mbuf.c
> +++ b/slirp/mbuf.c
> @@ -68,8 +68,7 @@ m_get(Slirp *slirp)
> m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
> m->m_data = m->m_dat;
> m->m_len = 0;
> - m->m_nextpkt = NULL;
> - m->m_prevpkt = NULL;
> + ifs_init(m);
> m->arp_requested = false;
> m->expiration_date = (uint64_t)-1;
> end_error:
Thanks for digging into this, but I really think it needs more comments
and potentially even some cleanups.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
next prev parent reply other threads:[~2012-02-15 8:31 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-15 8:13 [Qemu-devel] [PATCH 2/2] slirp: fix packet requeue issue in batchq zwu.kernel
2012-02-15 8:30 ` Jan Kiszka [this message]
2012-02-16 7:34 ` Zhi Yong Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F3B6D36.1030808@web.de \
--to=jan.kiszka@web.de \
--cc=aliguori@us.ibm.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
--cc=wuzhy@linux.vnet.ibm.com \
--cc=zwu.kernel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.