[07/10] kcmp: files -- Add fd_kid_epoll_lookup helper

Submitted by Cyrill Gorcunov on Feb. 28, 2017, 3:05 p.m.

Details

Message ID 1488294349-2742-8-git-send-email-gorcunov@openvz.org
State New
Series "epoll: Start using new kcmp operation to find targets"
Headers show

Commit Message

Cyrill Gorcunov Feb. 28, 2017, 3:05 p.m.
So we will use it to lookup for target file in epoll queue.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 criu/file-ids.c         | 12 ++++++++++++
 criu/include/file-ids.h |  6 +++++-
 criu/include/kcmp-ids.h |  4 ++++
 criu/kcmp-ids.c         | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 72 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/file-ids.c b/criu/file-ids.c
index 36973cbdd939..6e68eebe2cac 100644
--- a/criu/file-ids.c
+++ b/criu/file-ids.c
@@ -111,3 +111,15 @@  int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct fd_parms *p)
 	fe->id = id;
 	return new_id;
 }
+
+struct kid_elem *fd_kid_epoll_lookup(pid_t pid, unsigned int genid,
+				     kcmp_epoll_slot_t *slot)
+{
+	struct kid_elem e = {
+		.pid	= pid,
+		.genid	= genid,
+		.idx	= -1,	/* A stub, not needed for epoll */
+	};
+
+	return kid_epoll_lookup(&fd_tree, &e, slot);
+}
diff --git a/criu/include/file-ids.h b/criu/include/file-ids.h
index e796f403a57e..71acf6a1f242 100644
--- a/criu/include/file-ids.h
+++ b/criu/include/file-ids.h
@@ -5,6 +5,7 @@ 
 
 #include "common/compiler.h"
 #include "rbtree.h"
+#include "kcmp.h"
 
 #include "images/fdinfo.pb-c.h"
 
@@ -13,10 +14,13 @@ 
 
 struct fdinfo_entry;
 struct stat;
-
+struct kid_elem;
 struct fd_parms;
+
 extern int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct fd_parms *p);
 extern int fd_id_generate_special(struct fd_parms *p, u32 *id);
+extern struct kid_elem *fd_kid_epoll_lookup(pid_t pid, unsigned int genid,
+					    kcmp_epoll_slot_t *slot);
 
 /*
  * The gen_id thing is used to optimize the comparison of shared files.
diff --git a/criu/include/kcmp-ids.h b/criu/include/kcmp-ids.h
index 37e2398db206..b1f7a1970bb8 100644
--- a/criu/include/kcmp-ids.h
+++ b/criu/include/kcmp-ids.h
@@ -29,4 +29,8 @@  struct kid_elem {
 extern uint32_t kid_generate_gen(struct kid_tree *tree,
 				 struct kid_elem *elem, int *new_id);
 
+extern struct kid_elem *kid_epoll_lookup(struct kid_tree *tree,
+					 struct kid_elem *elem,
+					 kcmp_epoll_slot_t *slot);
+
 #endif /* __CR_KCMP_IDS_H__ */
diff --git a/criu/kcmp-ids.c b/criu/kcmp-ids.c
index 5b91fb66b886..79bd86f9140b 100644
--- a/criu/kcmp-ids.c
+++ b/criu/kcmp-ids.c
@@ -154,3 +154,54 @@  uint32_t kid_generate_gen(struct kid_tree *tree,
 	return e->subid;
 
 }
