Commit 624b9ac1 authored by Harish Chegondi's avatar Harish Chegondi Committed by Doug Ledford

IB/hfi1: Clean up user_sdma_send_pkts() function

user_sdma_send_pkts() function is unnecessarily long. Clean it up by
moving some of its code into separate functions.
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarHarish Chegondi <harish.chegondi@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 9dc11709
......@@ -847,6 +847,84 @@ static inline u32 get_lrh_len(struct hfi1_pkt_header hdr, u32 len)
return ((sizeof(hdr) - sizeof(hdr.pbc)) + 4 + len);
}
static int user_sdma_txadd_ahg(struct user_sdma_request *req,
struct user_sdma_txreq *tx,
u32 datalen)
{
int ret;
u16 pbclen = le16_to_cpu(req->hdr.pbc[0]);
u32 lrhlen = get_lrh_len(req->hdr, pad_len(datalen));
struct hfi1_user_sdma_pkt_q *pq = req->pq;
/*
* Copy the request header into the tx header
* because the HW needs a cacheline-aligned
* address.
* This copy can be optimized out if the hdr
* member of user_sdma_request were also
* cacheline aligned.
*/
memcpy(&tx->hdr, &req->hdr, sizeof(tx->hdr));
if (PBC2LRH(pbclen) != lrhlen) {
pbclen = (pbclen & 0xf000) | LRH2PBC(lrhlen);
tx->hdr.pbc[0] = cpu_to_le16(pbclen);
}
ret = check_header_template(req, &tx->hdr, lrhlen, datalen);
if (ret)
return ret;
ret = sdma_txinit_ahg(&tx->txreq, SDMA_TXREQ_F_AHG_COPY,
sizeof(tx->hdr) + datalen, req->ahg_idx,
0, NULL, 0, user_sdma_txreq_cb);
if (ret)
return ret;
ret = sdma_txadd_kvaddr(pq->dd, &tx->txreq, &tx->hdr, sizeof(tx->hdr));
if (ret)
sdma_txclean(pq->dd, &tx->txreq);
return ret;
}
static int user_sdma_txadd(struct user_sdma_request *req,
struct user_sdma_txreq *tx,
struct user_sdma_iovec *iovec, u32 datalen,
u32 *queued_ptr, u32 *data_sent_ptr,
u64 *iov_offset_ptr)
{
int ret;
unsigned int pageidx, len;
unsigned long base, offset;
u64 iov_offset = *iov_offset_ptr;
u32 queued = *queued_ptr, data_sent = *data_sent_ptr;
struct hfi1_user_sdma_pkt_q *pq = req->pq;
base = (unsigned long)iovec->iov.iov_base;
offset = offset_in_page(base + iovec->offset + iov_offset);
pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >>
PAGE_SHIFT);
len = offset + req->info.fragsize > PAGE_SIZE ?
PAGE_SIZE - offset : req->info.fragsize;
len = min((datalen - queued), len);
ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx],
offset, len);
if (ret) {
SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret);
return ret;
}
iov_offset += len;
queued += len;
data_sent += len;
if (unlikely(queued < datalen && pageidx == iovec->npages &&
req->iov_idx < req->data_iovs - 1)) {
iovec->offset += iov_offset;
iovec = &req->iovs[++req->iov_idx];
iov_offset = 0;
}
*queued_ptr = queued;
*data_sent_ptr = data_sent;
*iov_offset_ptr = iov_offset;
return ret;
}
static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
{
int ret = 0, count;
......@@ -943,39 +1021,9 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
if (req->ahg_idx >= 0) {
if (!req->seqnum) {
u16 pbclen = le16_to_cpu(req->hdr.pbc[0]);
u32 lrhlen = get_lrh_len(req->hdr,
pad_len(datalen));
/*
* Copy the request header into the tx header
* because the HW needs a cacheline-aligned
* address.
* This copy can be optimized out if the hdr
* member of user_sdma_request were also
* cacheline aligned.
*/
memcpy(&tx->hdr, &req->hdr, sizeof(tx->hdr));
if (PBC2LRH(pbclen) != lrhlen) {
pbclen = (pbclen & 0xf000) |
LRH2PBC(lrhlen);
tx->hdr.pbc[0] = cpu_to_le16(pbclen);
}
ret = check_header_template(req, &tx->hdr,
lrhlen, datalen);
if (ret)
goto free_tx;
ret = sdma_txinit_ahg(&tx->txreq,
SDMA_TXREQ_F_AHG_COPY,
sizeof(tx->hdr) + datalen,
req->ahg_idx, 0, NULL, 0,
user_sdma_txreq_cb);
ret = user_sdma_txadd_ahg(req, tx, datalen);
if (ret)
goto free_tx;
ret = sdma_txadd_kvaddr(pq->dd, &tx->txreq,
&tx->hdr,
sizeof(tx->hdr));
if (ret)
goto free_txreq;
} else {
int changes;
......@@ -1006,35 +1054,10 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
*/
while (queued < datalen &&
(req->sent + data_sent) < req->data_len) {
unsigned long base, offset;
unsigned pageidx, len;
base = (unsigned long)iovec->iov.iov_base;
offset = offset_in_page(base + iovec->offset +
iov_offset);
pageidx = (((iovec->offset + iov_offset +
base) - (base & PAGE_MASK)) >> PAGE_SHIFT);
len = offset + req->info.fragsize > PAGE_SIZE ?
PAGE_SIZE - offset : req->info.fragsize;
len = min((datalen - queued), len);
ret = sdma_txadd_page(pq->dd, &tx->txreq,
iovec->pages[pageidx],
offset, len);
if (ret) {
SDMA_DBG(req, "SDMA txreq add page failed %d\n",
ret);
ret = user_sdma_txadd(req, tx, iovec, datalen,
&queued, &data_sent, &iov_offset);
if (ret)
goto free_txreq;
}
iov_offset += len;
queued += len;
data_sent += len;
if (unlikely(queued < datalen &&
pageidx == iovec->npages &&
req->iov_idx < req->data_iovs - 1)) {
iovec->offset += iov_offset;
iovec = &req->iovs[++req->iov_idx];
iov_offset = 0;
}
}
/*
* The txreq was submitted successfully so we can update
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment