From ab14f3bc852e708100d21770c00235f95841708a Mon Sep 17 00:00:00 2001 From: Chris Horn Date: Wed, 21 Apr 2021 14:22:46 -0500 Subject: [PATCH] LU-14627 lnet: Allow delayed sends The net_delay_add has some code related to delaying sends, but it isn't fully implemented. Modify lnet_post_send_locked() to check whether the message being sent matches a rule and should be delayed. Fix some bugs with how the delay timers were set and checked. HPE-bug-id: LUS-7651 Test-Parameters: trivial Signed-off-by: Chris Horn Change-Id: Icbd9ee81d2ff0162a01a4187807ea2114a42276d Reviewed-on: https://review.whamcloud.com/43416 Reviewed-by: Serguei Smirnov Reviewed-by: James Simmons Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/include/lnet/lib-lnet.h | 1 + lnet/lnet/lib-move.c | 8 +++++++- lnet/lnet/net_fault.c | 30 ++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h index a620aaa..358cb63 100644 --- a/lnet/include/lnet/lib-lnet.h +++ b/lnet/include/lnet/lib-lnet.h @@ -672,6 +672,7 @@ void lnet_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, void lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, int delayed, unsigned int offset, unsigned int mlen, unsigned int rlen); +void lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg); struct lnet_msg *lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *get_msg); diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c index 9420d6a..ed87e97 100644 --- a/lnet/lnet/lib-move.c +++ b/lnet/lnet/lib-move.c @@ -725,7 +725,7 @@ lnet_prep_send(struct lnet_msg *msg, int type, struct lnet_process_id target, msg->msg_hdr.payload_length = cpu_to_le32(len); } -static void +void lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) { void *priv = msg->msg_private; @@ -927,6 +927,12 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) } } + if (unlikely(!list_empty(&the_lnet.ln_delay_rules)) && + lnet_delay_rule_match_locked(&msg->msg_hdr, msg)) { + msg->msg_tx_delayed = 1; + return LNET_CREDIT_WAIT; + } + /* unset the tx_delay flag as we're going to send it now */ msg->msg_tx_delayed = 0; diff --git a/lnet/lnet/net_fault.c b/lnet/lnet/net_fault.c index 8ea4436..cea39da 100644 --- a/lnet/lnet/net_fault.c +++ b/lnet/lnet/net_fault.c @@ -534,8 +534,9 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, lnet_nid_t dst, unsigned int type, unsigned int portal, struct lnet_msg *msg) { - struct lnet_fault_attr *attr = &rule->dl_attr; - bool delay; + struct lnet_fault_attr *attr = &rule->dl_attr; + bool delay; + time64_t now = ktime_get_seconds(); if (!lnet_fault_attr_match(attr, src, LNET_NID_ANY, dst, type, portal)) @@ -544,8 +545,6 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, /* match this rule, check delay rate now */ spin_lock(&rule->dl_lock); if (rule->dl_delay_time != 0) { /* time based delay */ - time64_t now = ktime_get_seconds(); - rule->dl_stat.fs_count++; delay = now >= rule->dl_delay_time; if (delay) { @@ -587,11 +586,11 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, rule->dl_stat.u.delay.ls_delayed++; list_add_tail(&msg->msg_list, &rule->dl_msg_list); - msg->msg_delay_send = ktime_get_seconds() + attr->u.delay.la_latency; + msg->msg_delay_send = now + attr->u.delay.la_latency; if (rule->dl_msg_send == -1) { rule->dl_msg_send = msg->msg_delay_send; mod_timer(&rule->dl_timer, - jiffies + cfs_time_seconds(rule->dl_msg_send)); + jiffies + cfs_time_seconds(attr->u.delay.la_latency)); } spin_unlock(&rule->dl_lock); @@ -637,7 +636,7 @@ delayed_msg_check(struct lnet_delay_rule *rule, bool all, struct lnet_msg *tmp; time64_t now = ktime_get_seconds(); - if (!all && cfs_time_seconds(rule->dl_msg_send) > now) + if (!all && rule->dl_msg_send > now) return; spin_lock(&rule->dl_lock); @@ -660,7 +659,8 @@ delayed_msg_check(struct lnet_delay_rule *rule, bool all, struct lnet_msg, msg_list); rule->dl_msg_send = msg->msg_delay_send; mod_timer(&rule->dl_timer, - jiffies + cfs_time_seconds(rule->dl_msg_send)); + jiffies + + cfs_time_seconds(msg->msg_delay_send - now)); } spin_unlock(&rule->dl_lock); } @@ -676,6 +676,20 @@ delayed_msg_process(struct list_head *msg_list, bool drop) int rc; msg = list_entry(msg_list->next, struct lnet_msg, msg_list); + + if (msg->msg_sending) { + /* Delayed send */ + list_del_init(&msg->msg_list); + ni = msg->msg_txni; + CDEBUG(D_NET, "TRACE: msg %p %s -> %s : %s\n", msg, + libcfs_nid2str(ni->ni_nid), + libcfs_nid2str(msg->msg_txpeer->lpni_nid), + lnet_msgtyp2str(msg->msg_type)); + lnet_ni_send(ni, msg); + continue; + } + + /* Delayed receive */ LASSERT(msg->msg_rxpeer != NULL); LASSERT(msg->msg_rxni != NULL); -- 1.8.3.1