From patchwork Wed Jul 4 15:51:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v5,16/19] epoll: Add kid_lookup_epoll_tfd helper From: Cyrill Gorcunov X-Patchwork-Id: 8822 Message-Id: <20180704155147.29114-17-gorcunov@gmail.com> To: crml Cc: Andrey Vagin Date: Wed, 4 Jul 2018 18:51:44 +0300 To find target files with help of our collected rbtree. Signed-off-by: Cyrill Gorcunov --- criu/file-ids.c | 2 +- criu/include/file-ids.h | 2 ++ criu/include/kcmp-ids.h | 4 ++++ criu/kcmp-ids.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/criu/file-ids.c b/criu/file-ids.c index 36973cbdd939..006e47d64f7e 100644 --- a/criu/file-ids.c +++ b/criu/file-ids.c @@ -19,7 +19,7 @@ #include "irmap.h" #include "files.h" -static DECLARE_KCMP_TREE(fd_tree, KCMP_FILE); +DECLARE_KCMP_TREE(fd_tree, KCMP_FILE); #define FDID_BITS 5 #define FDID_SIZE (1 << FDID_BITS) diff --git a/criu/include/file-ids.h b/criu/include/file-ids.h index 845cfaa9f9db..9a39f0d2d36a 100644 --- a/criu/include/file-ids.h +++ b/criu/include/file-ids.h @@ -16,4 +16,6 @@ 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_tree fd_tree; + #endif /* __CR_FILE_IDS_H__ */ diff --git a/criu/include/kcmp-ids.h b/criu/include/kcmp-ids.h index 37e2398db206..a37622c504a0 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_lookup_epoll_tfd(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..4fde10e67e75 100644 --- a/criu/kcmp-ids.c +++ b/criu/kcmp-ids.c @@ -152,5 +152,57 @@ uint32_t kid_generate_gen(struct kid_tree *tree, rb_link_and_balance(&tree->root, &e->node, parent, new); *new_id = 1; return e->subid; +} + +static struct kid_elem *kid_lookup_epoll_tfd_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; + struct rb_node **new = &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, new = &((*new)->rb_left); + else if (ret == 2) + node = node->rb_right, new = &((*new)->rb_right); + else if (ret == 0) + return &this->elem; + else { + pr_perror("kcmp-epoll 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_lookup_epoll_tfd(struct kid_tree *tree, + struct kid_elem *elem, + kcmp_epoll_slot_t *slot) +{ + struct rb_node *node = tree->root.rb_node; + struct rb_node **new = &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, new = &((*new)->rb_left); + else if (elem->genid > this->elem.genid) + node = node->rb_right, new = &((*new)->rb_right); + else + return kid_lookup_epoll_tfd_sub(tree, this, elem, slot); + } + return NULL; }