From e40ea6fd4494b86d26a9d459f7bf620d816af4e1 Mon Sep 17 00:00:00 2001 From: Amir Shehata Date: Wed, 30 May 2018 13:22:11 -0700 Subject: [PATCH] LU-11064 lnd: determine gaps correctly 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 Change-Id: I8a9231db7db404a5d5a6294ff263c1bd2ac28e6c Reviewed-on: https://review.whamcloud.com/32586 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Doug Oucharek Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lnet/klnds/o2iblnd/o2iblnd_cb.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lnet/klnds/o2iblnd/o2iblnd_cb.c b/lnet/klnds/o2iblnd/o2iblnd_cb.c index cd22264..752e352 100644 --- a/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -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 int max_niov; 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); } + max_niov = niov; + 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); - 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" - " 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; } @@ -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; + int max_nkiov; 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); } + max_nkiov = nkiov; + 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" - " 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; } -- 1.8.3.1