cr: move CR_BAD_VM_FLAGS to header file
Subsystems (6)
PATCH 1/3 cr: move CR_BAD_VM_FLAGS to header file
[ this set is on top of Dave's c/r tree ]
We'll be using it from files other than ckpt_mem.c soon.
--- checkpoint/ckpt_mem.c | 3 --- include/linux/checkpoint.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-)
checkpoint/ckpt_mem.c +0 -3
@@ -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));
include/linux/checkpoint.h +3 -0
@@ -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 */
Signature · 1 line
1.5.4.3
PATCH 2/3 cr: add file checkpointability to /proc/pid/status
Add file checkpointability info at the end of /proc/pid/status output. This will next be augmented by vm checkpointability info.
--- checkpoint/checkpoint.c | 14 ++++++++++++++ fs/proc/array.c | 2 ++ include/linux/checkpoint.h | 4 ++++ 3 files changed, 20 insertions(+), 0 deletions(-)
checkpoint/checkpoint.c +14 -0
@@ -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
fs/proc/array.c +2 -0
@@ -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 ; }
include/linux/checkpoint.h +4 -0
@@ -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_ */
Signature · 1 line
1.5.4.3
PATCH 3/3 cr: track mm checkpointability
In reply to Serge E. HallynTrack 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...
--- 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(-)
checkpoint/checkpoint.c +24 -0
@@ -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
include/linux/checkpoint.h +32 -0
@@ -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_ */
include/linux/mm.h +1 -0
@@ -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 */
include/linux/mm_types.h +3 -0
@@ -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 */
kernel/fork.c +5 -0
@@ -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; }
mm/mmap.c +2 -0
@@ -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 */
Signature · 1 line
1.5.4.3