[Devel] [RFC v14-rc3][PATCH 33/36] Support for share memory address spaces

Oren Laadan orenl at cs.columbia.edu
Tue Apr 7 05:27:41 PDT 2009


The task address space (task->mm) may be shared between processes if
CLONE_VM is used, and particularly among threads. Accordingly, treat
'task->mm' as a shared object: during checkpoint check against the
objhash and only dump the contents if seen for the first time. During
restart, likewise, only restore if it's a new instance, otherwise use
the one already registered in the objhash.

Signed-off-by: Oren Laadan <orenl at cs.columbia.edu>
---
 checkpoint/ckpt_mem.c      |   36 +++++++++++++++++++++++-------------
 checkpoint/objhash.c       |    6 ++++++
 checkpoint/rstr_mem.c      |   31 +++++++++++++++++++++++++++----
 include/linux/checkpoint.h |    1 +
 4 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/checkpoint/ckpt_mem.c b/checkpoint/ckpt_mem.c
index 92a3edc..0df3cda 100644
--- a/checkpoint/ckpt_mem.c
+++ b/checkpoint/ckpt_mem.c
@@ -733,22 +733,29 @@ int cr_write_mm(struct cr_ctx *ctx, struct task_struct *t)
 	struct cr_hdr_mm *hh;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
-	int objref, ret;
+	int objref, new;
+	int ret;
+
+	mm = get_task_mm(t);
+
+	new = cr_obj_add_ptr(ctx, mm, &objref, CR_OBJ_MM, 0);
+	if (new < 0) {
+		ret = new;
+		goto mmput;
+	}
 
 	h.type = CR_HDR_MM;
 	h.len = sizeof(*hh);
 
+	ret = -ENOMEM;
 	hh = cr_hbuf_get(ctx, sizeof(*hh));
 	if (!hh)
-		return -ENOMEM;
+		goto mmput;
 
-	mm = get_task_mm(t);
+	down_read(&mm->mmap_sem);
 
-	objref = 0;	/* will be meaningful with multiple processes */
 	hh->objref = objref;
 
-	down_read(&mm->mmap_sem);
-
 	hh->start_code = mm->start_code;
 	hh->end_code = mm->end_code;
 	hh->start_data = mm->start_data;
@@ -770,17 +777,20 @@ int cr_write_mm(struct cr_ctx *ctx, struct task_struct *t)
 	if (ret < 0)
 		goto out;
 
-	/* write the vma's */
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		ret = cr_write_vma(ctx, vma);
-		if (ret < 0)
-			goto out;
-	}
+	if (new) {
+		/* write the vma's */
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			ret = cr_write_vma(ctx, vma);
+			if (ret < 0)
+				goto out;
+		}
 
-	ret = cr_write_mm_context(ctx, mm);
+		ret = cr_write_mm_context(ctx, mm);
+	}
 
  out:
 	up_read(&mm->mmap_sem);
+ mmput:
 	mmput(mm);
 	return ret;
 }
diff --git a/checkpoint/objhash.c b/checkpoint/objhash.c
index 25916c1..6584579 100644
--- a/checkpoint/objhash.c
+++ b/checkpoint/objhash.c
@@ -38,6 +38,9 @@ static void cr_obj_ref_drop(struct cr_objref *obj)
 	case CR_OBJ_INODE:
 		iput((struct inode *) obj->ptr);
 		break;
+	case CR_OBJ_MM:
+		mmput((struct mm_struct *) obj->ptr);
+		break;
 	default:
 		BUG();
 	}
@@ -55,6 +58,9 @@ static int cr_obj_ref_grab(struct cr_objref *obj)
 		if (!igrab((struct inode *) obj->ptr))
 			ret = -EBADF;
 		break;
+	case CR_OBJ_MM:
+		atomic_inc(&((struct mm_struct *) obj->ptr)->mm_users);
+		break;
 	default:
 		BUG();
 	}
diff --git a/checkpoint/rstr_mem.c b/checkpoint/rstr_mem.c
index da3eb0e..7e73129 100644
--- a/checkpoint/rstr_mem.c
+++ b/checkpoint/rstr_mem.c
@@ -505,16 +505,39 @@ int cr_read_mm(struct cr_ctx *ctx)
 	if (ret < 0)
 		goto out;
 
-	cr_debug("map_count %d\n", hh->map_count);
+	cr_debug("map_count %d objref %d\n", hh->map_count, hh->objref);
 
-	/* XXX need more sanity checks */
+	/* FIX need more sanity checks */
 
 	ret = -EINVAL;
-	if ((hh->start_code > hh->end_code) ||
-	    (hh->start_data > hh->end_data))
+	if (hh->objref < 0)
 		goto out;
+	if ((hh->start_code > hh->end_code) || (hh->start_data > hh->end_data))
+		goto out;
+
+	/* if the mm's objref is in the objhash, use that instance */
+	mm = cr_obj_get_by_ref(ctx, hh->objref, CR_OBJ_MM);
+	if (IS_ERR(mm)) {
+		ret = PTR_ERR(mm);
+		goto out;
+	}
 
+	if (mm) {
+		if (mm != current->mm) {
+			ret = exec_mmap(mm);
+			if (ret < 0)
+				goto out;
+			atomic_inc(&mm->mm_users);
+		}
+		ret = 0;
+		goto out;
+	}
+
+	/* otherwise, add our mm to the objhash for future generations */
 	mm = current->mm;
+	ret = cr_obj_add_ref(ctx, mm, hh->objref, CR_OBJ_MM, 0);
+	if (ret < 0)
+		goto out;
 
 	/* point of no return -- destruct current mm */
 	down_write(&mm->mmap_sem);
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index 043535c..1bfe284 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -77,6 +77,7 @@ extern void cr_ctx_put(struct cr_ctx *ctx);
 enum {
 	CR_OBJ_FILE = 1,
 	CR_OBJ_INODE,
+	CR_OBJ_MM,
 	CR_OBJ_MAX
 };
 
-- 
1.5.4.3

_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list