+
+static struct kid_elem *kid_epoll_lookup_sub(struct kid_tree *tree,
+					     struct kid_entry *e,
+					     struct kid_elem *elem,
+					     kcmp_epoll_slot_t *slot)
+{
+	struct rb_node *node = e->subtree_root.rb_node;
+
+	BUG_ON(!node);
+
+	while (node) {
+		struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node);
+		int ret = syscall(SYS_kcmp, this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
+				this->elem.idx, slot);
+
+		if (ret == 1)
+			node = node->rb_left;
+		else if (ret == 2)
+			node = node->rb_right;
+		else if (ret == 0)
+			return &this->elem;
+		else {
+			pr_perror("kcmp failed: pid (%d %d) type %u idx (%u %u)",
+				  this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
+				  this->elem.idx, elem->idx);
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+struct kid_elem *kid_epoll_lookup(struct kid_tree *tree,
+				  struct kid_elem *elem,
+				  kcmp_epoll_slot_t *slot)
+{
+	struct rb_node *node = tree->root.rb_node;
+
+	while (node) {
+		struct kid_entry *this = rb_entry(node, struct kid_entry, node);
+
+		if (elem->genid < this->elem.genid)
+			node = node->rb_left;
+		else if (elem->genid > this->elem.genid)
+			node = node->rb_right;
+		else
+			return kid_epoll_lookup_sub(tree, this, elem, slot);
+	}
+
+	return NULL;
+}

Comments

Kirill Tkhai March 13, 2017, 10:41 a.m.
On 28.02.2017 18:05, Cyrill Gorcunov wrote:
> So we will use it to lookup for target file in epoll queue.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>  criu/file-ids.c         | 12 ++++++++++++
>  criu/include/file-ids.h |  6 +++++-
>  criu/include/kcmp-ids.h |  4 ++++
>  criu/kcmp-ids.c         | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 72 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/file-ids.c b/criu/file-ids.c
> index 36973cbdd939..6e68eebe2cac 100644
> --- a/criu/file-ids.c
> +++ b/criu/file-ids.c
> @@ -111,3 +111,15 @@ int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct fd_parms *p)
>  	fe->id = id;
>  	return new_id;
>  }
> +
> +struct kid_elem *fd_kid_epoll_lookup(pid_t pid, unsigned int genid,
> +				     kcmp_epoll_slot_t *slot)
> +{
> +	struct kid_elem e = {
> +		.pid	= pid,
> +		.genid	= genid,
> +		.idx	= -1,	/* A stub, not needed for epoll */
> +	};
> +
> +	return kid_epoll_lookup(&fd_tree, &e, slot);
> +}
> diff --git a/criu/include/file-ids.h b/criu/include/file-ids.h
> index e796f403a57e..71acf6a1f242 100644
> --- a/criu/include/file-ids.h
> +++ b/criu/include/file-ids.h
> @@ -5,6 +5,7 @@
>  
>  #include "common/compiler.h"
>  #include "rbtree.h"
> +#include "kcmp.h"
>  
>  #include "images/fdinfo.pb-c.h"
>  
> @@ -13,10 +14,13 @@
>  
>  struct fdinfo_entry;
>  struct stat;
> -
> +struct kid_elem;
>  struct fd_parms;
> +
>  extern int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct fd_parms *p);
>  extern int fd_id_generate_special(struct fd_parms *p, u32 *id);
> +extern struct kid_elem *fd_kid_epoll_lookup(pid_t pid, unsigned int genid,
> +					    kcmp_epoll_slot_t *slot);
>  
>  /*
>   * The gen_id thing is used to optimize the comparison of shared files.
> diff --git a/criu/include/kcmp-ids.h b/criu/include/kcmp-ids.h
> index 37e2398db206..b1f7a1970bb8 100644
> --- a/criu/include/kcmp-ids.h
> +++ b/criu/include/kcmp-ids.h
> @@ -29,4 +29,8 @@ struct kid_elem {
>  extern uint32_t kid_generate_gen(struct kid_tree *tree,
>  				 struct kid_elem *elem, int *new_id);
>  
> +extern struct kid_elem *kid_epoll_lookup(struct kid_tree *tree,
> +					 struct kid_elem *elem,
> +					 kcmp_epoll_slot_t *slot);
> +
>  #endif /* __CR_KCMP_IDS_H__ */
> diff --git a/criu/kcmp-ids.c b/criu/kcmp-ids.c
> index 5b91fb66b886..79bd86f9140b 100644
> --- a/criu/kcmp-ids.c
> +++ b/criu/kcmp-ids.c
> @@ -154,3 +154,54 @@ uint32_t kid_generate_gen(struct kid_tree *tree,
>  	return e->subid;
>  
>  }
> +
> +static struct kid_elem *kid_epoll_lookup_sub(struct kid_tree *tree,

Parameter "tree" is unused in this function, and it may safely be killed.

> +					     struct kid_entry *e,
> +					     struct kid_elem *elem,
> +					     kcmp_epoll_slot_t *slot)
> +{
> +	struct rb_node *node = e->subtree_root.rb_node;
> +
> +	BUG_ON(!node);
> +
> +	while (node) {
> +		struct kid_entry *this = rb_entry(node, struct kid_entry, subtree_node);
> +		int ret = syscall(SYS_kcmp, this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
> +				this->elem.idx, slot);
> +
> +		if (ret == 1)
> +			node = node->rb_left;
> +		else if (ret == 2)
> +			node = node->rb_right;
> +		else if (ret == 0)
> +			return &this->elem;
> +		else {
> +			pr_perror("kcmp failed: pid (%d %d) type %u idx (%u %u)",
> +				  this->elem.pid, elem->pid, KCMP_EPOLL_TFD,
> +				  this->elem.idx, elem->idx);
> +			return NULL;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +struct kid_elem *kid_epoll_lookup(struct kid_tree *tree,
> +				  struct kid_elem *elem,
> +				  kcmp_epoll_slot_t *slot)
> +{
> +	struct rb_node *node = tree->root.rb_node;
> +
> +	while (node) {
> +		struct kid_entry *this = rb_entry(node, struct kid_entry, node);
> +
> +		if (elem->genid < this->elem.genid)
> +			node = node->rb_left;
> +		else if (elem->genid > this->elem.genid)
> +			node = node->rb_right;
> +		else
> +			return kid_epoll_lookup_sub(tree, this, elem, slot);
> +	}
> +
> +	return NULL;
> +}
>
Cyrill Gorcunov March 13, 2017, 11:20 a.m.
On Mon, Mar 13, 2017 at 01:41:43PM +0300, Kirill Tkhai wrote:
> > +
> > +static struct kid_elem *kid_epoll_lookup_sub(struct kid_tree *tree,
> 
> Parameter "tree" is unused in this function, and it may safely be killed.

Will do it on top of the series. Thanks!