All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jack Wang <jinpu.wang@ionos.com>
To: linux-rdma@vger.kernel.org
Cc: bvanassche@acm.org, leon@kernel.org, dledford@redhat.com,
	jgg@ziepe.ca, haris.iqbal@ionos.com, jinpu.wang@ionos.com,
	Md Haris Iqbal <haris.iqbal@cloud.ionos.com>,
	Gioh Kim <gi-oh.kim@ionos.com>
Subject: [PATCHv3 for-next 13/20] RDMA/rtrs-srv: Replace atomic_t with percpu_ref for ids_inflight
Date: Fri, 28 May 2021 13:30:11 +0200	[thread overview]
Message-ID: <20210528113018.52290-14-jinpu.wang@ionos.com> (raw)
In-Reply-To: <20210528113018.52290-1-jinpu.wang@ionos.com>

From: Md Haris Iqbal <haris.iqbal@cloud.ionos.com>

ids_inflight is used to track the inflight IOs. But the use of atomic_t
variable can cause performance drops and can also become a performance
bottleneck.

This commit replaces the use of atomic_t with a percpu_ref structure. The
advantage it offers is, it doesn't check if the reference has fallen to 0,
until the user explicitly signals it to; and that is done by the
percpu_ref_kill() function call. After that, the percpu_ref structure
behaves like an atomic_t and for every put call, checks whether the
reference has fallen to 0 or not.

rtrs_srv_stats_rdma_to_str shows the count of ids_inflight as 0
for user-mode tools not to be confused.

Fixes: 9cb837480424e ("RDMA/rtrs: server: main functionality")
Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Gioh Kim <gi-oh.kim@ionos.com>
---
 drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c | 12 +++---
 drivers/infiniband/ulp/rtrs/rtrs-srv.c       | 43 +++++++++++++-------
 drivers/infiniband/ulp/rtrs/rtrs-srv.h       |  4 +-
 3 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c
index e102b1368d0c..520c24773229 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c
@@ -27,12 +27,10 @@ ssize_t rtrs_srv_stats_rdma_to_str(struct rtrs_srv_stats *stats,
 				    char *page, size_t len)
 {
 	struct rtrs_srv_stats_rdma_stats *r = &stats->rdma_stats;
-	struct rtrs_srv_sess *sess = stats->sess;
 
-	return scnprintf(page, len, "%lld %lld %lld %lld %u\n",
-			 (s64)atomic64_read(&r->dir[READ].cnt),
-			 (s64)atomic64_read(&r->dir[READ].size_total),
-			 (s64)atomic64_read(&r->dir[WRITE].cnt),
-			 (s64)atomic64_read(&r->dir[WRITE].size_total),
-			 atomic_read(&sess->ids_inflight));
+	return scnprintf(page, len, "%lld %lld %lld %lldn %u\n",
+			  (s64)atomic64_read(&r->dir[READ].cnt),
+			  (s64)atomic64_read(&r->dir[READ].size_total),
+			  (s64)atomic64_read(&r->dir[WRITE].cnt),
+			  (s64)atomic64_read(&r->dir[WRITE].size_total), 0);
 }
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
index 840a3423f749..631d37976518 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
@@ -111,7 +111,6 @@ static void rtrs_srv_free_ops_ids(struct rtrs_srv_sess *sess)
 	struct rtrs_srv *srv = sess->srv;
 	int i;
 
-	WARN_ON(atomic_read(&sess->ids_inflight));
 	if (sess->ops_ids) {
 		for (i = 0; i < srv->queue_depth; i++)
 			free_id(sess->ops_ids[i]);
@@ -126,11 +125,19 @@ static struct ib_cqe io_comp_cqe = {
 	.done = rtrs_srv_rdma_done
 };
 
+static inline void rtrs_srv_inflight_ref_release(struct percpu_ref *ref)
+{
+	struct rtrs_srv_sess *sess = container_of(ref, struct rtrs_srv_sess, ids_inflight_ref);
+
+	percpu_ref_exit(&sess->ids_inflight_ref);
+	complete(&sess->complete_done);
+}
+
 static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_sess *sess)
 {
 	struct rtrs_srv *srv = sess->srv;
 	struct rtrs_srv_op *id;
-	int i;
+	int i, ret;
 
 	sess->ops_ids = kcalloc(srv->queue_depth, sizeof(*sess->ops_ids),
 				GFP_KERNEL);
@@ -144,8 +151,14 @@ static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_sess *sess)
 
 		sess->ops_ids[i] = id;
 	}
-	init_waitqueue_head(&sess->ids_waitq);
-	atomic_set(&sess->ids_inflight, 0);
+
+	ret = percpu_ref_init(&sess->ids_inflight_ref,
+			      rtrs_srv_inflight_ref_release, 0, GFP_KERNEL);
+	if (ret) {
+		pr_err("Percpu reference init failed\n");
+		goto err;
+	}
+	init_completion(&sess->complete_done);
 
 	return 0;
 
@@ -156,21 +169,14 @@ static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_sess *sess)
 
 static inline void rtrs_srv_get_ops_ids(struct rtrs_srv_sess *sess)
 {
-	atomic_inc(&sess->ids_inflight);
+	percpu_ref_get(&sess->ids_inflight_ref);
 }
 
 static inline void rtrs_srv_put_ops_ids(struct rtrs_srv_sess *sess)
 {
-	if (atomic_dec_and_test(&sess->ids_inflight))
-		wake_up(&sess->ids_waitq);
+	percpu_ref_put(&sess->ids_inflight_ref);
 }
 
