* [PATCH 1/3] cr: move CR_BAD_VM_FLAGS to header file
@ 2009-03-06 19:59 Serge E. Hallyn
2009-03-06 19:59 ` [PATCH 2/3] cr: add file checkpointability to /proc/pid/status Serge E. Hallyn
[not found] ` <20090306195911.GA9512-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 2 replies; 4+ messages in thread
From: Serge E. Hallyn @ 2009-03-06 19:59 UTC (permalink / raw)
To: Dave Hansen, Ingo Molnar, Oren Laadan, Alexey Dobriyan,
Cedric Le Goater
Cc: lkml, Linux Containers
[ this set is on top of Dave's c/r tree ]
We'll be using it from files other than ckpt_mem.c soon.
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
checkpoint/ckpt_mem.c | 3 ---
include/linux/checkpoint.h | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/checkpoint/ckpt_mem.c b/checkpoint/ckpt_mem.c
index 4925ff2..b2531f7 100644
--- a/checkpoint/ckpt_mem.c
+++ b/checkpoint/ckpt_mem.c
@@ -448,9 +448,6 @@ static int cr_write_vma(struct cr_ctx *ctx, struct vm_area_struct *vma)
hh->vm_flags = vma->vm_flags;
hh->vm_pgoff = vma->vm_pgoff;
-#define CR_BAD_VM_FLAGS \
- (VM_SHARED | VM_MAYSHARE | VM_IO | VM_HUGETLB | VM_NONLINEAR)
-
if (vma->vm_flags & CR_BAD_VM_FLAGS) {
pr_warning("c/r: unsupported VMA %#lx\n", vma->vm_flags);
cr_hbuf_put(ctx, sizeof(*hh));
diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h
index e77393f..6c31c1b 100644
--- a/include/linux/checkpoint.h
+++ b/include/linux/checkpoint.h
@@ -18,6 +18,9 @@
#define CR_VERSION 2
+#define CR_BAD_VM_FLAGS \
+ (VM_SHARED | VM_MAYSHARE | VM_IO | VM_HUGETLB | VM_NONLINEAR)
+
struct cr_ctx {
int crid; /* unique checkpoint id */
--
1.5.4.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/3] cr: add file checkpointability to /proc/pid/status 2009-03-06 19:59 [PATCH 1/3] cr: move CR_BAD_VM_FLAGS to header file Serge E. Hallyn @ 2009-03-06 19:59 ` Serge E. Hallyn [not found] ` <20090306195911.GA9512-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> 1 sibling, 0 replies; 4+ messages in thread From: Serge E. Hallyn @ 2009-03-06 19:59 UTC (permalink / raw) To: Dave Hansen, Ingo Molnar, Oren Laadan, Alexey Dobriyan, Cedric Le Goater Cc: lkml, Linux Containers Add file checkpointability info at the end of /proc/pid/status output. This will next be augmented by vm checkpointability info. Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> --- checkpoint/checkpoint.c | 14 ++++++++++++++ fs/proc/array.c | 2 ++ include/linux/checkpoint.h | 4 ++++ 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c index e0af8a2..5debe70 100644 --- a/checkpoint/checkpoint.c +++ b/checkpoint/checkpoint.c @@ -21,12 +21,26 @@ #include <linux/magic.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h> +#include <linux/seq_file.h> #include "checkpoint_arch.h" /* unique checkpoint identifier (FIXME: should be per-container ?) */ static atomic_t cr_ctx_count = ATOMIC_INIT(0); +void task_checkpoint_status(struct seq_file *m, struct task_struct *p) +{ + if (!p->files) { + seq_printf(m, "task has no files_struct\n"); + return; + } + + if (test_bit(0, &p->files->may_checkpoint)) + seq_printf(m, "files are checkpointable\n"); + else + seq_printf(m, "files are not checkpointable\n"); +} + /** * cr_write_obj - write a record described by a cr_hdr * @ctx: checkpoint context diff --git a/fs/proc/array.c b/fs/proc/array.c index 7e4877d..f350e45 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -81,6 +81,7 @@ #include <linux/seq_file.h> #include <linux/pid_namespace.h> #include <linux/tracehook.h> +#include <linux/checkpoint.h> #include <asm/pgtable.h> #include <asm/processor.h> @@ -339,6 +340,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, task_show_regs(m, task); #endif task_context_switch_counts(m, task); + task_checkpoint_status(m, task); return 0; } diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h index 6c31c1b..0e90b67 100644 --- a/include/linux/checkpoint.h +++ b/include/linux/checkpoint.h @@ -123,6 +123,8 @@ static inline int cr_enabled(void) return 1; } +extern void task_checkpoint_status(struct seq_file *m, struct task_struct *p); + #else /* !CONFIG_CHECKPOINT_RESTART */ static inline void files_deny_checkpointing(struct files_struct *files) {} @@ -143,5 +145,7 @@ static inline int cr_enabled(void) return 0; } +static inline void task_checkpoint_status(struct seq_file *m, + struct task_struct *p) {} #endif /* CONFIG_CHECKPOINT_RESTART */ #endif /* _CHECKPOINT_CKPT_H_ */ -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 4+ messages in thread
[parent not found: <20090306195911.GA9512-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>]
* [PATCH 3/3] cr: track mm checkpointability 2009-03-06 19:59 [PATCH 1/3] cr: move CR_BAD_VM_FLAGS to header file Serge E. Hallyn @ 2009-03-06 20:00 ` Serge E. Hallyn [not found] ` <20090306195911.GA9512-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> 1 sibling, 0 replies; 4+ messages in thread From: Serge E. Hallyn @ 2009-03-06 20:00 UTC (permalink / raw) To: Dave Hansen, Ingo Molnar, Oren Laadan, Alexey Dobriyan, Cedric Le Goater <clg@ Cc: Linux Containers, lkml Track checkpointability of an mm_struct. When a new mm_struct is created, it is checkpointable. If an mmap is added using one of the non-checkpointable flags (i.e. VM_IO) then the mm_struct becomes forevermore uncheckpointable. Also, creating a new container with a shared mm_struct makes the mm uncheckpointable. I realize vm_stat_account() may seem like an odd choice, but it really seems like the best fit... Signed-off-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org> --- checkpoint/checkpoint.c | 24 ++++++++++++++++++++++++ include/linux/checkpoint.h | 32 ++++++++++++++++++++++++++++++++ include/linux/mm.h | 1 + include/linux/mm_types.h | 3 +++ kernel/fork.c | 5 +++++ mm/mmap.c | 2 ++ 6 files changed, 67 insertions(+), 0 deletions(-) diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c index 5debe70..d8febd1 100644 --- a/checkpoint/checkpoint.c +++ b/checkpoint/checkpoint.c @@ -30,6 +30,15 @@ static atomic_t cr_ctx_count = ATOMIC_INIT(0); void task_checkpoint_status(struct seq_file *m, struct task_struct *p) { + struct mm_struct *mm = get_task_mm(p); + if (mm) { + if (test_bit(0, &mm->may_checkpoint)) + seq_printf(m, "mm is checkpointable\n"); + else + seq_printf(m, "mm is not checkpointable\n"); + mmput(mm); + } else + seq_printf(m, "task has no mm\n"); if (!p->files) { seq_printf(m, "task has no files_struct\n"); return; @@ -41,6 +50,21 @@ void task_checkpoint_status(struct seq_file *m, struct task_struct *p) seq_printf(m, "files are not checkpointable\n"); } +void checkpoint_assert_flags(struct mm_struct *mm, unsigned long flags) +{ + if (flags & CR_BAD_VM_FLAGS) + mm_deny_checkpointing(mm); +} + +void checkpoint_account_mm(struct mm_struct *mm, unsigned long flags, + long pages) +{ + if (pages < 0) + return; + + checkpoint_assert_flags(mm, flags); +} + /** * cr_write_obj - write a record described by a cr_hdr * @ctx: checkpoint context diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h index 0e90b67..a60e0b3 100644 --- a/include/linux/checkpoint.h +++ b/include/linux/checkpoint.h @@ -13,6 +13,11 @@ #include <linux/path.h> #include <linux/fs.h> #include <linux/fdtable.h> +#include <linux/mm.h> +#include <linux/mm_types.h> + +#define NEW_CONTAINER_FLAGS (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | \ + CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET) #ifdef CONFIG_CHECKPOINT_RESTART @@ -105,6 +110,19 @@ extern int cr_read_files(struct cr_ctx *ctx); #define pr_fmt(fmt) "[%d:c/r:%s] " fmt, task_pid_vnr(current), __func__ +static inline void __mm_deny_checkpointing(struct mm_struct *mm, + char *file, int line) +{ + if (!mm) + return; + if (!test_and_clear_bit(0, &mm->may_checkpoint)) + return; + printk(KERN_INFO "process loaded a vma which can not be " + "checkpointed at: %s:%d\n", file, line); +} +#define mm_deny_checkpointing(mm) \ + __mm_deny_checkpointing(mm, __FILE__, __LINE__) + static inline void __files_deny_checkpointing(struct files_struct *files, char *file, int line) { @@ -124,6 +142,14 @@ static inline int cr_enabled(void) } extern void task_checkpoint_status(struct seq_file *m, struct task_struct *p); +extern void checkpoint_assert_flags(struct mm_struct *mm, unsigned long flags); +extern void checkpoint_account_mm(struct mm_struct *mm, unsigned long flags, + long pages); + +static inline void checkpoint_clear_mm_flag(struct mm_struct *mm) +{ + set_bit(0, &mm->may_checkpoint); +} #else /* !CONFIG_CHECKPOINT_RESTART */ @@ -145,7 +171,13 @@ static inline int cr_enabled(void) return 0; } +static inline void checkpoint_clear_mm_flag(struct mm_struct *mm) {} +static inline void mm_deny_checkpointing(struct mm_struct *mm) {} static inline void task_checkpoint_status(struct seq_file *m, struct task_struct *p) {} +static inline void checkpoint_assert_flags(struct mm_struct *mm, + unsigned long flags) {} +static inline void checkpoint_account_mm(struct mm_struct *mm, + unsigned long flags, long pages) {} #endif /* CONFIG_CHECKPOINT_RESTART */ #endif /* _CHECKPOINT_CKPT_H_ */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 065cdf8..b3a0bd8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1255,6 +1255,7 @@ void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); static inline void vm_stat_account(struct mm_struct *mm, unsigned long flags, struct file *file, long pages) { + checkpoint_account_mm(mm, flags, files, pages); } #endif /* CONFIG_PROC_FS */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 92915e8..28c3c9f 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -274,6 +274,9 @@ struct mm_struct { #ifdef CONFIG_MMU_NOTIFIER struct mmu_notifier_mm *mmu_notifier_mm; #endif +#ifdef CONFIG_CHECKPOINT_RESTART + unsigned long may_checkpoint; +#endif }; #endif /* _LINUX_MM_TYPES_H */ diff --git a/kernel/fork.c b/kernel/fork.c index a66fbde..89c6c6b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -60,6 +60,7 @@ #include <linux/tty.h> #include <linux/proc_fs.h> #include <linux/blkdev.h> +#include <linux/checkpoint.h> #include <trace/sched.h> #include <asm/pgtable.h> @@ -295,6 +296,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) -pages); continue; } + checkpoint_assert_flags(mm, mpnt->vm_flags); charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; @@ -418,6 +420,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) { atomic_set(&mm->mm_users, 1); atomic_set(&mm->mm_count, 1); + checkpoint_clear_mm_flag(mm); init_rwsem(&mm->mmap_sem); INIT_LIST_HEAD(&mm->mmlist); mm->flags = (current->mm) ? current->mm->flags : default_dump_filter; @@ -655,6 +658,8 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) if (clone_flags & CLONE_VM) { atomic_inc(&oldmm->mm_users); mm = oldmm; + if (clone_flags & NEW_CONTAINER_FLAGS) + mm_deny_checkpointing(mm); goto good_mm; } diff --git a/mm/mmap.c b/mm/mmap.c index fb4df8f..8141fd0 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -27,6 +27,7 @@ #include <linux/mempolicy.h> #include <linux/rmap.h> #include <linux/mmu_notifier.h> +#include <linux/checkpoint.h> #include <asm/uaccess.h> #include <asm/cacheflush.h> @@ -903,6 +904,7 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags, mm->stack_vm += pages; if (flags & (VM_RESERVED|VM_IO)) mm->reserved_vm += pages; + checkpoint_account_mm(mm, flags, pages); } #endif /* CONFIG_PROC_FS */ -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] cr: track mm checkpointability @ 2009-03-06 20:00 ` Serge E. Hallyn 0 siblings, 0 replies; 4+ messages in thread From: Serge E. Hallyn @ 2009-03-06 20:00 UTC (permalink / raw) To: Dave Hansen, Ingo Molnar, Oren Laadan, Alexey Dobriyan, Cedric Le Goater Cc: lkml, Linux Containers Track checkpointability of an mm_struct. When a new mm_struct is created, it is checkpointable. If an mmap is added using one of the non-checkpointable flags (i.e. VM_IO) then the mm_struct becomes forevermore uncheckpointable. Also, creating a new container with a shared mm_struct makes the mm uncheckpointable. I realize vm_stat_account() may seem like an odd choice, but it really seems like the best fit... Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> --- checkpoint/checkpoint.c | 24 ++++++++++++++++++++++++ include/linux/checkpoint.h | 32 ++++++++++++++++++++++++++++++++ include/linux/mm.h | 1 + include/linux/mm_types.h | 3 +++ kernel/fork.c | 5 +++++ mm/mmap.c | 2 ++ 6 files changed, 67 insertions(+), 0 deletions(-) diff --git a/checkpoint/checkpoint.c b/checkpoint/checkpoint.c index 5debe70..d8febd1 100644 --- a/checkpoint/checkpoint.c +++ b/checkpoint/checkpoint.c @@ -30,6 +30,15 @@ static atomic_t cr_ctx_count = ATOMIC_INIT(0); void task_checkpoint_status(struct seq_file *m, struct task_struct *p) { + struct mm_struct *mm = get_task_mm(p); + if (mm) { + if (test_bit(0, &mm->may_checkpoint)) + seq_printf(m, "mm is checkpointable\n"); + else + seq_printf(m, "mm is not checkpointable\n"); + mmput(mm); + } else + seq_printf(m, "task has no mm\n"); if (!p->files) { seq_printf(m, "task has no files_struct\n"); return; @@ -41,6 +50,21 @@ void task_checkpoint_status(struct seq_file *m, struct task_struct *p) seq_printf(m, "files are not checkpointable\n"); } +void checkpoint_assert_flags(struct mm_struct *mm, unsigned long flags) +{ + if (flags & CR_BAD_VM_FLAGS) + mm_deny_checkpointing(mm); +} + +void checkpoint_account_mm(struct mm_struct *mm, unsigned long flags, + long pages) +{ + if (pages < 0) + return; + + checkpoint_assert_flags(mm, flags); +} + /** * cr_write_obj - write a record described by a cr_hdr * @ctx: checkpoint context diff --git a/include/linux/checkpoint.h b/include/linux/checkpoint.h index 0e90b67..a60e0b3 100644 --- a/include/linux/checkpoint.h +++ b/include/linux/checkpoint.h @@ -13,6 +13,11 @@ #include <linux/path.h> #include <linux/fs.h> #include <linux/fdtable.h> +#include <linux/mm.h> +#include <linux/mm_types.h> + +#define NEW_CONTAINER_FLAGS (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | \ + CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET) #ifdef CONFIG_CHECKPOINT_RESTART @@ -105,6 +110,19 @@ extern int cr_read_files(struct cr_ctx *ctx); #define pr_fmt(fmt) "[%d:c/r:%s] " fmt, task_pid_vnr(current), __func__ +static inline void __mm_deny_checkpointing(struct mm_struct *mm, + char *file, int line) +{ + if (!mm) + return; + if (!test_and_clear_bit(0, &mm->may_checkpoint)) + return; + printk(KERN_INFO "process loaded a vma which can not be " + "checkpointed at: %s:%d\n", file, line); +} +#define mm_deny_checkpointing(mm) \ + __mm_deny_checkpointing(mm, __FILE__, __LINE__) + static inline void __files_deny_checkpointing(struct files_struct *files, char *file, int line) { @@ -124,6 +142,14 @@ static inline int cr_enabled(void) } extern void task_checkpoint_status(struct seq_file *m, struct task_struct *p); +extern void checkpoint_assert_flags(struct mm_struct *mm, unsigned long flags); +extern void checkpoint_account_mm(struct mm_struct *mm, unsigned long flags, + long pages); + +static inline void checkpoint_clear_mm_flag(struct mm_struct *mm) +{ + set_bit(0, &mm->may_checkpoint); +} #else /* !CONFIG_CHECKPOINT_RESTART */ @@ -145,7 +171,13 @@ static inline int cr_enabled(void) return 0; } +static inline void checkpoint_clear_mm_flag(struct mm_struct *mm) {} +static inline void mm_deny_checkpointing(struct mm_struct *mm) {} static inline void task_checkpoint_status(struct seq_file *m, struct task_struct *p) {} +static inline void checkpoint_assert_flags(struct mm_struct *mm, + unsigned long flags) {} +static inline void checkpoint_account_mm(struct mm_struct *mm, + unsigned long flags, long pages) {} #endif /* CONFIG_CHECKPOINT_RESTART */ #endif /* _CHECKPOINT_CKPT_H_ */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 065cdf8..b3a0bd8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1255,6 +1255,7 @@ void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); static inline void vm_stat_account(struct mm_struct *mm, unsigned long flags, struct file *file, long pages) { + checkpoint_account_mm(mm, flags, files, pages); } #endif /* CONFIG_PROC_FS */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 92915e8..28c3c9f 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -274,6 +274,9 @@ struct mm_struct { #ifdef CONFIG_MMU_NOTIFIER struct mmu_notifier_mm *mmu_notifier_mm; #endif +#ifdef CONFIG_CHECKPOINT_RESTART + unsigned long may_checkpoint; +#endif }; #endif /* _LINUX_MM_TYPES_H */ diff --git a/kernel/fork.c b/kernel/fork.c index a66fbde..89c6c6b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -60,6 +60,7 @@ #include <linux/tty.h> #include <linux/proc_fs.h> #include <linux/blkdev.h> +#include <linux/checkpoint.h> #include <trace/sched.h> #include <asm/pgtable.h> @@ -295,6 +296,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) -pages); continue; } + checkpoint_assert_flags(mm, mpnt->vm_flags); charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; @@ -418,6 +420,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) { atomic_set(&mm->mm_users, 1); atomic_set(&mm->mm_count, 1); + checkpoint_clear_mm_flag(mm); init_rwsem(&mm->mmap_sem); INIT_LIST_HEAD(&mm->mmlist); mm->flags = (current->mm) ? current->mm->flags : default_dump_filter; @@ -655,6 +658,8 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) if (clone_flags & CLONE_VM) { atomic_inc(&oldmm->mm_users); mm = oldmm; + if (clone_flags & NEW_CONTAINER_FLAGS) + mm_deny_checkpointing(mm); goto good_mm; } diff --git a/mm/mmap.c b/mm/mmap.c index fb4df8f..8141fd0 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -27,6 +27,7 @@ #include <linux/mempolicy.h> #include <linux/rmap.h> #include <linux/mmu_notifier.h> +#include <linux/checkpoint.h> #include <asm/uaccess.h> #include <asm/cacheflush.h> @@ -903,6 +904,7 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags, mm->stack_vm += pages; if (flags & (VM_RESERVED|VM_IO)) mm->reserved_vm += pages; + checkpoint_account_mm(mm, flags, pages); } #endif /* CONFIG_PROC_FS */ -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-03-06 20:01 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-06 19:59 [PATCH 1/3] cr: move CR_BAD_VM_FLAGS to header file Serge E. Hallyn
2009-03-06 19:59 ` [PATCH 2/3] cr: add file checkpointability to /proc/pid/status Serge E. Hallyn
[not found] ` <20090306195911.GA9512-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-03-06 20:00 ` [PATCH 3/3] cr: track mm checkpointability Serge E. Hallyn
2009-03-06 20:00 ` Serge E. Hallyn
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.