From: ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b@public.gmane.org
Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dennis.dalessandro-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
mike.marciniszyn-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
Niranjana Vishwanathapura
<niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Ira Weiny <ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: [PATCH v2 06/22] staging/rdma/hfi1: Add coalescing support for SDMA TX descriptors
Date: Mon, 19 Oct 2015 22:11:21 -0400 [thread overview]
Message-ID: <1445307097-8244-7-git-send-email-ira.weiny@intel.com> (raw)
In-Reply-To: <1445307097-8244-1-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
From: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
This fixes transmit errors when the number of scatter gather elements in the
request is more that the number of per packet descriptors supported by the
hardware, allocate and coalesce the extra scatter gather elements into a single
buffer. The last descriptor is reserved and used for this coalesced buffer.
Verbs potentially need this support when transferring small data chunks
involving different memory regions.
Reviewed-by: Mike Marciniszyn <mike.marciniszyn-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Reviewed-by: Mitko Haralanov <mitko.haralanov-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Ira Weiny <ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
drivers/staging/rdma/hfi1/sdma.c | 124 ++++++++++++++++++++++++++++++++++++---
drivers/staging/rdma/hfi1/sdma.h | 74 +++++++++++++++--------
2 files changed, 168 insertions(+), 30 deletions(-)
diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/staging/rdma/hfi1/sdma.c
index d57531796723..53b3e4d9518b 100644
--- a/drivers/staging/rdma/hfi1/sdma.c
+++ b/drivers/staging/rdma/hfi1/sdma.c
@@ -55,6 +55,7 @@
#include <linux/bitops.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
+#include <linux/highmem.h>
#include "hfi.h"
#include "common.h"
@@ -2706,27 +2707,134 @@ static void __sdma_process_event(struct sdma_engine *sde,
* of descriptors in the sdma_txreq is exhausted.
*
* The code will bump the allocation up to the max
- * of MAX_DESC (64) descriptors. There doesn't seem
- * much point in an interim step.
+ * of MAX_DESC (64) descriptors. There doesn't seem
+ * much point in an interim step. The last descriptor
+ * is reserved for coalesce buffer in order to support
+ * cases where input packet has >MAX_DESC iovecs.
*
*/
-int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
+static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
{
int i;
+ /* Handle last descriptor */
+ if (unlikely((tx->num_desc == (MAX_DESC - 1)))) {
+ /* if tlen is 0, it is for padding, release last descriptor */
+ if (!tx->tlen) {
+ tx->desc_limit = MAX_DESC;
+ } else if (!tx->coalesce_buf) {
+ /* allocate coalesce buffer with space for padding */
+ tx->coalesce_buf = kmalloc(tx->tlen + sizeof(u32),
+ GFP_ATOMIC);
+ if (!tx->coalesce_buf)
+ return -ENOMEM;
+
+ tx->coalesce_idx = 0;
+ }
+ return 0;
+ }
+
+ if (unlikely(tx->num_desc == MAX_DESC))
+ return -ENOMEM;
+
tx->descp = kmalloc_array(
MAX_DESC,
sizeof(struct sdma_desc),
GFP_ATOMIC);
if (!tx->descp)
return -ENOMEM;
- tx->desc_limit = MAX_DESC;
+
+ /* reserve last descriptor for coalescing */
+ tx->desc_limit = MAX_DESC - 1;
/* copy ones already built */
for (i = 0; i < tx->num_desc; i++)
tx->descp[i] = tx->descs[i];
return 0;
}
+/*
+ * ext_coal_sdma_tx_descs() - extend or coalesce sdma tx descriptors
+ *
+ * This is called once the initial nominal allocation of descriptors
+ * in the sdma_txreq is exhausted.
+ *
+ * This function calls _extend_sdma_tx_descs to extend or allocate
+ * coalesce buffer. If there is a allocated coalesce buffer, it will
+ * copy the input packet data into the coalesce buffer. It also adds
+ * coalesce buffer descriptor once whe whole packet is received.
+ *
+ * Return:
+ * <0 - error
+ * 0 - coalescing, don't populate descriptor
+ * 1 - continue with populating descriptor
+ */
+int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
+ int type, void *kvaddr, struct page *page,
+ unsigned long offset, u16 len)
+{
+ int pad_len, rval;
+ dma_addr_t addr;
+
+ rval = _extend_sdma_tx_descs(dd, tx);
+ if (rval) {
+ sdma_txclean(dd, tx);
+ return rval;
+ }
+
+ /* If coalesce buffer is allocated, copy data into it */
+ if (tx->coalesce_buf) {
+ if (type == SDMA_MAP_NONE) {
+ sdma_txclean(dd, tx);
+ return -EINVAL;
+ }
+
+ if (type == SDMA_MAP_PAGE) {
+ kvaddr = kmap(page);
+ kvaddr += offset;
+ } else if (WARN_ON(!kvaddr)) {
+ sdma_txclean(dd, tx);
+ return -EINVAL;
+ }
+
+ memcpy(tx->coalesce_buf + tx->coalesce_idx, kvaddr, len);
+ tx->coalesce_idx += len;
+ if (type == SDMA_MAP_PAGE)
+ kunmap(page);
+
+ /* If there is more data, return */
+ if (tx->tlen - tx->coalesce_idx)
+ return 0;
+
+ /* Whole packet is received; add any padding */
+ pad_len = tx->packet_len & (sizeof(u32) - 1);
+ if (pad_len) {
+ pad_len = sizeof(u32) - pad_len;
+ memset(tx->coalesce_buf + tx->coalesce_idx, 0, pad_len);
+ /* padding is taken care of for coalescing case */
+ tx->packet_len += pad_len;
+ tx->tlen += pad_len;
+ }
+
+ /* dma map the coalesce buffer */
+ addr = dma_map_single(&dd->pcidev->dev,
+ tx->coalesce_buf,
+ tx->tlen,
+ DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
+ sdma_txclean(dd, tx);
+ return -ENOSPC;
+ }
+
+ /* Add descriptor for coalesce buffer */
+ tx->desc_limit = MAX_DESC;
+ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx,
+ addr, tx->tlen);
+ }
+
+ return 1;
+}
+
/* Update sdes when the lmc changes */
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid)
{
@@ -2752,13 +2860,15 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx)
{
int rval = 0;
+ tx->num_desc++;
if ((unlikely(tx->num_desc == tx->desc_limit))) {
rval = _extend_sdma_tx_descs(dd, tx);
- if (rval)
+ if (rval) {
+ sdma_txclean(dd, tx);
return rval;
+ }
}
- /* finish the one just added */
- tx->num_desc++;
+ /* finish the one just added */
make_tx_sdma_desc(
tx,
SDMA_MAP_NONE,
diff --git a/drivers/staging/rdma/hfi1/sdma.h b/drivers/staging/rdma/hfi1/sdma.h
index 496086903891..52a7d04067e0 100644
--- a/drivers/staging/rdma/hfi1/sdma.h
+++ b/drivers/staging/rdma/hfi1/sdma.h
@@ -352,6 +352,8 @@ struct sdma_txreq {
/* private: */
void *coalesce_buf;
/* private: */
+ u16 coalesce_idx;
+ /* private: */
struct iowait *wait;
/* private: */
callback_t complete;
@@ -735,7 +737,9 @@ static inline void make_tx_sdma_desc(
}
/* helper to extend txreq */
-int _extend_sdma_tx_descs(struct hfi1_devdata *, struct sdma_txreq *);
+int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
+ int type, void *kvaddr, struct page *page,
+ unsigned long offset, u16 len);
int _pad_sdma_tx_descs(struct hfi1_devdata *, struct sdma_txreq *);
void sdma_txclean(struct hfi1_devdata *, struct sdma_txreq *);
@@ -762,11 +766,6 @@ static inline int _sdma_txadd_daddr(
{
int rval = 0;
- if ((unlikely(tx->num_desc == tx->desc_limit))) {
- rval = _extend_sdma_tx_descs(dd, tx);
- if (rval)
- return rval;
- }
make_tx_sdma_desc(
tx,
type,
@@ -798,9 +797,7 @@ static inline int _sdma_txadd_daddr(
*
* Return:
* 0 - success, -ENOSPC - mapping fail, -ENOMEM - couldn't
- * extend descriptor array or couldn't allocate coalesce
- * buffer.
- *
+ * extend/coalesce descriptor array
*/
static inline int sdma_txadd_page(
struct hfi1_devdata *dd,
@@ -809,17 +806,28 @@ static inline int sdma_txadd_page(
unsigned long offset,
u16 len)
{
- dma_addr_t addr =
- dma_map_page(
- &dd->pcidev->dev,
- page,
- offset,
- len,
- DMA_TO_DEVICE);
+ dma_addr_t addr;
+ int rval;
+
+ if ((unlikely(tx->num_desc == tx->desc_limit))) {
+ rval = ext_coal_sdma_tx_descs(dd, tx, SDMA_MAP_PAGE,
+ NULL, page, offset, len);
+ if (rval <= 0)
+ return rval;
+ }
+
+ addr = dma_map_page(
+ &dd->pcidev->dev,
+ page,
+ offset,
+ len,
+ DMA_TO_DEVICE);
+
if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
sdma_txclean(dd, tx);
return -ENOSPC;
}
+
return _sdma_txadd_daddr(
dd, SDMA_MAP_PAGE, tx, addr, len);
}
@@ -846,6 +854,15 @@ static inline int sdma_txadd_daddr(
dma_addr_t addr,
u16 len)
{
+ int rval;
+
+ if ((unlikely(tx->num_desc == tx->desc_limit))) {
+ rval = ext_coal_sdma_tx_descs(dd, tx, SDMA_MAP_NONE,
+ NULL, NULL, 0, 0);
+ if (rval <= 0)
+ return rval;
+ }
+
return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len);
}
@@ -862,7 +879,7 @@ static inline int sdma_txadd_daddr(
* The mapping/unmapping of the kvaddr and len is automatically handled.
*
* Return:
- * 0 - success, -ENOSPC - mapping fail, -ENOMEM - couldn't extend
+ * 0 - success, -ENOSPC - mapping fail, -ENOMEM - couldn't extend/coalesce
* descriptor array
*/
static inline int sdma_txadd_kvaddr(
@@ -871,16 +888,27 @@ static inline int sdma_txadd_kvaddr(
void *kvaddr,
u16 len)
{
- dma_addr_t addr =
- dma_map_single(
- &dd->pcidev->dev,
- kvaddr,
- len,
- DMA_TO_DEVICE);
+ dma_addr_t addr;
+ int rval;
+
+ if ((unlikely(tx->num_desc == tx->desc_limit))) {
+ rval = ext_coal_sdma_tx_descs(dd, tx, SDMA_MAP_SINGLE,
+ kvaddr, 0, 0, len);
+ if (rval <= 0)
+ return rval;
+ }
+
+ addr = dma_map_single(
+ &dd->pcidev->dev,
+ kvaddr,
+ len,
+ DMA_TO_DEVICE);
+
if (unlikely(dma_mapping_error(&dd->pcidev->dev, addr))) {
sdma_txclean(dd, tx);
return -ENOSPC;
}
+
return _sdma_txadd_daddr(
dd, SDMA_MAP_SINGLE, tx, addr, len);
}
--
1.8.2
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-10-20 2:11 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-20 2:11 [PATCH v2 00/22] staging/rdma/hfi1: Fix bugs and performance issues ira.weiny-ral2JQCrhuEAvxtiuMwx3w
[not found] ` <1445307097-8244-1-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-10-20 2:11 ` [PATCH v2 01/22] staging/rdma/hfi1: Fix regression in send performance ira.weiny-ral2JQCrhuEAvxtiuMwx3w
[not found] ` <1445307097-8244-2-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-10-21 13:18 ` Dan Carpenter
2015-10-26 2:10 ` ira.weiny
2015-10-20 2:11 ` [PATCH v2 02/22] staging/rdma/hfi1: Fix code to reset ASIC CSRs on FLR ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 03/22] staging/rdma/hfi1: Extend the offline timeout ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 04/22] staging/rdma/hfi1: Prevent host software lock up ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 05/22] staging/rdma/hfi1: Remove QSFP_ENABLED from HFI capability mask ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` ira.weiny-ral2JQCrhuEAvxtiuMwx3w [this message]
2015-10-20 2:11 ` [PATCH v2 07/22] staging/rdma/hfi1: Fix sparse error in sdma.h file ira.weiny-ral2JQCrhuEAvxtiuMwx3w
[not found] ` <1445307097-8244-8-git-send-email-ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-10-21 14:12 ` Dan Carpenter
2015-10-21 16:29 ` Weiny, Ira
2015-10-22 10:01 ` Dan Carpenter
2015-10-25 1:59 ` gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
2015-10-20 2:11 ` [PATCH v2 08/22] staging/rdma/hfi1: close shared context security hole ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 09/22] staging/rdma/hfi1: Reset firmware instead of reloading Sbus ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 10/22] staging/rdma/hfi1: Add a schedule in send thread ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 11/22] staging/rdma/hfi1: Fix port bounce issues with 0.22 DC firmware ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 12/22] staging/rdma/hfi1: Prevent silent data corruption with user SDMA ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 13/22] staging/rdma/hfi1: Macro code clean up ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 14/22] staging/rdma/hfi1: Implement Expected Receive TID caching ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-22 10:41 ` Dan Carpenter
2015-10-22 23:18 ` ira.weiny
[not found] ` <20151022231819.GB4019-W4f6Xiosr+yv7QzWx2u06xL4W9x8LtSr@public.gmane.org>
2015-10-23 3:53 ` Dan Carpenter
2015-10-20 2:11 ` [PATCH v2 15/22] staging/rdma/hfi1: Allow tuning of SDMA interrupt rate ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-22 10:54 ` Dan Carpenter
2015-10-22 22:27 ` ira.weiny
2015-10-20 2:11 ` [PATCH v2 16/22] staging/rdma/hfi1: Add irqsaves in the packet processing path ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 17/22] staging/rdma/hfi1: Thread the receive interrupt ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 18/22] staging/rdma/hfi: modify workqueue for parallelism ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 19/22] staging/rdma/hfi1: Load SBus firmware once per ASIC ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 20/22] staging/rdma/hfi1: Add unit # to verbs txreq cache name ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 21/22] staging/rdma/hfi1: add additional rc traces ira.weiny-ral2JQCrhuEAvxtiuMwx3w
2015-10-20 2:11 ` [PATCH v2 22/22] staging/rdma/hfi1: Update driver version string to 0.9-294 ira.weiny-ral2JQCrhuEAvxtiuMwx3w
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=1445307097-8244-7-git-send-email-ira.weiny@intel.com \
--to=ira.weiny-ral2jqcrhueavxtiumwx3w@public.gmane.org \
--cc=dennis.dalessandro-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b@public.gmane.org \
--cc=dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
--cc=linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mike.marciniszyn-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=niranjana.vishwanathapura-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
/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.