-static void rtrs_srv_wait_ops_ids(struct rtrs_srv_sess *sess)
-{
-	wait_event(sess->ids_waitq, !atomic_read(&sess->ids_inflight));
-}
-
-
 static void rtrs_srv_reg_mr_done(struct ib_cq *cq, struct ib_wc *wc)
 {
 	struct rtrs_srv_con *con = to_srv_con(wc->qp->qp_context);
@@ -1479,8 +1485,15 @@ static void rtrs_srv_close_work(struct work_struct *work)
 		rdma_disconnect(con->c.cm_id);
 		ib_drain_qp(con->c.qp);
 	}
-	/* Wait for all inflights */
-	rtrs_srv_wait_ops_ids(sess);
+
+	/*
+	 * Degrade ref count to the usual model with a single shared
+	 * atomic_t counter
+	 */
+	percpu_ref_kill(&sess->ids_inflight_ref);
+
+	/* Wait for all completion */
+	wait_for_completion(&sess->complete_done);
 
 	/* Notify upper layer if we are the last path */
 	rtrs_srv_sess_down(sess);
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.h b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
index 9543ae19996c..f8da2e3f0bda 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.h
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.h
@@ -81,8 +81,8 @@ struct rtrs_srv_sess {
 	spinlock_t		state_lock;
 	int			cur_cq_vector;
 	struct rtrs_srv_op	**ops_ids;
-	atomic_t		ids_inflight;
-	wait_queue_head_t	ids_waitq;
+	struct percpu_ref       ids_inflight_ref;
+	struct completion       complete_done;
 	struct rtrs_srv_mr	*mrs;
 	unsigned int		mrs_num;
 	dma_addr_t		*dma_addr;
-- 
2.25.1


  parent reply	other threads:[~2021-05-28 11:30 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-28 11:29 [PATCHv3 for-next 00/20] RTRS update for 5.14 Jack Wang
2021-05-28 11:29 ` [PATCHv3 for-next 01/20] RDMA/rtrs-srv: Kill reject_w_econnreset label Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 02/20] RDMA/rtrs-clt: Remove MAX_SESS_QUEUE_DEPTH from rtrs_send_sess_info Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 03/20] RDMA/rtrs-srv: Add error messages for cases when failing RDMA connection Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 04/20] RDMA/rtrs-srv: Clean up the code in __rtrs_srv_change_state Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 05/20] RDMA/rtrs: Change MAX_SESS_QUEUE_DEPTH Jack Wang
2021-05-28 16:19   ` kernel test robot
2021-05-28 16:19     ` kernel test robot
2021-05-31 11:44     ` Jinpu Wang
2021-05-31 11:44       ` Jinpu Wang
2021-05-31 12:17       ` Jason Gunthorpe
2021-05-31 12:17         ` Jason Gunthorpe
2021-05-31 12:29         ` Jinpu Wang
2021-05-31 12:29           ` Jinpu Wang
2021-05-28 11:30 ` [PATCHv3 for-next 06/20] RDMA/rtrs: Define MIN_CHUNK_SIZE Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 07/20] RDMA/rtrs: Use strscpy instead of strlcpy Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 08/20] RDMA/rtrs-clt: Kill rtrs_clt_{start,stop}_hb Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 09/20] RDMA/rtrs-clt: Kill rtrs_clt_disconnect_from_sysfs Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 10/20] RDMA/rtrs-srv: Kill __rtrs_srv_change_state Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 11/20] RDMA/rtrs-clt: Remove redundant 'break' Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 12/20] RDMA/rtrs-clt: Check state of the rtrs_clt_sess before reading its stats Jack Wang
2021-05-28 11:30 ` Jack Wang [this message]
2021-05-28 11:30 ` [PATCHv3 for-next 14/20] RDMA/rtrs-srv: convert scnprintf to sysfs_emit Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 15/20] RDMA/rtrs: Do not reset hb_missed_max after re-connection Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 16/20] RDMA/rtrs-srv: Duplicated session name is not allowed Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 17/20] RDMA/rtrs-srv: Fix memory leak of unfreed rtrs_srv_stats object Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 18/20] RDMA/rtrs-srv: Fix memory leak when having multiple sessions Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 19/20] RDMA/rtrs-clt: Check if the queue_depth has changed during a reconnection Jack Wang
2021-05-28 11:30 ` [PATCHv3 for-next 20/20] RDMA/rtrs-clt: Fix memory leak of not-freed sess->stats and stats->pcpu_stats Jack Wang
2021-05-28 23:53 ` [PATCHv3 for-next 00/20] RTRS update for 5.14 Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210528113018.52290-14-jinpu.wang@ionos.com \
    --to=jinpu.wang@ionos.com \
    --cc=bvanassche@acm.org \
    --cc=dledford@redhat.com \
    --cc=gi-oh.kim@ionos.com \
    --cc=haris.iqbal@cloud.ionos.com \
    --cc=haris.iqbal@ionos.com \
    --cc=jgg@ziepe.ca \
    --cc=leon@kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.