pstree: Relax parent finding fast path

Submitted by Pavel Emelianov on May 13, 2016, 1:33 p.m.

Details

Message ID 5735D7B1.6090105@virtuozzo.com
State Accepted
Series "pstree: Relax parent finding fast path"
Commit 98335b627cd777fbb805b1162cce83e0a69e1174
Headers show

Commit Message

Pavel Emelianov May 13, 2016, 1:33 p.m.
When we didn't have tree with pids, the search for parent
item was optimized. Nowadays we can just use one rbtree
lookup.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/pstree.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/pstree.c b/criu/pstree.c
index 5c0d30e..00e6204 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -478,7 +478,7 @@  static int read_pstree_image(void)
 {
 	int ret = 0, i;
 	struct cr_img *img;
-	struct pstree_item *pi, *parent = NULL;
+	struct pstree_item *pi;
 
 	pr_info("Reading image tree\n");
 
@@ -524,37 +524,22 @@  static int read_pstree_image(void)
 			root_item = pi;
 			pi->parent = NULL;
 		} else {
-			/*
-			 * Fast path -- if the pstree image is not edited, the
-			 * parent of any item should have already being restored
-			 * and sit among the last item's ancestors.
-			 */
-			while (parent) {
-				if (parent->pid.virt == e->ppid)
-					break;
-				parent = parent->parent;
-			}
-
-			if (parent == NULL) {
-				for_each_pstree_item(parent) {
-					if (parent->pid.virt == e->ppid)
-						break;
-				}
+			struct pid *pid;
+			struct pstree_item *parent;
 
-				if (parent == NULL) {
-					pr_err("Can't find a parent for %d\n", pi->pid.virt);
-					pstree_entry__free_unpacked(e, NULL);
-					xfree(pi);
-					goto err;
-				}
+			pid = pstree_pid_by_virt(e->ppid);
+			if (!pid || pid->state == TASK_UNDEF || pid->state == TASK_THREAD) {
+				pr_err("Can't find a parent for %d\n", pi->pid.virt);
+				pstree_entry__free_unpacked(e, NULL);
+				xfree(pi);
+				goto err;
 			}
 
+			parent = container_of(pid, struct pstree_item, pid);
 			pi->parent = parent;
 			list_add(&pi->sibling, &parent->children);
 		}
 
-		parent = pi;
-
 		pi->nr_threads = e->n_threads;
 		pi->threads = xmalloc(e->n_threads * sizeof(struct pid));
 		if (!pi->threads)

Comments

Andrey Vagin May 13, 2016, 3:03 p.m.
On Fri, May 13, 2016 at 04:33:37PM +0300, Pavel Emelyanov wrote:
> When we didn't have tree with pids, the search for parent
> item was optimized. Nowadays we can just use one rbtree
> lookup.
>

Acked-by: Andrew Vagin <avagin@virtuozzo.com>
 
> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
> ---
>  criu/pstree.c | 35 ++++++++++-------------------------
>  1 file changed, 10 insertions(+), 25 deletions(-)
> 
> diff --git a/criu/pstree.c b/criu/pstree.c
> index 5c0d30e..00e6204 100644
> --- a/criu/pstree.c
> +++ b/criu/pstree.c
> @@ -478,7 +478,7 @@ static int read_pstree_image(void)
>  {
>  	int ret = 0, i;
>  	struct cr_img *img;
> -	struct pstree_item *pi, *parent = NULL;
> +	struct pstree_item *pi;
>  
>  	pr_info("Reading image tree\n");
>  
> @@ -524,37 +524,22 @@ static int read_pstree_image(void)
>  			root_item = pi;
>  			pi->parent = NULL;
>  		} else {
> -			/*
> -			 * Fast path -- if the pstree image is not edited, the
> -			 * parent of any item should have already being restored
> -			 * and sit among the last item's ancestors.
> -			 */
> -			while (parent) {
> -				if (parent->pid.virt == e->ppid)
> -					break;
> -				parent = parent->parent;
> -			}
> -
> -			if (parent == NULL) {
> -				for_each_pstree_item(parent) {
> -					if (parent->pid.virt == e->ppid)
> -						break;
> -				}
> +			struct pid *pid;
> +			struct pstree_item *parent;
>  
> -				if (parent == NULL) {
> -					pr_err("Can't find a parent for %d\n", pi->pid.virt);
> -					pstree_entry__free_unpacked(e, NULL);
> -					xfree(pi);
> -					goto err;
> -				}
> +			pid = pstree_pid_by_virt(e->ppid);
> +			if (!pid || pid->state == TASK_UNDEF || pid->state == TASK_THREAD) {
> +				pr_err("Can't find a parent for %d\n", pi->pid.virt);
> +				pstree_entry__free_unpacked(e, NULL);
> +				xfree(pi);
> +				goto err;
>  			}
>  
> +			parent = container_of(pid, struct pstree_item, pid);
>  			pi->parent = parent;
>  			list_add(&pi->sibling, &parent->children);
>  		}
>  
> -		parent = pi;
> -
>  		pi->nr_threads = e->n_threads;
>  		pi->threads = xmalloc(e->n_threads * sizeof(struct pid));
>  		if (!pi->threads)
> -- 
> 2.5.0
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu