From 339cf6d409598e52f5958c9a0941337281da90db Mon Sep 17 00:00:00 2001 From: Xiao Wang <jasowang@redhat.com> Date: Tue, 24 May 2011 08:35:21 -0300 Subject: [PATCH 1/2] e1000: introduce a helper to check the size of available rx buffers RH-Author: Xiao Wang <jasowang@redhat.com> Message-id: <20110524083521.21571.43279.stgit@dhcp-8-149.nay.redhat.com> Patchwork-id: 25390 O-Subject: [RHEL5.7 V2 PATCH 1/2] e1000: introduce a helper to check the size of available rx buffers Bugzilla: 704097 RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com> RH-Acked-by: Markus Armbruster <armbru@redhat.com> RH-Acked-by: Michael S. Tsirkin <mst@redhat.com> A helper was introduced to check the size of available rx buffer size. This would help reducing packet drop and also for the future support of multiple descriptors. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=704097 Upstream: e1000_has_rxbufs() was originally introduced in 322fd48afbed1ef7b834ac343a0c8687bcb33695. Since we only have single descriptor support for RHEL5 now, the call in e1000_recevie() which is used to avoid rolling back multiple descriptors is not needed. Test status: Tested with my local machine Changed from v1: - Separated into two patches based on Jes and Markus comments - s/opaque/s/ and add explain about why just pick e1000_has_rxbuf() in the commit log based on Juan's comment. Signed-off-by: Jason Wang <jasowang@redhat.com> --- qemu/hw/e1000.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/hw/e1000.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c index 1390f5a..dc17736 100644 --- a/qemu/hw/e1000.c +++ b/qemu/hw/e1000.c @@ -607,6 +607,24 @@ e1000_set_link_status(VLANClientState *vc) set_ics(s, 0, E1000_ICR_LSC); } +static int e1000_has_rxbufs(E1000State *s, size_t total_size) +{ + int bufs; + /* Fast-path short packets */ + if (total_size <= s->rxbuf_size) { + return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov; + } + if (s->mac_reg[RDH] < s->mac_reg[RDT]) { + bufs = s->mac_reg[RDT] - s->mac_reg[RDH]; + } else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) { + bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) + + s->mac_reg[RDT] - s->mac_reg[RDH]; + } else { + return 0; + } + return total_size <= bufs * s->rxbuf_size; +} + static int e1000_can_receive(void *opaque) { -- 1.7.3.2