All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -next 1/2] ipc/mqueue: remove redundant wq task assignment
@ 2019-03-21 19:02 Davidlohr Bueso
  2019-03-21 19:02 ` [PATCH -next 2/2] ipc/mqueue: optimize msg_get() Davidlohr Bueso
  0 siblings, 1 reply; 2+ messages in thread
From: Davidlohr Bueso @ 2019-03-21 19:02 UTC (permalink / raw)
  To: akpm; +Cc: manfred, dave, linux-kernel, Davidlohr Bueso

We already store the current task fo the new waiter before calling
wq_sleep() in both send and recv paths. Trivially remove the redundant
assignment.

Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
 ipc/mqueue.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 127ba1e8950b..be3f599e90ed 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -617,8 +617,6 @@ static void wq_add(struct mqueue_inode_info *info, int sr,
 {
 	struct ext_wait_queue *walk;
 
-	ewp->task = current;
-
 	list_for_each_entry(walk, &info->e_wait_q[sr].list, list) {
 		if (walk->task->prio <= current->prio) {
 			list_add_tail(&ewp->list, &walk->list);
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH -next 2/2] ipc/mqueue: optimize msg_get()
  2019-03-21 19:02 [PATCH -next 1/2] ipc/mqueue: remove redundant wq task assignment Davidlohr Bueso
@ 2019-03-21 19:02 ` Davidlohr Bueso
  0 siblings, 0 replies; 2+ messages in thread
From: Davidlohr Bueso @ 2019-03-21 19:02 UTC (permalink / raw)
  To: akpm; +Cc: manfred, dave, linux-kernel, Davidlohr Bueso

Our msg priorities became an rbtree as of

    d6629859b36d ("ipc/mqueue: improve performance of send/recv")

however, consuming a msg in msg_get() remains logarithmic (still being better
than the case before of course). By applying well known techniques to cache
pointers we can have the node with the highest priority in O(1), which is
specially nice for the rt cases. Furthermore, some callers can call msg_get()
in a loop.

A new msg_tree_erase() helper is also added to encapsulate the tree removal
and node_cache game. Passes ltp mq testcases.

Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
 ipc/mqueue.c | 60 +++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index be3f599e90ed..0c68d8d4b1a9 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -76,6 +76,7 @@ struct mqueue_inode_info {
 	wait_queue_head_t wait_q;
 
 	struct rb_root msg_tree;
+	struct rb_node *msg_tree_rightmost;
 	struct posix_msg_tree_node *node_cache;
 	struct mq_attr attr;
 
@@ -131,6 +132,7 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info)
 {
 	struct rb_node **p, *parent = NULL;
 	struct posix_msg_tree_node *leaf;
+	bool rightmost = true;
 
 	p = &info->msg_tree.rb_node;
 	while (*p) {
@@ -139,9 +141,10 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info)
 
 		if (likely(leaf->priority == msg->m_type))
 			goto insert_msg;
-		else if (msg->m_type < leaf->priority)
+		else if (msg->m_type < leaf->priority) {
 			p = &(*p)->rb_left;
-		else
+			rightmost = false;
+		} else
 			p = &(*p)->rb_right;
 	}
 	if (info->node_cache) {
@@ -154,6 +157,10 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info)
 		INIT_LIST_HEAD(&leaf->msg_list);
 	}
 	leaf->priority = msg->m_type;
+
+	if (rightmost)
+		info->msg_tree_rightmost = &leaf->rb_node;
+
 	rb_link_node(&leaf->rb_node, parent, p);
 	rb_insert_color(&leaf->rb_node, &info->msg_tree);
 insert_msg:
@@ -163,23 +170,35 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info)
 	return 0;
 }
 
+static inline void msg_tree_erase(struct posix_msg_tree_node *leaf,
+				  struct mqueue_inode_info *info)
+{
+	struct rb_node *node = &leaf->rb_node;
+
+	if (info->msg_tree_rightmost == node)
+		info->msg_tree_rightmost = rb_prev(node);
+
+	rb_erase(node, &info->msg_tree);
+	if (info->node_cache) {
+		kfree(leaf);
+	} else {
+		info->node_cache = leaf;
+	}
+}
+
 static inline struct msg_msg *msg_get(struct mqueue_inode_info *info)
 {
-	struct rb_node **p, *parent = NULL;
+	struct rb_node *parent = NULL;
 	struct posix_msg_tree_node *leaf;
 	struct msg_msg *msg;
 
 try_again:
-	p = &info->msg_tree.rb_node;
-	while (*p) {
-		parent = *p;
-		/*
-		 * During insert, low priorities go to the left and high to the
-		 * right.  On receive, we want the highest priorities first, so
-		 * walk all the way to the right.
-		 */
-		p = &(*p)->rb_right;
-	}
+	/*
+	 * During insert, low priorities go to the left and high to the
+	 * right.  On receive, we want the highest priorities first, so
+	 * walk all the way to the right.
+	 */
+	parent = info->msg_tree_rightmost;
 	if (!parent) {
 		if (info->attr.mq_curmsgs) {
 			pr_warn_once("Inconsistency in POSIX message queue, "
@@ -194,24 +213,14 @@ static inline struct msg_msg *msg_get(struct mqueue_inode_info *info)
 		pr_warn_once("Inconsistency in POSIX message queue, "
 			     "empty leaf node but we haven't implemented "
 			     "lazy leaf delete!\n");
-		rb_erase(&leaf->rb_node, &info->msg_tree);
-		if (info->node_cache) {
-			kfree(leaf);
-		} else {
-			info->node_cache = leaf;
-		}
+		msg_tree_erase(leaf, info);
 		goto try_again;
 	} else {
 		msg = list_first_entry(&leaf->msg_list,
 				       struct msg_msg, m_list);
 		list_del(&msg->m_list);
 		if (list_empty(&leaf->msg_list)) {
-			rb_erase(&leaf->rb_node, &info->msg_tree);
-			if (info->node_cache) {
-				kfree(leaf);
-			} else {
-				info->node_cache = leaf;
-			}
+			msg_tree_erase(leaf, info);
 		}
 	}
 	info->attr.mq_curmsgs--;
@@ -254,6 +263,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
 		info->qsize = 0;
 		info->user = NULL;	/* set when all is ok */
 		info->msg_tree = RB_ROOT;
+		info->msg_tree_rightmost = NULL;
 		info->node_cache = NULL;
 		memset(&info->attr, 0, sizeof(info->attr));
 		info->attr.mq_maxmsg = min(ipc_ns->mq_msg_max,
-- 
2.16.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-03-21 19:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-21 19:02 [PATCH -next 1/2] ipc/mqueue: remove redundant wq task assignment Davidlohr Bueso
2019-03-21 19:02 ` [PATCH -next 2/2] ipc/mqueue: optimize msg_get() Davidlohr Bueso

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.