diff options
author | Gioh Kim <gi-oh.kim@cloud.ionos.com> | 2021-04-07 13:34:41 +0200 |
---|---|---|
committer | Jason Gunthorpe <jgg@nvidia.com> | 2021-04-14 00:44:54 +0200 |
commit | dc3b66a0ce70ec40fd60884a835b9ef976765914 (patch) | |
tree | d9273d7889cbf5d7614a954ab41859196fff418f /drivers/infiniband/ulp/rtrs/rtrs-clt.c | |
parent | Merge branch 'mlx5_memic_ops' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff) | |
download | linux-dc3b66a0ce70ec40fd60884a835b9ef976765914.tar.xz linux-dc3b66a0ce70ec40fd60884a835b9ef976765914.zip |
RDMA/rtrs-clt: Add a minimum latency multipath policy
This patch adds new multipath policy: min-latency. Client checks the
latency of each path when it sends the heart-beat. And it sends IO to the
path with the minimum latency.
Link: https://lore.kernel.org/r/20210407113444.150961-2-gi-oh.kim@ionos.com
Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/infiniband/ulp/rtrs/rtrs-clt.c')
-rw-r--r-- | drivers/infiniband/ulp/rtrs/rtrs-clt.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index cb1731a4483d..8139c790ba7d 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -628,6 +628,8 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc) } else if (imm_type == RTRS_HB_ACK_IMM) { WARN_ON(con->c.cid); sess->s.hb_missed_cnt = 0; + sess->s.hb_cur_latency = + ktime_sub(ktime_get(), sess->s.hb_last_sent); if (sess->flags & RTRS_MSG_NEW_RKEY_F) return rtrs_clt_recv_done(con, wc); } else { @@ -826,6 +828,57 @@ static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it) return min_path; } +/** + * get_next_path_min_latency() - Returns path with minimal latency. + * @it: the path pointer + * + * Return: a path with the lowest latency or NULL if all paths are tried + * + * Locks: + * rcu_read_lock() must be hold. + * + * Related to @MP_POLICY_MIN_LATENCY + * + * This DOES skip an already-tried path. + * There is a skip-list to skip a path if the path has tried but failed. + * It will try the minimum latency path and then the second minimum latency + * path and so on. Finally it will return NULL if all paths are tried. + * Therefore the caller MUST check the returned + * path is NULL and trigger the IO error. + */ +static struct rtrs_clt_sess *get_next_path_min_latency(struct path_it *it) +{ + struct rtrs_clt_sess *min_path = NULL; + struct rtrs_clt *clt = it->clt; + struct rtrs_clt_sess *sess; + ktime_t min_latency = INT_MAX; + ktime_t latency; + + list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) { + if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)) + continue; + + if (unlikely(!list_empty(raw_cpu_ptr(sess->mp_skip_entry)))) + continue; + + latency = sess->s.hb_cur_latency; + + if (latency < min_latency) { + min_latency = latency; + min_path = sess; + } + } + + /* + * add the path to the skip list, so that next time we can get + * a different one + */ + if (min_path) + list_add(raw_cpu_ptr(min_path->mp_skip_entry), &it->skip_list); + + return min_path; +} + static inline void path_it_init(struct path_it *it, struct rtrs_clt *clt) { INIT_LIST_HEAD(&it->skip_list); @@ -834,8 +887,10 @@ static inline void path_it_init(struct path_it *it, struct rtrs_clt *clt) if (clt->mp_policy == MP_POLICY_RR) it->next_path = get_next_path_rr; - else + else if (clt->mp_policy == MP_POLICY_MIN_INFLIGHT) it->next_path = get_next_path_min_inflight; + else + it->next_path = get_next_path_min_latency; } static inline void path_it_deinit(struct path_it *it) |