All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: Fam Zheng <famz@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Peter Crosthwaite <peter.crosthwaite@xilinx.com>,
	Rob Herring <robh@kernel.org>,
	qemu-devel@nongnu.org, Michael Walle <michael@walle.cc>,
	Gerd Hoffmann <kraxel@redhat.com>,
	stefanha@redhat.com,
	"Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Subject: Re: [Qemu-devel] [PATCH for-2.4 06/12] etsec: Flush queue when rx buffer is consumed
Date: Wed, 15 Jul 2015 15:38:06 +0800	[thread overview]
Message-ID: <55A60DDE.3070804@redhat.com> (raw)
In-Reply-To: <20150715060108.GC2412@ad.nay.redhat.com>



On 07/15/2015 02:01 PM, Fam Zheng wrote:
> On Wed, 07/15 13:10, Jason Wang wrote:
>>>> And can we do this without a bh? Otherwise, we may need to stop and
>>>> restart the bh during vm stop and start?
>>> A bh doesn't hurt when vm stop and restart (we get superfluous flush),
>> The problem is qemu_flush_queued_packets() does not check runstate. So
>> it may call .receive() which may modify guest state (DMA or registers).
> You're right, .can_receive will be called incorrectly if the following sequence
> of events is processed by main loop right after we schedule it:
>
>  1) QMP 'stop' command:
>     Runstate is changed to STOP.
>
>  2) tap read:
>     A new packet is read in, but since qemu_can_send_packet is false, it will
>     be queued.
>
>  3) aio_dispatch:
>     This BH is called too late here, and the queue is flushed, which calls
>     .receive().
>
> An ideal fix would be stopping tap with a vmstate handler, but for this patch,
> does the following work?

Looks good for me. How about axienet then since in your series it also
uses a bh?

>
> diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
> index f5170ae..0f5cf44 100644
> --- a/hw/net/fsl_etsec/etsec.c
> +++ b/hw/net/fsl_etsec/etsec.c
> @@ -342,13 +342,22 @@ static ssize_t etsec_receive(NetClientState *nc,
>                               const uint8_t  *buf,
>                               size_t          size)
>  {
> +    ssize_t ret;
>      eTSEC *etsec = qemu_get_nic_opaque(nc);
>  
>  #if defined(HEX_DUMP)
>      fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size);
>      qemu_hexdump(buf, stderr, "", size);
>  #endif
> -    return etsec_rx_ring_write(etsec, buf, size);
> +    /* Flush is unnecessary as are already in receiving path */
> +    etsec->need_flush = false;
> +    ret = etsec_rx_ring_write(etsec, buf, size);
> +    if (ret == 0) {
> +        /* The packet will be queued, let's flush it when buffer is avilable
> +         * again. */
> +        etsec->need_flush = true;
> +    }
> +    return ret;
>  }
>  
>  
> diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h
> index fc41773..e7dc0a4 100644
> --- a/hw/net/fsl_etsec/etsec.h
> +++ b/hw/net/fsl_etsec/etsec.h
> @@ -144,6 +144,8 @@ typedef struct eTSEC {
>      QEMUBH *bh;
>      struct ptimer_state *ptimer;
>  
> +    /* Whether we should flush the rx queue when buffer becomes available. */
> +    bool need_flush;
>  } eTSEC;
>  
>  #define TYPE_ETSEC_COMMON "eTSEC"
> diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
> index a11280b..68e7b6d 100644
> --- a/hw/net/fsl_etsec/rings.c
> +++ b/hw/net/fsl_etsec/rings.c
> @@ -646,6 +646,9 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
>      } else {
>          etsec->rx_buffer_len = 0;
>          etsec->rx_buffer     = NULL;
> +        if (etsec->need_flush) {
> +            qemu_flush_queued_packets(qemu_get_queue(etsec->nic));
> +        }
>      }
>  
>      RING_DEBUG("eTSEC End of ring_write: remaining_data:%zu\n", remaining_data);
>
>

  reply	other threads:[~2015-07-15  7:38 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-14  7:53 [Qemu-devel] [PATCH for-2.4 00/12] hw/net: Fix .can_receive() for NICs Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 01/12] xgmac: Drop packets with eth_can_rx is false Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 02/12] pcnet: Drop pcnet_can_receive Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 03/12] eepro100: Drop nic_can_receive Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 04/12] usbnet: Drop usbnet_can_receive Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 05/12] etsec: Move etsec_can_receive into etsec_receive Fam Zheng
2015-07-14  9:30   ` Jason Wang
2015-07-14  9:49     ` Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 06/12] etsec: Flush queue when rx buffer is consumed Fam Zheng
2015-07-14  9:33   ` Jason Wang
2015-07-14  9:48     ` Fam Zheng
2015-07-15  5:10       ` Jason Wang
2015-07-15  6:01         ` Fam Zheng
2015-07-15  7:38           ` Jason Wang [this message]
2015-07-15  8:04             ` Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 07/12] mcf_fec: Drop mcf_fec_can_receive Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 08/12] milkymist-minimac2: Flush queued packets when link comes up Fam Zheng
2015-07-14 11:02   ` Michael Walle
2015-07-14 11:07     ` Fam Zheng
2015-07-15  7:50       ` Michael Walle
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 09/12] mipsnet: Flush queued packets when receiving is enabled Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 10/12] stellaris_enet: Flush queued packets when read done Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 11/12] dp8393x: Flush packets when link comes up Fam Zheng
2015-07-14  7:53 ` [Qemu-devel] [PATCH for-2.4 12/12] axienet: Flush queued packets when rx is done Fam Zheng
2015-07-14  8:34 ` [Qemu-devel] [PATCH for-2.4 00/12] hw/net: Fix .can_receive() for NICs Wen Congyang
2015-07-15  8:50   ` Stefan Hajnoczi
2015-07-14 14:40 ` Stefan Hajnoczi

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=55A60DDE.3070804@redhat.com \
    --to=jasowang@redhat.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=famz@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=michael@walle.cc \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=robh@kernel.org \
    --cc=stefanha@redhat.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.