diff options
-rw-r--r-- | mm/mempolicy.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index e9fc1c1ae66c..c6c61ea6bb8c 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -591,16 +591,29 @@ static long do_set_mempolicy(unsigned short mode, unsigned short flags, | |||
591 | nodemask_t *nodes) | 591 | nodemask_t *nodes) |
592 | { | 592 | { |
593 | struct mempolicy *new; | 593 | struct mempolicy *new; |
594 | struct mm_struct *mm = current->mm; | ||
594 | 595 | ||
595 | new = mpol_new(mode, flags, nodes); | 596 | new = mpol_new(mode, flags, nodes); |
596 | if (IS_ERR(new)) | 597 | if (IS_ERR(new)) |
597 | return PTR_ERR(new); | 598 | return PTR_ERR(new); |
599 | |||
600 | /* | ||
601 | * prevent changing our mempolicy while show_numa_maps() | ||
602 | * is using it. | ||
603 | * Note: do_set_mempolicy() can be called at init time | ||
604 | * with no 'mm'. | ||
605 | */ | ||
606 | if (mm) | ||
607 | down_write(&mm->mmap_sem); | ||
598 | mpol_put(current->mempolicy); | 608 | mpol_put(current->mempolicy); |
599 | current->mempolicy = new; | 609 | current->mempolicy = new; |
600 | mpol_set_task_struct_flag(); | 610 | mpol_set_task_struct_flag(); |
601 | if (new && new->policy == MPOL_INTERLEAVE && | 611 | if (new && new->policy == MPOL_INTERLEAVE && |
602 | nodes_weight(new->v.nodes)) | 612 | nodes_weight(new->v.nodes)) |
603 | current->il_next = first_node(new->v.nodes); | 613 | current->il_next = first_node(new->v.nodes); |
614 | if (mm) | ||
615 | up_write(&mm->mmap_sem); | ||
616 | |||
604 | return 0; | 617 | return 0; |
605 | } | 618 | } |
606 | 619 | ||