diff options
-rw-r--r-- | Documentation/cachetlb.txt | 2 | ||||
-rw-r--r-- | arch/x86/kernel/tboot.c | 1 | ||||
-rw-r--r-- | include/linux/mm_types.h | 9 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | init/main.c | 2 | ||||
-rw-r--r-- | kernel/fork.c | 37 | ||||
-rw-r--r-- | mm/init-mm.c | 1 |
7 files changed, 44 insertions, 9 deletions
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 9164ae3b83bc..9b728dc17535 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt | |||
@@ -16,7 +16,7 @@ on all processors in the system. Don't let this scare you into | |||
16 | thinking SMP cache/tlb flushing must be so inefficient, this is in | 16 | thinking SMP cache/tlb flushing must be so inefficient, this is in |
17 | fact an area where many optimizations are possible. For example, | 17 | fact an area where many optimizations are possible. For example, |
18 | if it can be proven that a user address space has never executed | 18 | if it can be proven that a user address space has never executed |
19 | on a cpu (see vma->cpu_vm_mask), one need not perform a flush | 19 | on a cpu (see mm_cpumask()), one need not perform a flush |
20 | for this address space on that cpu. | 20 | for this address space on that cpu. |
21 | 21 | ||
22 | First, the TLB flushing interfaces, since they are the simplest. The | 22 | First, the TLB flushing interfaces, since they are the simplest. The |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 998e972f3b1a..30ac65df7d4e 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -110,7 +110,6 @@ static struct mm_struct tboot_mm = { | |||
110 | .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), | 110 | .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), |
111 | .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), | 111 | .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), |
112 | .mmlist = LIST_HEAD_INIT(init_mm.mmlist), | 112 | .mmlist = LIST_HEAD_INIT(init_mm.mmlist), |
113 | .cpu_vm_mask = CPU_MASK_ALL, | ||
114 | }; | 113 | }; |
115 | 114 | ||
116 | static inline void switch_to_tboot_pt(void) | 115 | static inline void switch_to_tboot_pt(void) |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 201998e5b530..c2f9ea7922f4 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -265,8 +265,6 @@ struct mm_struct { | |||
265 | 265 | ||
266 | struct linux_binfmt *binfmt; | 266 | struct linux_binfmt *binfmt; |
267 | 267 | ||
268 | cpumask_t cpu_vm_mask; | ||
269 | |||
270 | /* Architecture-specific MM context */ | 268 | /* Architecture-specific MM context */ |
271 | mm_context_t context; | 269 | mm_context_t context; |
272 | 270 | ||
@@ -316,9 +314,14 @@ struct mm_struct { | |||
316 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 314 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
317 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ | 315 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ |
318 | #endif | 316 | #endif |
317 | |||
318 | cpumask_var_t cpu_vm_mask_var; | ||
319 | }; | 319 | }; |
320 | 320 | ||
321 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ | 321 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ |
322 | #define mm_cpumask(mm) (&(mm)->cpu_vm_mask) | 322 | static inline cpumask_t *mm_cpumask(struct mm_struct *mm) |
323 | { | ||
324 | return mm->cpu_vm_mask_var; | ||
325 | } | ||
323 | 326 | ||
324 | #endif /* _LINUX_MM_TYPES_H */ | 327 | #endif /* _LINUX_MM_TYPES_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 44b8faaac7c0..f18300eddfcb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2176,6 +2176,7 @@ static inline void mmdrop(struct mm_struct * mm) | |||
2176 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 2176 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
2177 | __mmdrop(mm); | 2177 | __mmdrop(mm); |
2178 | } | 2178 | } |
2179 | extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); | ||
2179 | 2180 | ||
2180 | /* mmput gets rid of the mappings and all user-space */ | 2181 | /* mmput gets rid of the mappings and all user-space */ |
2181 | extern void mmput(struct mm_struct *); | 2182 | extern void mmput(struct mm_struct *); |
diff --git a/init/main.c b/init/main.c index 48df882d51d2..22da33918aef 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -509,6 +509,8 @@ asmlinkage void __init start_kernel(void) | |||
509 | sort_main_extable(); | 509 | sort_main_extable(); |
510 | trap_init(); | 510 | trap_init(); |
511 | mm_init(); | 511 | mm_init(); |
512 | BUG_ON(mm_init_cpumask(&init_mm, 0)); | ||
513 | |||
512 | /* | 514 | /* |
513 | * Set up the scheduler prior starting any interrupts (such as the | 515 | * Set up the scheduler prior starting any interrupts (such as the |
514 | * timer interrupt). Full topology setup happens at smp_init() | 516 | * timer interrupt). Full topology setup happens at smp_init() |
diff --git a/kernel/fork.c b/kernel/fork.c index 927692734bcf..8e7e135d0817 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -485,6 +485,20 @@ static void mm_init_aio(struct mm_struct *mm) | |||
485 | #endif | 485 | #endif |
486 | } | 486 | } |
487 | 487 | ||
488 | int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) | ||
489 | { | ||
490 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
491 | if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | if (oldmm) | ||
495 | cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); | ||
496 | else | ||
497 | memset(mm_cpumask(mm), 0, cpumask_size()); | ||
498 | #endif | ||
499 | return 0; | ||
500 | } | ||
501 | |||
488 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 502 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
489 | { | 503 | { |
490 | atomic_set(&mm->mm_users, 1); | 504 | atomic_set(&mm->mm_users, 1); |
@@ -521,10 +535,20 @@ struct mm_struct * mm_alloc(void) | |||
521 | struct mm_struct * mm; | 535 | struct mm_struct * mm; |
522 | 536 | ||
523 | mm = allocate_mm(); | 537 | mm = allocate_mm(); |
524 | if (mm) { | 538 | if (!mm) |
525 | memset(mm, 0, sizeof(*mm)); | 539 | return NULL; |
526 | mm = mm_init(mm, current); | 540 | |
541 | memset(mm, 0, sizeof(*mm)); | ||
542 | mm = mm_init(mm, current); | ||
543 | if (!mm) | ||
544 | return NULL; | ||
545 | |||
546 | if (mm_init_cpumask(mm, NULL)) { | ||
547 | mm_free_pgd(mm); | ||
548 | free_mm(mm); | ||
549 | return NULL; | ||
527 | } | 550 | } |
551 | |||
528 | return mm; | 552 | return mm; |
529 | } | 553 | } |
530 | 554 | ||
@@ -536,6 +560,7 @@ struct mm_struct * mm_alloc(void) | |||
536 | void __mmdrop(struct mm_struct *mm) | 560 | void __mmdrop(struct mm_struct *mm) |
537 | { | 561 | { |
538 | BUG_ON(mm == &init_mm); | 562 | BUG_ON(mm == &init_mm); |
563 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
539 | mm_free_pgd(mm); | 564 | mm_free_pgd(mm); |
540 | destroy_context(mm); | 565 | destroy_context(mm); |
541 | mmu_notifier_mm_destroy(mm); | 566 | mmu_notifier_mm_destroy(mm); |
@@ -690,6 +715,9 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
690 | if (!mm_init(mm, tsk)) | 715 | if (!mm_init(mm, tsk)) |
691 | goto fail_nomem; | 716 | goto fail_nomem; |
692 | 717 | ||
718 | if (mm_init_cpumask(mm, oldmm)) | ||
719 | goto fail_nocpumask; | ||
720 | |||
693 | if (init_new_context(tsk, mm)) | 721 | if (init_new_context(tsk, mm)) |
694 | goto fail_nocontext; | 722 | goto fail_nocontext; |
695 | 723 | ||
@@ -716,6 +744,9 @@ fail_nomem: | |||
716 | return NULL; | 744 | return NULL; |
717 | 745 | ||
718 | fail_nocontext: | 746 | fail_nocontext: |
747 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
748 | |||
749 | fail_nocpumask: | ||
719 | /* | 750 | /* |
720 | * If init_new_context() failed, we cannot use mmput() to free the mm | 751 | * If init_new_context() failed, we cannot use mmput() to free the mm |
721 | * because it calls destroy_context() | 752 | * because it calls destroy_context() |
diff --git a/mm/init-mm.c b/mm/init-mm.c index 1d29cdfe8ebb..4019979b2637 100644 --- a/mm/init-mm.c +++ b/mm/init-mm.c | |||
@@ -21,6 +21,5 @@ struct mm_struct init_mm = { | |||
21 | .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), | 21 | .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), |
22 | .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), | 22 | .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), |
23 | .mmlist = LIST_HEAD_INIT(init_mm.mmlist), | 23 | .mmlist = LIST_HEAD_INIT(init_mm.mmlist), |
24 | .cpu_vm_mask = CPU_MASK_ALL, | ||
25 | INIT_MM_CONTEXT(init_mm) | 24 | INIT_MM_CONTEXT(init_mm) |
26 | }; | 25 | }; |