From 7ac839837c1c6cd1ff629c7898349db8cc55891d Mon Sep 17 00:00:00 2001 From: Amir Shehata Date: Wed, 5 Feb 2020 17:46:03 -0800 Subject: [PATCH] LU-14798 lnet: RMDA infrastructure updates Add infrastructure to force RDMA for payloads < 4K. Add infrastructure to extract the first page in a payload. Useful for determining the type of the payload to be transmitted. Signed-off-by: Amir Shehata Change-Id: Id7dc26c83f00dadd26feca94fc4d8233872650d3 Lustre-change: https://review.whamcloud.com/37453 Reviewed-by: Andreas Dilger Reviewed-by: Wang Shilong Whamcloud-bug-id: EX-773 Reviewed-on: https://review.whamcloud.com/44109 Tested-by: jenkins Reviewed-by: Wang Shilong Tested-by: Maloo --- lnet/include/lnet/lib-lnet.h | 1 + lnet/include/lnet/lib-types.h | 2 ++ lnet/klnds/o2iblnd/o2iblnd_cb.c | 4 ++-- lnet/lnet/lib-md.c | 29 ++++++++++++++++++++++------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h index 358cb63..b419f9e 100644 --- a/lnet/include/lnet/lib-lnet.h +++ b/lnet/include/lnet/lib-lnet.h @@ -784,6 +784,7 @@ void lnet_me_unlink(struct lnet_me *me); void lnet_md_unlink(struct lnet_libmd *md); void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_event *ev); struct page *lnet_kvaddr_to_page(unsigned long vaddr); +struct page *lnet_get_first_page(struct lnet_libmd *md, unsigned int offset); int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset); unsigned int lnet_get_lnd_timeout(void); diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index d671fb04..b8e2a2e 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -125,6 +125,8 @@ struct lnet_msg { enum lnet_msg_hstatus msg_health_status; /* This is a recovery message */ bool msg_recovery; + /* force an RDMA even if the message size is < 4K */ + bool msg_rdma_force; /* the number of times a transmission has been retried */ int msg_retry_count; /* flag to indicate that we do not want to resend this message */ diff --git a/lnet/klnds/o2iblnd/o2iblnd_cb.c b/lnet/klnds/o2iblnd/o2iblnd_cb.c index 9fd0baa..b96e0e8 100644 --- a/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1653,7 +1653,7 @@ kiblnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg) /* is the REPLY message too small for RDMA? */ nob = offsetof(struct kib_msg, ibm_u.immediate.ibim_payload[lntmsg->msg_md->md_length]); - if (nob <= IBLND_MSG_SIZE) + if (nob <= IBLND_MSG_SIZE && !lntmsg->msg_rdma_force) break; /* send IMMEDIATE */ tx = kiblnd_get_idle_tx(ni, target.nid); @@ -1700,7 +1700,7 @@ kiblnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg) case LNET_MSG_PUT: /* Is the payload small enough not to need RDMA? */ nob = offsetof(struct kib_msg, ibm_u.immediate.ibim_payload[payload_nob]); - if (nob <= IBLND_MSG_SIZE) + if (nob <= IBLND_MSG_SIZE && !lntmsg->msg_rdma_force) break; /* send IMMEDIATE */ tx = kiblnd_get_idle_tx(ni, target.nid); diff --git a/lnet/lnet/lib-md.c b/lnet/lnet/lib-md.c index 550b233..68da79e 100644 --- a/lnet/lnet/lib-md.c +++ b/lnet/lnet/lib-md.c @@ -104,10 +104,9 @@ lnet_kvaddr_to_page(unsigned long vaddr) } EXPORT_SYMBOL(lnet_kvaddr_to_page); -int -lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) +struct page * +lnet_get_first_page(struct lnet_libmd *md, unsigned int offset) { - int cpt = CFS_CPT_ANY; unsigned int niov; struct bio_vec *kiov; @@ -120,7 +119,7 @@ lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) md = lnet_handle2md(&md->md_bulk_handle); if (!md || md->md_niov == 0) - return CFS_CPT_ANY; + return NULL; kiov = md->md_kiov; niov = md->md_niov; @@ -131,12 +130,28 @@ lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) kiov++; if (niov == 0) { CERROR("offset %d goes beyond kiov\n", offset); - goto out; + return NULL; } } - cpt = cfs_cpt_of_node(lnet_cpt_table(), - page_to_nid(kiov->bv_page)); + return kiov->bv_page; +} + +int +lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) +{ + struct page *page; + int cpt = CFS_CPT_ANY; + + page = lnet_get_first_page(md, offset); + if (!page) { + CDEBUG(D_NET, "Couldn't resolve first page of md %p with offset %u\n", + md, offset); + goto out; + } + + cpt = cfs_cpt_of_node(lnet_cpt_table(), page_to_nid(page)); + out: return cpt; } -- 1.8.3.1