[PATCH 1/2] rds: track memory region (MR) usage in kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Excessive MR utilization by certain RDS applications can starve other
RDS applications from getting MRs. Therefore tracking MR usage by RDS
applications is beneficial.

The collected data is intended to be exported to userspace using
rds-info interface.

Signed-off-by: Manjunath Patil <manjunath.b.patil@xxxxxxxxxx>
Reviewed-by: Alan Maguire <alan.maguire@xxxxxxxxxx>
---
 net/rds/af_rds.c |  4 ++++
 net/rds/rdma.c   | 29 ++++++++++++++++++++++-------
 net/rds/rds.h    |  6 ++++++
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 1a5bf3fa4578..e291095e5224 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -688,6 +688,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
 	rs->rs_rx_traces = 0;
 	rs->rs_tos = 0;
 	rs->rs_conn = NULL;
+	rs->rs_pid = current->pid;
+	get_task_comm(rs->rs_comm, current);
+	atomic64_set(&rs->rs_mr_gets, 0);
+	atomic64_set(&rs->rs_mr_puts, 0);
 
 	spin_lock_bh(&rds_sock_lock);
 	list_add_tail(&rs->rs_item, &rds_sock_list);
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 585e6b3b69ce..a1ae7b5ea3b2 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -44,6 +44,23 @@
  *  - an rdma is an mlock, apply rlimit?
  */
 
+static inline void mr_stats_update_gets(struct rds_sock *rs)
+{
+	atomic64_inc(&rs->rs_mr_gets);
+}
+
+static inline void mr_stats_update_puts(struct rds_sock *rs)
+{
+	atomic64_inc(&rs->rs_mr_puts);
+}
+
+static inline void rds_rb_erase(struct rds_sock *rs, struct rds_mr *mr)
+{
+	rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
+	RB_CLEAR_NODE(&mr->r_rb_node);
+	mr_stats_update_puts(rs);
+}
+
 /*
  * get the number of pages by looking at the page indices that the start and
  * end addresses fall in.
@@ -106,7 +123,7 @@ static void rds_destroy_mr(struct rds_mr *mr)
 
 	spin_lock_irqsave(&rs->rs_rdma_lock, flags);
 	if (!RB_EMPTY_NODE(&mr->r_rb_node))
-		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
+		rds_rb_erase(rs, mr);
 	trans_private = mr->r_trans_private;
 	mr->r_trans_private = NULL;
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
@@ -137,8 +154,7 @@ void rds_rdma_drop_keys(struct rds_sock *rs)
 		mr = rb_entry(node, struct rds_mr, r_rb_node);
 		if (mr->r_trans == rs->rs_transport)
 			mr->r_invalidate = 0;
-		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
-		RB_CLEAR_NODE(&mr->r_rb_node);
+		rds_rb_erase(rs, mr);
 		spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
 		rds_destroy_mr(mr);
 		rds_mr_put(mr);
@@ -337,6 +353,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 	 * reference count. */
 	spin_lock_irqsave(&rs->rs_rdma_lock, flags);
 	found = rds_mr_tree_walk(&rs->rs_rdma_keys, mr->r_key, mr);
+	mr_stats_update_gets(rs);
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
 
 	BUG_ON(found && found != mr);
@@ -424,8 +441,7 @@ int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen)
 	spin_lock_irqsave(&rs->rs_rdma_lock, flags);
 	mr = rds_mr_tree_walk(&rs->rs_rdma_keys, rds_rdma_cookie_key(args.cookie), NULL);
 	if (mr) {
-		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
-		RB_CLEAR_NODE(&mr->r_rb_node);
+		rds_rb_erase(rs, mr);
 		if (args.flags & RDS_RDMA_INVALIDATE)
 			mr->r_invalidate = 1;
 	}
@@ -465,8 +481,7 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force)
 	}
 
 	if (mr->r_use_once || force) {
-		rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys);
-		RB_CLEAR_NODE(&mr->r_rb_node);
+		rds_rb_erase(rs, mr);
 		zot_me = 1;
 	}
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
diff --git a/net/rds/rds.h b/net/rds/rds.h
index e4a603523083..5e61868e1799 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -654,6 +654,12 @@ struct rds_sock {
 	spinlock_t		rs_rdma_lock;
 	struct rb_root		rs_rdma_keys;
 
+	/* per rds_sock MR stats */
+	pid_t                   rs_pid;
+	char                    rs_comm[TASK_COMM_LEN];
+	atomic64_t              rs_mr_gets;
+	atomic64_t              rs_mr_puts;
+
 	/* Socket options - in case there will be more */
 	unsigned char		rs_recverr,
 				rs_cong_monitor;
-- 
2.27.0.112.g101b320




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux