From f710782156ec21a8a69d7f12a9e7de1bde02c22b Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Wed, 6 Jan 2021 16:19:28 -0800 Subject: [PATCH] LU-13783 o2iblnd: make FMR-pool support optional. Linux 5.8 removes the FMR-pool API. This patch makes all use for this API optional, selected only if the support exists in the kernel. Lustre-commit: 14b20ca66b2b6c5a735d39b753ec77fa6a574a6b Lustre-change: https://review.whamcloud.com/40287 Signed-off-by: Mr NeilBrown Change-Id: I4c40f3a766f5b46ae4f26d7d3ecf8434a6e5a0cb Reviewed-on: https://review.whamcloud.com/41152 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lnet/autoconf/lustre-lnet.m4 | 17 ++++++++++++---- lnet/klnds/o2iblnd/o2iblnd.c | 44 ++++++++++++++++++++++++++++++----------- lnet/klnds/o2iblnd/o2iblnd.h | 12 ++++++++++- lnet/klnds/o2iblnd/o2iblnd_cb.c | 23 +++++++++++++++++---- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/lnet/autoconf/lustre-lnet.m4 b/lnet/autoconf/lustre-lnet.m4 index b30250e..9717cec 100644 --- a/lnet/autoconf/lustre-lnet.m4 +++ b/lnet/autoconf/lustre-lnet.m4 @@ -157,8 +157,7 @@ AS_IF([test $ENABLEO2IB = "no"], [ for O2IBPATH in $O2IBPATHS; do AS_IF([test \( -f ${O2IBPATH}/include/rdma/rdma_cm.h -a \ -f ${O2IBPATH}/include/rdma/ib_cm.h -a \ - -f ${O2IBPATH}/include/rdma/ib_verbs.h -a \ - -f ${O2IBPATH}/include/rdma/ib_fmr_pool.h \)], [ + -f ${O2IBPATH}/include/rdma/ib_verbs.h \)], [ o2ib_found=true break ]) @@ -235,13 +234,11 @@ AS_IF([test $ENABLEO2IB = "no"], [ #include #include #include - #include ],[ struct rdma_cm_id *cm_idi __attribute__ ((unused)); struct rdma_conn_param conn_param __attribute__ ((unused)); struct ib_device_attr device_attr __attribute__ ((unused)); struct ib_qp_attr qp_attr __attribute__ ((unused)); - struct ib_pool_fmr pool_fmr __attribute__ ((unused)); enum ib_cm_rej_reason rej_reason __attribute__ ((unused)); rdma_destroy_id(NULL); ],[ @@ -593,6 +590,18 @@ AS_IF([test $ENABLEO2IB != "no"], [ [rdma_reject has 4 arguments]) ]) + # The FMR pool API was removed in Linux 5.8, + # commit 4e373d5417ecbb4f438a8500f0379a2fc29c2643 + LB_CHECK_COMPILE([if FMR pools API available], + ib_fmr, [ + #include + ],[ + struct ib_fmr fmr = {}; + ],[ + AC_DEFINE(HAVE_FMR_POOL_API, 1, + [FMR pool API is available]) + ]) + EXTRA_CHECK_INCLUDE="" ]) # ENABLEO2IB != "no" ]) # LN_CONFIG_O2IB diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c index efcb58b..b677d57 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.c +++ b/lnet/klnds/o2iblnd/o2iblnd.c @@ -1469,9 +1469,12 @@ kiblnd_destroy_fmr_pool(struct kib_fmr_pool *fpo) { LASSERT(fpo->fpo_map_count == 0); +#ifdef HAVE_FMR_POOL_API if (fpo->fpo_is_fmr && fpo->fmr.fpo_fmr_pool) { ib_destroy_fmr_pool(fpo->fmr.fpo_fmr_pool); - } else { + } else +#endif /* HAVE_FMR_POOL_API */ + { struct kib_fast_reg_descriptor *frd, *tmp; int i = 0; @@ -1525,6 +1528,7 @@ kiblnd_fmr_flush_trigger(struct lnet_ioctl_config_o2iblnd_tunables *tunables, return max(IBLND_FMR_POOL_FLUSH, size); } +#ifdef HAVE_FMR_POOL_API static int kiblnd_alloc_fmr_pool(struct kib_fmr_poolset *fps, struct kib_fmr_pool *fpo) { @@ -1553,6 +1557,7 @@ static int kiblnd_alloc_fmr_pool(struct kib_fmr_poolset *fps, return rc; } +#endif /* HAVE_FMR_POOL_API */ static int kiblnd_alloc_freg_pool(struct kib_fmr_poolset *fps, struct kib_fmr_pool *fpo, @@ -1561,7 +1566,9 @@ static int kiblnd_alloc_freg_pool(struct kib_fmr_poolset *fps, struct kib_fast_reg_descriptor *frd, *tmp; int i, rc; +#ifdef HAVE_FMR_POOL_API fpo->fpo_is_fmr = false; +#endif INIT_LIST_HEAD(&fpo->fast_reg.fpo_pool_list); fpo->fast_reg.fpo_pool_size = 0; @@ -1668,9 +1675,11 @@ static int kiblnd_create_fmr_pool(struct kib_fmr_poolset *fps, fpo->fpo_hdev = kiblnd_current_hdev(dev); +#ifdef HAVE_FMR_POOL_API if (dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED) rc = kiblnd_alloc_fmr_pool(fps, fpo); else +#endif /* HAVE_FMR_POOL_API */ rc = kiblnd_alloc_freg_pool(fps, fpo, dev->ibd_dev_caps); if (rc) goto out_fpo; @@ -1758,6 +1767,7 @@ kiblnd_fmr_pool_is_idle(struct kib_fmr_pool *fpo, time64_t now) return now >= fpo->fpo_deadline; } +#if defined(HAVE_FMR_POOL_API) || !defined(HAVE_IB_MAP_MR_SG) static int kiblnd_map_tx_pages(struct kib_tx *tx, struct kib_rdma_desc *rd) { @@ -1779,6 +1789,7 @@ kiblnd_map_tx_pages(struct kib_tx *tx, struct kib_rdma_desc *rd) return npages; } +#endif void kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status) @@ -1788,12 +1799,13 @@ kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status) struct kib_fmr_poolset *fps; time64_t now = ktime_get_seconds(); struct kib_fmr_pool *tmp; - int rc; if (!fpo) return; fps = fpo->fpo_owner; + +#ifdef HAVE_FMR_POOL_API if (fpo->fpo_is_fmr) { if (fmr->fmr_pfmr) { ib_fmr_pool_unmap(fmr->fmr_pfmr); @@ -1801,10 +1813,12 @@ kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status) } if (status) { - rc = ib_flush_fmr_pool(fpo->fmr.fpo_fmr_pool); + int rc = ib_flush_fmr_pool(fpo->fmr.fpo_fmr_pool); LASSERT(!rc); } - } else { + } else +#endif /* HAVE_FMR_POOL_API */ + { struct kib_fast_reg_descriptor *frd = fmr->fmr_frd; if (frd) { @@ -1841,11 +1855,13 @@ int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, struct kib_fmr *fmr) { struct kib_fmr_pool *fpo; - __u64 *pages = tx->tx_pages; __u64 version; bool is_rx = (rd != tx->tx_rd); +#ifdef HAVE_FMR_POOL_API + __u64 *pages = tx->tx_pages; bool tx_pages_mapped = 0; int npages = 0; +#endif int rc; again: @@ -1855,6 +1871,8 @@ again: fpo->fpo_deadline = ktime_get_seconds() + IBLND_POOL_DEADLINE; fpo->fpo_map_count++; +#ifdef HAVE_FMR_POOL_API + fmr->fmr_pfmr = NULL; if (fpo->fpo_is_fmr) { struct ib_pool_fmr *pfmr; @@ -1876,7 +1894,9 @@ again: return 0; } rc = PTR_ERR(pfmr); - } else { + } else +#endif /* HAVE_FMR_POOL_API */ + { if (!list_empty(&fpo->fast_reg.fpo_pool_list)) { struct kib_fast_reg_descriptor *frd; #ifdef HAVE_IB_MAP_MR_SG @@ -1922,7 +1942,7 @@ again: #else n = ib_map_mr_sg(mr, tx->tx_frags, tx->tx_nfrags, PAGE_SIZE); -#endif +#endif /* HAVE_IB_MAP_MR_SG_5ARGS */ if (unlikely(n != tx->tx_nfrags)) { CERROR("Failed to map mr %d/%d " "elements\n", n, tx->tx_nfrags); @@ -1940,7 +1960,7 @@ again: wr->key = is_rx ? mr->rkey : mr->lkey; wr->access = (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE); -#else +#else /* HAVE_IB_MAP_MR_SG */ if (!tx_pages_mapped) { npages = kiblnd_map_tx_pages(tx, rd); tx_pages_mapped = 1; @@ -1967,11 +1987,10 @@ again: wr->wr.wr.fast_reg.access_flags = (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE); -#endif +#endif /* HAVE_IB_MAP_MR_SG */ fmr->fmr_key = is_rx ? mr->rkey : mr->lkey; fmr->fmr_frd = frd; - fmr->fmr_pfmr = NULL; fmr->fmr_pool = fpo; return 0; } @@ -2567,6 +2586,7 @@ kiblnd_hdev_get_attr(struct kib_hca_dev *hdev) hdev->ibh_max_qp_wr = dev_attr->max_qp_wr; /* Setup device Memory Registration capabilities */ +#ifdef HAVE_FMR_POOL_API #ifdef HAVE_IB_DEVICE_OPS if (hdev->ibh_ibdev->ops.alloc_fmr && hdev->ibh_ibdev->ops.dealloc_fmr && @@ -2580,7 +2600,9 @@ kiblnd_hdev_get_attr(struct kib_hca_dev *hdev) #endif LCONSOLE_INFO("Using FMR for registration\n"); hdev->ibh_dev->ibd_dev_caps |= IBLND_DEV_CAPS_FMR_ENABLED; - } else if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { + } else +#endif /* HAVE_FMR_POOL_API */ + if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { LCONSOLE_INFO("Using FastReg for registration\n"); hdev->ibh_dev->ibd_dev_caps |= IBLND_DEV_CAPS_FASTREG_ENABLED; #ifndef HAVE_IB_ALLOC_FAST_REG_MR diff --git a/lnet/klnds/o2iblnd/o2iblnd.h b/lnet/klnds/o2iblnd/o2iblnd.h index 5a8b966..1a392fe 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.h +++ b/lnet/klnds/o2iblnd/o2iblnd.h @@ -71,7 +71,9 @@ #include #include #include +#ifdef HAVE_FMR_POOL_API #include +#endif #define DEBUG_SUBSYSTEM S_LND @@ -172,7 +174,9 @@ struct kib_hca_dev; enum kib_dev_caps { IBLND_DEV_CAPS_FASTREG_ENABLED = BIT(0), IBLND_DEV_CAPS_FASTREG_GAPS_SUPPORT = BIT(1), +#ifdef HAVE_FMR_POOL_API IBLND_DEV_CAPS_FMR_ENABLED = BIT(2), +#endif }; struct kib_dev { @@ -333,24 +337,30 @@ struct kib_fmr_pool { struct list_head fpo_list; /* chain on pool list */ struct kib_hca_dev *fpo_hdev; /* device for this pool */ struct kib_fmr_poolset *fpo_owner; /* owner of this pool */ +#ifdef HAVE_FMR_POOL_API union { struct { struct ib_fmr_pool *fpo_fmr_pool; /* IB FMR pool */ } fmr; +#endif struct { /* For fast registration */ struct list_head fpo_pool_list; int fpo_pool_size; } fast_reg; +#ifdef HAVE_FMR_POOL_API }; + bool fpo_is_fmr; /* True if FMR pools allocated */ +#endif time64_t fpo_deadline; /* deadline of this pool */ int fpo_failed; /* fmr pool is failed */ int fpo_map_count; /* # of mapped FMR */ - bool fpo_is_fmr; /* True if FMR pools allocated */ }; struct kib_fmr { struct kib_fmr_pool *fmr_pool; /* pool of FMR */ +#ifdef HAVE_FMR_POOL_API struct ib_pool_fmr *fmr_pfmr; /* IB pool fmr */ +#endif /* HAVE_FMR_POOL_API */ struct kib_fast_reg_descriptor *fmr_frd; u32 fmr_key; }; diff --git a/lnet/klnds/o2iblnd/o2iblnd_cb.c b/lnet/klnds/o2iblnd/o2iblnd_cb.c index 2432a8e..217f83d 100644 --- a/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -588,6 +588,7 @@ kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, return -EPROTONOSUPPORT; } +#ifdef HAVE_FMR_POOL_API /* * FMR does not support gaps but the tx has gaps then * we should make sure that the number of fragments we'll be sending @@ -606,6 +607,7 @@ kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, return -EFBIG; } } +#endif fps = net->ibn_fmr_ps[cpt]; rc = kiblnd_fmr_pool_map(fps, tx, rd, nob, 0, &tx->tx_fmr); @@ -623,11 +625,17 @@ kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, * for FastReg or FMR with no gaps we can accumulate all * the fragments in one FastReg or FMR fragment. */ - if (((dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED) && !tx->tx_gaps) || + if ( +#ifdef HAVE_FMR_POOL_API + ((dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED) + && !tx->tx_gaps) || +#endif (dev->ibd_dev_caps & IBLND_DEV_CAPS_FASTREG_ENABLED)) { /* FMR requires zero based address */ +#ifdef HAVE_FMR_POOL_API if (dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED) rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; +#endif rd->rd_frags[0].rf_nob = nob; rd->rd_nfrags = 1; } else { @@ -648,7 +656,11 @@ kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, static void kiblnd_unmap_tx(struct kib_tx *tx) { - if (tx->tx_fmr.fmr_pfmr || tx->tx_fmr.fmr_frd) + if ( +#ifdef HAVE_FMR_POOL_API + tx->tx_fmr.fmr_pfmr || +#endif + tx->tx_fmr.fmr_frd) kiblnd_fmr_pool_unmap(&tx->tx_fmr, tx->tx_status); if (tx->tx_nfrags != 0) { @@ -675,8 +687,11 @@ kiblnd_find_rd_dma_mr(struct lnet_ni *ni, struct kib_rdma_desc *rd) * dead in the water and fail the operation. */ if (tunables->lnd_map_on_demand && - (net->ibn_dev->ibd_dev_caps & IBLND_DEV_CAPS_FASTREG_ENABLED || - net->ibn_dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED)) + (net->ibn_dev->ibd_dev_caps & IBLND_DEV_CAPS_FASTREG_ENABLED +#ifdef HAVE_FMR_POOL_API + || net->ibn_dev->ibd_dev_caps & IBLND_DEV_CAPS_FMR_ENABLED +#endif + )) return NULL; /* -- 1.8.3.1