diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-05-27 10:11:11 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-05-27 10:11:11 +0100 |
| commit | 34c99d7b93c9181aa8c426300beca130b2b19e39 (patch) | |
| tree | d7792ce9c3f0acd47c7dc23313010047d13cc9a9 /hw/net/spapr_llan.c | |
| parent | 84cfc756d158a061bd462473d42b0a9f072218de (diff) | |
| parent | b4daafbd13826dfa9d2596fb0f31f1453611189f (diff) | |
| download | focaccia-qemu-34c99d7b93c9181aa8c426300beca130b2b19e39.tar.gz focaccia-qemu-34c99d7b93c9181aa8c426300beca130b2b19e39.zip | |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.7-20160527' into staging
ppc patch queue for 2016-05-27 (first pull for qemu-2.7) I'm back from holidays now, and have re-collated the ppc patch queue. This is a first pull request against the qemu-2.7 branch, mostly consisting of patches which were posted before the 2.6 freeze, but weren't suitable for late inclusion in the 2.6 branch. * Assorted bugfixes and cleanups * Some preliminary patches towards dynamic DMA windows and CPU hotplug * Significant performance impovement for the spapr-llan device * Added myself to MAINTAINERS for ppc (overdue) # gpg: Signature made Fri 27 May 2016 04:04:15 BST using RSA key ID 20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.7-20160527: MAINTAINERS: Add David Gibson as ppc maintainer spapr_iommu: Move table allocation to helpers spapr_iommu: Finish renaming vfio_accel to need_vfio spapr_pci: Use correct DMA LIOBN when composing the device tree spapr: ensure device trees are always associated with DRC PPC/KVM: early validation of vcpu id Added negative check for get_image_size() hw/net/spapr_llan: Provide counter with dropped rx frames to the guest hw/net/spapr_llan: Delay flushing of the RX queue while adding new RX buffers target-ppc: Cleanups to rldinm, rldnm, rldimi target-ppc: Use 32-bit rotate instead of deposit + 64-bit rotate target-ppc: Use movcond in isel target-ppc: Correct KVM synchronization for ppc_hash64_set_external_hpt() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/net/spapr_llan.c')
| -rw-r--r-- | hw/net/spapr_llan.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index a8266f8ec7..8b2eebd4e3 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -110,6 +110,7 @@ typedef struct VIOsPAPRVLANDevice { hwaddr buf_list; uint32_t add_buf_ptr, use_buf_ptr, rx_bufs; hwaddr rxq_ptr; + QEMUTimer *rxp_timer; uint32_t compat_flags; /* Compatability flags for migration */ RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */ } VIOsPAPRVLANDevice; @@ -122,6 +123,21 @@ static int spapr_vlan_can_receive(NetClientState *nc) } /** + * The last 8 bytes of the receive buffer list page (that has been + * supplied by the guest with the H_REGISTER_LOGICAL_LAN call) contain + * a counter for frames that have been dropped because there was no + * suitable receive buffer available. This function is used to increase + * this counter by one. + */ +static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev) +{ + uint64_t cnt; + + cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8); + vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1); +} + +/** * Get buffer descriptor from one of our receive buffer pools */ static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev, @@ -206,7 +222,8 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, } if (!dev->rx_bufs) { - return -1; + spapr_vlan_record_dropped_rx_frame(dev); + return 0; } if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) { @@ -215,7 +232,8 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, bd = spapr_vlan_get_rx_bd_from_page(dev, size); } if (!bd) { - return -1; + spapr_vlan_record_dropped_rx_frame(dev); + return 0; } dev->rx_bufs--; @@ -266,6 +284,13 @@ static NetClientInfo net_spapr_vlan_info = { .receive = spapr_vlan_receive, }; +static void spapr_vlan_flush_rx_queue(void *opaque) +{ + VIOsPAPRVLANDevice *dev = opaque; + + qemu_flush_queued_packets(qemu_get_queue(dev->nic)); +} + static void spapr_vlan_reset_rx_pool(RxBufPool *rxp) { /* @@ -302,6 +327,9 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp) dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev); qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a); + + dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue, + dev); } static void spapr_vlan_instance_init(Object *obj) @@ -332,6 +360,11 @@ static void spapr_vlan_instance_finalize(Object *obj) dev->rx_pool[i] = NULL; } } + + if (dev->rxp_timer) { + timer_del(dev->rxp_timer); + timer_free(dev->rxp_timer); + } } void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd) @@ -629,7 +662,13 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, dev->rx_bufs++; - qemu_flush_queued_packets(qemu_get_queue(dev->nic)); + /* + * Give guest some more time to add additional RX buffers before we + * flush the receive queue, so that e.g. fragmented IP packets can + * be passed to the guest in one go later (instead of passing single + * fragments if there is only one receive buffer available). + */ + timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500); return H_SUCCESS; } |