]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
etsec: Flush queue when rx buffer is consumed
authorFam Zheng <famz@redhat.com>
Wed, 15 Jul 2015 10:19:07 +0000 (18:19 +0800)
committerStefan Hajnoczi <stefanha@redhat.com>
Mon, 27 Jul 2015 13:12:18 +0000 (14:12 +0100)
The BH will be scheduled when etsec->rx_buffer_len is becoming 0, which
is the condition of queuing.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1436955553-22791-7-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
hw/net/fsl_etsec/etsec.c
hw/net/fsl_etsec/etsec.h
hw/net/fsl_etsec/rings.c

index f5170aee86f939e276acb3c739b4e452c70b9158..0f5cf4477bbea94805630a84102ed51e9ea90a46 100644 (file)
@@ -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;
 }
 
 
index fc417738ef1797d9693987755ea1b4d7cff47467..e7dc0a4b90c68161fb474aab1b6d901774054840 100644 (file)
@@ -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"
index a11280b2b7c5cc77d91369c4fa19520de6583410..68e7b6d16bafc3a672a0a2f3fe2cc17bde8b9a1c 100644 (file)
@@ -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);