From patchwork Tue Jul 24 21:08:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 43326 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 554A2378B; Tue, 24 Jul 2018 23:09:15 +0200 (CEST) Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by dpdk.org (Postfix) with ESMTP id 536B431FC for ; Tue, 24 Jul 2018 23:09:08 +0200 (CEST) Received: by mail-pg1-f193.google.com with SMTP id y5-v6so3738683pgv.1 for ; Tue, 24 Jul 2018 14:09:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HaoleF6LEwfv/RUyTJXu/pNeriaeB4qgaJoPjlofCcY=; b=IMy+pQXKwlm+HJfMpxX1HrwbyaUpnD4B41BdNQoahnsehZsWzXDDRD01ybSHHiEYfM 7KNQr6W5jvt3NkoVNx7PGKIfjfS5IMuPxhXAUotYB8GFwEy/BagEI3iziuoUKlimnLR8 n915SvBanMoBDt2A3T1Ctm5B75KTfVrPoKsW2rzK4NoaEjRLSITZjANLoRYJBwAU7mB7 pDWp6cYnx9zLufR5+TGyMxxQx554iturCDMUFS4sGIvt683MWo3RBvZcgMlAFeRDCAW5 elHIiw7vkPZgjdB+KmuHy738hWiBfdAtlXIzE0EEqknMJMSCtgjlu0GL75w89j+x99HE h3Og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HaoleF6LEwfv/RUyTJXu/pNeriaeB4qgaJoPjlofCcY=; b=pLCnw8i+a+2dUFo7Pmhfjr6kjUzAoyCsRN2eZK3GuaEbqthp0Xgia3oBeNBf0Mp5XQ pDOrz4jHOOd7CzOiDKT42MgYdW2PZx7TqpiSNgfxFbsuqYyhgjjI4vs8rfSLdy66j9Ci 5OeoGTaQyq27DRC5tmlKURxXx/IwEMfwo+27bvC45BOlE5rUUtDdFCIKzozNbfWoapZt GBQiUiKX+0uoWeEn9BVpI/NZFTzcqQhNDEHJKUnk6Onlwb0dw1D3OWwEB6pSjDVlTHAy HXR7dw3FrsLMEsI1cEcaPBX5R4UGcyjgG/DfbdFQdineCxz2seXOi1LJSJlnkF/GjcrK oZug== X-Gm-Message-State: AOUpUlFj0QGWEvTTriXwy1za09gfXseWkZiR450qdx+Yzl3ggZoxhnwW PIJIaFMXkDtTqZhuwx0jbi+WE/QcVbs= X-Google-Smtp-Source: AAOMgpd+iA30u/hhN2O4/TlsVons6cFJGLFJXSJHtXB6qK9YFB0FckJ292Ju9ZkKvL+toCF/44y/FQ== X-Received: by 2002:a63:2dc1:: with SMTP id t184-v6mr17756291pgt.62.1532466547106; Tue, 24 Jul 2018 14:09:07 -0700 (PDT) Received: from xeon-e3.wavecable.com (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id d11-v6sm16921161pfo.135.2018.07.24.14.09.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Jul 2018 14:09:06 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger , Stephen Hemminger Date: Tue, 24 Jul 2018 14:08:53 -0700 Message-Id: <20180724210853.22767-5-stephen@networkplumber.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180724210853.22767-1-stephen@networkplumber.org> References: <20180724210853.22767-1-stephen@networkplumber.org> Subject: [dpdk-dev] [PATCH 4/4] netvsc/vmbus: avoid signalling host on read X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Don't signal host that receive ring has been read until all events have been processed. This reduces the number of guest exits and therefore improves performance. Signed-off-by: Stephen Hemminger --- drivers/bus/vmbus/rte_bus_vmbus.h | 13 +++++- drivers/bus/vmbus/rte_bus_vmbus_version.map | 1 + drivers/bus/vmbus/vmbus_bufring.c | 3 ++ drivers/bus/vmbus/vmbus_channel.c | 45 +++++++++---------- drivers/net/netvsc/hn_rxtx.c | 49 +++++++-------------- drivers/net/netvsc/hn_var.h | 3 +- 6 files changed, 56 insertions(+), 58 deletions(-) diff --git a/drivers/bus/vmbus/rte_bus_vmbus.h b/drivers/bus/vmbus/rte_bus_vmbus.h index 0100f80ff9a0..4a2c1f6fd918 100644 --- a/drivers/bus/vmbus/rte_bus_vmbus.h +++ b/drivers/bus/vmbus/rte_bus_vmbus.h @@ -337,12 +337,23 @@ int rte_vmbus_chan_recv(struct vmbus_channel *chan, * @param len * Pointer to size of receive buffer (in/out) * @return - * On success, returns 0 + * On success, returns number of bytes read. * On failure, returns negative errno. */ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan, void *data, uint32_t *len); +/** + * Notify host of bytes read (after recv_raw) + * Signals host if required. + * + * @param channel + * Pointer to vmbus_channel structure. + * @param bytes_read + * Number of bytes read since last signal + */ +void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read); + /** * Determine sub channel index of the given channel * diff --git a/drivers/bus/vmbus/rte_bus_vmbus_version.map b/drivers/bus/vmbus/rte_bus_vmbus_version.map index 5324fef4662c..dabb9203104b 100644 --- a/drivers/bus/vmbus/rte_bus_vmbus_version.map +++ b/drivers/bus/vmbus/rte_bus_vmbus_version.map @@ -10,6 +10,7 @@ DPDK_18.08 { rte_vmbus_chan_rx_empty; rte_vmbus_chan_send; rte_vmbus_chan_send_sglist; + rte_vmbus_chan_signal_read; rte_vmbus_chan_signal_tx; rte_vmbus_irq_mask; rte_vmbus_irq_read; diff --git a/drivers/bus/vmbus/vmbus_bufring.c b/drivers/bus/vmbus/vmbus_bufring.c index c2d7d8cc2254..c88001605dbb 100644 --- a/drivers/bus/vmbus/vmbus_bufring.c +++ b/drivers/bus/vmbus/vmbus_bufring.c @@ -221,6 +221,9 @@ vmbus_rxbr_read(struct vmbus_br *rbr, void *data, size_t dlen, size_t skip) if (vmbus_br_availread(rbr) < dlen + skip + sizeof(uint64_t)) return -EAGAIN; + /* Record where host was when we started read (for debug) */ + rbr->windex = rbr->vbr->windex; + /* * Copy channel packet from RX bufring. */ diff --git a/drivers/bus/vmbus/vmbus_channel.c b/drivers/bus/vmbus/vmbus_channel.c index f9feada9b047..cc5f3e8379a5 100644 --- a/drivers/bus/vmbus/vmbus_channel.c +++ b/drivers/bus/vmbus/vmbus_channel.c @@ -176,49 +176,37 @@ bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel) return br->vbr->rindex == br->vbr->windex; } -static int vmbus_read_and_signal(struct vmbus_channel *chan, - void *data, size_t dlen, size_t skip) +/* Signal host after reading N bytes */ +void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read) { struct vmbus_br *rbr = &chan->rxbr; - uint32_t write_sz, pending_sz, bytes_read; - int error; - - /* Record where host was when we started read (for debug) */ - rbr->windex = rbr->vbr->windex; - - /* Read data and skip packet header */ - error = vmbus_rxbr_read(rbr, data, dlen, skip); - if (error) - return error; + uint32_t write_sz, pending_sz; /* No need for signaling on older versions */ if (!rbr->vbr->feature_bits.feat_pending_send_sz) - return 0; + return; /* Make sure reading of pending happens after new read index */ rte_mb(); pending_sz = rbr->vbr->pending_send; if (!pending_sz) - return 0; + return; rte_smp_rmb(); write_sz = vmbus_br_availwrite(rbr, rbr->vbr->windex); - bytes_read = dlen + skip + sizeof(uint64_t); /* If there was space before then host was not blocked */ if (write_sz - bytes_read > pending_sz) - return 0; + return; /* If pending write will not fit */ if (write_sz <= pending_sz) - return 0; + return; vmbus_set_event(chan->device, chan); - return 0; } -/* TODO: replace this with inplace ring buffer (no copy) */ int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len, uint64_t *request_id) { @@ -256,10 +244,16 @@ int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len, if (request_id) *request_id = pkt.xactid; - /* Read data and skip the header */ - return vmbus_read_and_signal(chan, data, dlen, hlen); + /* Read data and skip packet header */ + error = vmbus_rxbr_read(&chan->rxbr, data, dlen, hlen); + if (error) + return error; + + rte_vmbus_chan_signal_read(chan, dlen + hlen + sizeof(uint64_t)); + return 0; } +/* TODO: replace this with inplace ring buffer (no copy) */ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan, void *data, uint32_t *len) { @@ -291,8 +285,13 @@ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan, if (unlikely(dlen > bufferlen)) return -ENOBUFS; - /* Put packet header in data buffer */ - return vmbus_read_and_signal(chan, data, dlen, 0); + /* Read data and skip packet header */ + error = vmbus_rxbr_read(&chan->rxbr, data, dlen, 0); + if (error) + return error; + + /* Return the number of bytes read */ + return dlen + sizeof(uint64_t); } int vmbus_chan_create(const struct rte_vmbus_device *device, diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index 17cebeb74456..38c1612a6ac6 100644 --- a/drivers/net/netvsc/hn_rxtx.c +++ b/drivers/net/netvsc/hn_rxtx.c @@ -40,7 +40,7 @@ #define HN_TXCOPY_THRESHOLD 512 #define HN_RXCOPY_THRESHOLD 256 -#define HN_RXQ_EVENT_DEFAULT 1024 +#define HN_RXQ_EVENT_DEFAULT 2048 struct hn_rxinfo { uint32_t vlan_info; @@ -709,7 +709,8 @@ struct hn_rx_queue *hn_rx_queue_alloc(struct hn_data *hv, { struct hn_rx_queue *rxq; - rxq = rte_zmalloc_socket("HN_RXQ", sizeof(*rxq), + rxq = rte_zmalloc_socket("HN_RXQ", + sizeof(*rxq) + HN_RXQ_EVENT_DEFAULT, RTE_CACHE_LINE_SIZE, socket_id); if (rxq) { rxq->hv = hv; @@ -717,16 +718,6 @@ struct hn_rx_queue *hn_rx_queue_alloc(struct hn_data *hv, rte_spinlock_init(&rxq->ring_lock); rxq->port_id = hv->port_id; rxq->queue_id = queue_id; - - rxq->event_sz = HN_RXQ_EVENT_DEFAULT; - rxq->event_buf = rte_malloc_socket("RX_EVENTS", - rxq->event_sz, - RTE_CACHE_LINE_SIZE, - socket_id); - if (!rxq->event_buf) { - rte_free(rxq); - rxq = NULL; - } } return rxq; } @@ -835,6 +826,7 @@ void hn_process_events(struct hn_data *hv, uint16_t queue_id) { struct rte_eth_dev *dev = &rte_eth_devices[hv->port_id]; struct hn_rx_queue *rxq; + uint32_t bytes_read = 0; int ret = 0; rxq = queue_id == 0 ? hv->primary : dev->data->rx_queues[queue_id]; @@ -852,34 +844,21 @@ void hn_process_events(struct hn_data *hv, uint16_t queue_id) for (;;) { const struct vmbus_chanpkt_hdr *pkt; - uint32_t len = rxq->event_sz; + uint32_t len = HN_RXQ_EVENT_DEFAULT; const void *data; ret = rte_vmbus_chan_recv_raw(rxq->chan, rxq->event_buf, &len); if (ret == -EAGAIN) break; /* ring is empty */ - if (ret == -ENOBUFS) { - /* expanded buffer needed */ - len = rte_align32pow2(len); - PMD_DRV_LOG(DEBUG, "expand event buf to %u", len); - - rxq->event_buf = rte_realloc(rxq->event_buf, - len, RTE_CACHE_LINE_SIZE); - if (rxq->event_buf) { - rxq->event_sz = len; - continue; - } - - rte_exit(EXIT_FAILURE, "can not expand event buf!\n"); - break; - } - - if (ret != 0) { - PMD_DRV_LOG(ERR, "vmbus ring buffer error: %d", ret); - break; - } + else if (ret == -ENOBUFS) + rte_exit(EXIT_FAILURE, "event buffer not big enough (%u < %u)", + HN_RXQ_EVENT_DEFAULT, len); + else if (ret <= 0) + rte_exit(EXIT_FAILURE, + "vmbus ring buffer error: %d", ret); + bytes_read += ret; pkt = (const struct vmbus_chanpkt_hdr *)rxq->event_buf; data = (char *)rxq->event_buf + vmbus_chanpkt_getlen(pkt->hlen); @@ -904,6 +883,10 @@ void hn_process_events(struct hn_data *hv, uint16_t queue_id) if (rxq->rx_ring && rte_ring_full(rxq->rx_ring)) break; } + + if (bytes_read > 0) + rte_vmbus_chan_signal_read(rxq->chan, bytes_read); + rte_spinlock_unlock(&rxq->ring_lock); } diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index 3f3b442697af..f7ff8585bc1c 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -69,7 +69,6 @@ struct hn_rx_queue { struct vmbus_channel *chan; struct rte_mempool *mb_pool; struct rte_ring *rx_ring; - void *event_buf; rte_spinlock_t ring_lock; uint32_t event_sz; @@ -77,6 +76,8 @@ struct hn_rx_queue { uint16_t queue_id; struct hn_stats stats; uint64_t ring_full; + + uint8_t event_buf[]; };