Whamcloud - gitweb
LU-11064 lnd: determine gaps correctly 86/32586/4
authorAmir Shehata <amir.shehata@intel.com>
Wed, 30 May 2018 20:22:11 +0000 (13:22 -0700)
committerOleg Drokin <green@whamcloud.com>
Wed, 18 Jul 2018 05:59:04 +0000 (05:59 +0000)
We're allowed to start at a non-aligned page offset in the first
fragment and end at a non-aligned page offset in the last fragment.

When checking the iovec exclude both of the first and last fragments
from the tx_gaps check.

Test-Parameters: trivial
Signed-off-by: Amir Shehata <amir.shehata@intel.com>
Change-Id: I8a9231db7db404a5d5a6294ff263c1bd2ac28e6c
Reviewed-on: https://review.whamcloud.com/32586
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Doug Oucharek <dougso@me.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/klnds/o2iblnd/o2iblnd_cb.c

index cd22264..752e352 100644 (file)
@@ -724,6 +724,7 @@ kiblnd_setup_rd_iov(struct lnet_ni *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
         unsigned long       vaddr;
         int                 fragnob;
         int                 page_offset;
         unsigned long       vaddr;
         int                 fragnob;
         int                 page_offset;
+       unsigned int        max_niov;
 
         LASSERT (nob > 0);
         LASSERT (niov > 0);
 
         LASSERT (nob > 0);
         LASSERT (niov > 0);
@@ -736,6 +737,8 @@ kiblnd_setup_rd_iov(struct lnet_ni *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
                 LASSERT (niov > 0);
         }
 
                 LASSERT (niov > 0);
         }
 
+       max_niov = niov;
+
        sg = tx->tx_frags;
        do {
                LASSERT(niov > 0);
        sg = tx->tx_frags;
        do {
                LASSERT(niov > 0);
@@ -751,10 +754,17 @@ kiblnd_setup_rd_iov(struct lnet_ni *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
                fragnob = min((int)(iov->iov_len - offset), nob);
                fragnob = min(fragnob, (int)PAGE_SIZE - page_offset);
 
                fragnob = min((int)(iov->iov_len - offset), nob);
                fragnob = min(fragnob, (int)PAGE_SIZE - page_offset);
 
-               if ((fragnob < (int)PAGE_SIZE - page_offset) && (niov > 1)) {
+               /*
+                * We're allowed to start at a non-aligned page offset in
+                * the first fragment and end at a non-aligned page offset
+                * in the last fragment.
+                */
+               if ((fragnob < (int)PAGE_SIZE - page_offset) &&
+                   (niov < max_niov) && nob > fragnob) {
                        CDEBUG(D_NET, "fragnob %d < available page %d: with"
                        CDEBUG(D_NET, "fragnob %d < available page %d: with"
-                                     " remaining %d iovs\n",
-                              fragnob, (int)PAGE_SIZE - page_offset, niov);
+                                     " remaining %d iovs with %d nob left\n",
+                              fragnob, (int)PAGE_SIZE - page_offset, niov,
+                              nob);
                        tx->tx_gaps = true;
                }
 
                        tx->tx_gaps = true;
                }
 
@@ -785,6 +795,7 @@ kiblnd_setup_rd_kiov(struct lnet_ni *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
        kib_net_t          *net = ni->ni_data;
        struct scatterlist *sg;
        int                 fragnob;
        kib_net_t          *net = ni->ni_data;
        struct scatterlist *sg;
        int                 fragnob;
+       int                 max_nkiov;
 
        CDEBUG(D_NET, "niov %d offset %d nob %d\n", nkiov, offset, nob);
 
 
        CDEBUG(D_NET, "niov %d offset %d nob %d\n", nkiov, offset, nob);
 
@@ -799,16 +810,25 @@ kiblnd_setup_rd_kiov(struct lnet_ni *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
                LASSERT(nkiov > 0);
        }
 
                LASSERT(nkiov > 0);
        }
 
+       max_nkiov = nkiov;
+
        sg = tx->tx_frags;
        do {
                LASSERT(nkiov > 0);
 
                fragnob = min((int)(kiov->kiov_len - offset), nob);
 
        sg = tx->tx_frags;
        do {
                LASSERT(nkiov > 0);
 
                fragnob = min((int)(kiov->kiov_len - offset), nob);
 
-               if ((fragnob < (int)(kiov->kiov_len - offset)) && nkiov > 1) {
+               /*
+                * We're allowed to start at a non-aligned page offset in
+                * the first fragment and end at a non-aligned page offset
+                * in the last fragment.
+                */
+               if ((fragnob < (int)(kiov->kiov_len - offset)) &&
+                   nkiov < max_nkiov && nob > fragnob) {
                        CDEBUG(D_NET, "fragnob %d < available page %d: with"
                        CDEBUG(D_NET, "fragnob %d < available page %d: with"
-                                     " remaining %d kiovs\n",
-                              fragnob, (int)(kiov->kiov_len - offset), nkiov);
+                                     " remaining %d kiovs with %d nob left\n",
+                              fragnob, (int)(kiov->kiov_len - offset),
+                              nkiov, nob);
                        tx->tx_gaps = true;
                }
 
                        tx->tx_gaps = true;
                }