common/qat: fix offset greater than first segment
authorTomasz Jozwiak <tomaszx.jozwiak@intel.com>
Thu, 2 Aug 2018 15:09:26 +0000 (17:09 +0200)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Fri, 3 Aug 2018 07:14:24 +0000 (09:14 +0200)
This patch fixes sgl filling to handle offset
greater than first sgl segment

Fixes: 1947bd18580b ("compress/qat: support scatter-gather buffers")

Signed-off-by: Tomasz Jozwiak <tomaszx.jozwiak@intel.com>
Acked-by: Fiona Trahe <fiona.trahe@intel.com>
drivers/common/qat/qat_common.c
drivers/common/qat/qat_common.h
drivers/compress/qat/qat_comp.c
drivers/crypto/qat/qat_sym.c

index bc04c07..4753866 100644 (file)
@@ -7,79 +7,66 @@
 #include "qat_logs.h"
 
 int
-qat_sgl_fill_array(struct rte_mbuf *buf, uint64_t buf_start,
+qat_sgl_fill_array(struct rte_mbuf *buf, int64_t offset,
                void *list_in, uint32_t data_len,
                const uint16_t max_segs)
 {
-       int nr = 1;
+       int res = -EINVAL;
+       uint32_t buf_len, nr;
        struct qat_sgl *list = (struct qat_sgl *)list_in;
-       /* buf_start allows the first buffer to start at an address before or
-        * after the mbuf data start. It's used to either optimally align the
-        * dma to 64 or to start dma from an offset.
-        */
-       uint32_t buf_len;
-       uint32_t first_buf_len = rte_pktmbuf_data_len(buf) +
-                       (rte_pktmbuf_mtophys(buf) - buf_start);
 #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
        uint8_t *virt_addr[max_segs];
-       virt_addr[0] = rte_pktmbuf_mtod(buf, uint8_t*) +
-                       (rte_pktmbuf_mtophys(buf) - buf_start);
 #endif
 
-       list->buffers[0].addr = buf_start;
-       list->buffers[0].resrvd = 0;
-       list->buffers[0].len = first_buf_len;
-
-       if (data_len <= first_buf_len) {
-               list->num_bufs = nr;
-               list->buffers[0].len = data_len;
-               goto sgl_end;
-       }
-
-       buf = buf->next;
-       buf_len = first_buf_len;
-       while (buf) {
-               if (unlikely(nr == max_segs)) {
-                       QAT_DP_LOG(ERR, "Exceeded max segments in QAT SGL (%u)",
-                                       max_segs);
-                       return -EINVAL;
+       for (nr = buf_len = 0; buf &&  nr < max_segs; buf = buf->next)  {
+               if (offset >= rte_pktmbuf_data_len(buf)) {
+                       offset -= rte_pktmbuf_data_len(buf);
+                       continue;
                }
 
-               list->buffers[nr].len = rte_pktmbuf_data_len(buf);
+               list->buffers[nr].len = rte_pktmbuf_data_len(buf) - offset;
                list->buffers[nr].resrvd = 0;
-               list->buffers[nr].addr = rte_pktmbuf_mtophys(buf);
+               list->buffers[nr].addr = rte_pktmbuf_iova_offset(buf, offset);
+
 #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
-               virt_addr[nr] = rte_pktmbuf_mtod(buf, uint8_t*);
+               virt_addr[nr] = rte_pktmbuf_mtod_offset(buf, uint8_t*, offset);
 #endif
+               offset = 0;
                buf_len += list->buffers[nr].len;
-               buf = buf->next;
 
                if (buf_len >= data_len) {
-                       list->buffers[nr].len -=
-                               buf_len - data_len;
-                       buf = NULL;
+                       list->buffers[nr].len -= buf_len - data_len;
+                       res = 0;
+                       break;
                }
                ++nr;
        }
-       list->num_bufs = nr;
 
-sgl_end:
+       if (unlikely(res != 0)) {
+               if (nr == max_segs) {
+                       QAT_DP_LOG(ERR, "Exceeded max segments in QAT SGL (%u)",
+                                  max_segs);
+               } else {
+                       QAT_DP_LOG(ERR, "Mbuf chain is too short");
+               }
+       } else {
+
+               list->num_bufs = ++nr;
 #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
-       {
-               uint16_t i;
                QAT_DP_LOG(INFO, "SGL with %d buffers:", list->num_bufs);
-               for (i = 0; i < list->num_bufs; i++) {
+               for (nr = 0; nr < list->num_bufs; nr++) {
                        QAT_DP_LOG(INFO,
                                "QAT SGL buf %d, len = %d, iova = 0x%012"PRIx64,
-                               i, list->buffers[i].len,
-                               list->buffers[i].addr);
+                                nr, list->buffers[nr].len,
+                                list->buffers[nr].addr);
                        QAT_DP_HEXDUMP_LOG(DEBUG, "qat SGL",
-                                       virt_addr[i], list->buffers[i].len);
+                                          virt_addr[nr],
+                                          list->buffers[nr].len);
                }
-       }
 #endif
+       }
 
-       return 0;
+       return res;
 }
 
 void qat_stats_get(struct qat_pci_device *dev,
index b26aa26..d4bef53 100644 (file)
@@ -65,7 +65,7 @@ struct qat_common_stats {
 struct qat_pci_device;
 
 int
-qat_sgl_fill_array(struct rte_mbuf *buf, uint64_t buf_start,
+qat_sgl_fill_array(struct rte_mbuf *buf, int64_t offset,
                void *list_in, uint32_t data_len,
                const uint16_t max_segs);
 void
index 522edfc..38c8a5b 100644 (file)
@@ -53,25 +53,24 @@ qat_comp_build_request(void *in_op, uint8_t *out_msg,
 
                ICP_QAT_FW_COMN_PTR_TYPE_SET(comp_req->comn_hdr.comn_req_flags,
                                QAT_COMN_PTR_TYPE_SGL);
+
                ret = qat_sgl_fill_array(op->m_src,
-                               rte_pktmbuf_mtophys_offset(op->m_src,
-                                                       op->src.offset),
+                               op->src.offset,
                                &cookie->qat_sgl_src,
                                op->src.length,
                                RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS);
                if (ret) {
-                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
+                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill source sgl array");
                        return ret;
                }
 
                ret = qat_sgl_fill_array(op->m_dst,
-                               rte_pktmbuf_mtophys_offset(op->m_dst,
-                                                       op->dst.offset),
+                               op->dst.offset,
                                &cookie->qat_sgl_dst,
                                comp_req->comp_pars.out_buffer_sz,
                                RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS);
                if (ret) {
-                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
+                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill dest. sgl array");
                        return ret;
                }
 
index 8273968..10cdf2e 100644 (file)
@@ -494,10 +494,11 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg,
 
                ICP_QAT_FW_COMN_PTR_TYPE_SET(qat_req->comn_hdr.comn_req_flags,
                                QAT_COMN_PTR_TYPE_SGL);
-               ret = qat_sgl_fill_array(op->sym->m_src, src_buf_start,
-                                       &cookie->qat_sgl_src,
-                                       qat_req->comn_mid.src_length,
-                                       QAT_SYM_SGL_MAX_NUMBER);
+               ret = qat_sgl_fill_array(op->sym->m_src,
+                  (int64_t)(src_buf_start - rte_pktmbuf_iova(op->sym->m_src)),
+                  &cookie->qat_sgl_src,
+                  qat_req->comn_mid.src_length,
+                  QAT_SYM_SGL_MAX_NUMBER);
 
                if (unlikely(ret)) {
                        QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
@@ -510,10 +511,11 @@ qat_sym_build_request(void *in_op, uint8_t *out_msg,
                                cookie->qat_sgl_src_phys_addr;
                else {
                        ret = qat_sgl_fill_array(op->sym->m_dst,
-                                                dst_buf_start,
-                                                &cookie->qat_sgl_dst,
-                                                qat_req->comn_mid.dst_length,
-                                                QAT_SYM_SGL_MAX_NUMBER);
+                               (int64_t)(dst_buf_start -
+                                         rte_pktmbuf_iova(op->sym->m_dst)),
+                                &cookie->qat_sgl_dst,
+                                qat_req->comn_mid.dst_length,
+                                QAT_SYM_SGL_MAX_NUMBER);
 
                        if (unlikely(ret)) {
                                QAT_DP_LOG(ERR, "QAT PMD can't fill sgl array");