diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r-- | fs/proc/task_mmu.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 2ed53d18b2ef..2c9db29ea358 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -871,6 +871,11 @@ struct numa_maps { | |||
871 | unsigned long node[MAX_NUMNODES]; | 871 | unsigned long node[MAX_NUMNODES]; |
872 | }; | 872 | }; |
873 | 873 | ||
874 | struct numa_maps_private { | ||
875 | struct proc_maps_private proc_maps; | ||
876 | struct numa_maps md; | ||
877 | }; | ||
878 | |||
874 | static void gather_stats(struct page *page, struct numa_maps *md, int pte_dirty) | 879 | static void gather_stats(struct page *page, struct numa_maps *md, int pte_dirty) |
875 | { | 880 | { |
876 | int count = page_mapcount(page); | 881 | int count = page_mapcount(page); |
@@ -963,9 +968,10 @@ static int gather_hugetbl_stats(pte_t *pte, unsigned long hmask, | |||
963 | */ | 968 | */ |
964 | static int show_numa_map(struct seq_file *m, void *v) | 969 | static int show_numa_map(struct seq_file *m, void *v) |
965 | { | 970 | { |
966 | struct proc_maps_private *priv = m->private; | 971 | struct numa_maps_private *numa_priv = m->private; |
972 | struct proc_maps_private *proc_priv = &numa_priv->proc_maps; | ||
967 | struct vm_area_struct *vma = v; | 973 | struct vm_area_struct *vma = v; |
968 | struct numa_maps *md; | 974 | struct numa_maps *md = &numa_priv->md; |
969 | struct file *file = vma->vm_file; | 975 | struct file *file = vma->vm_file; |
970 | struct mm_struct *mm = vma->vm_mm; | 976 | struct mm_struct *mm = vma->vm_mm; |
971 | struct mm_walk walk = {}; | 977 | struct mm_walk walk = {}; |
@@ -976,9 +982,8 @@ static int show_numa_map(struct seq_file *m, void *v) | |||
976 | if (!mm) | 982 | if (!mm) |
977 | return 0; | 983 | return 0; |
978 | 984 | ||
979 | md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL); | 985 | /* Ensure we start with an empty set of numa_maps statistics. */ |
980 | if (!md) | 986 | memset(md, 0, sizeof(*md)); |
981 | return 0; | ||
982 | 987 | ||
983 | md->vma = vma; | 988 | md->vma = vma; |
984 | 989 | ||
@@ -987,7 +992,7 @@ static int show_numa_map(struct seq_file *m, void *v) | |||
987 | walk.private = md; | 992 | walk.private = md; |
988 | walk.mm = mm; | 993 | walk.mm = mm; |
989 | 994 | ||
990 | pol = get_vma_policy(priv->task, vma, vma->vm_start); | 995 | pol = get_vma_policy(proc_priv->task, vma, vma->vm_start); |
991 | mpol_to_str(buffer, sizeof(buffer), pol, 0); | 996 | mpol_to_str(buffer, sizeof(buffer), pol, 0); |
992 | mpol_cond_put(pol); | 997 | mpol_cond_put(pol); |
993 | 998 | ||
@@ -1034,12 +1039,12 @@ static int show_numa_map(struct seq_file *m, void *v) | |||
1034 | seq_printf(m, " N%d=%lu", n, md->node[n]); | 1039 | seq_printf(m, " N%d=%lu", n, md->node[n]); |
1035 | out: | 1040 | out: |
1036 | seq_putc(m, '\n'); | 1041 | seq_putc(m, '\n'); |
1037 | kfree(md); | ||
1038 | 1042 | ||
1039 | if (m->count < m->size) | 1043 | if (m->count < m->size) |
1040 | m->version = (vma != priv->tail_vma) ? vma->vm_start : 0; | 1044 | m->version = (vma != proc_priv->tail_vma) ? vma->vm_start : 0; |
1041 | return 0; | 1045 | return 0; |
1042 | } | 1046 | } |
1047 | |||
1043 | static const struct seq_operations proc_pid_numa_maps_op = { | 1048 | static const struct seq_operations proc_pid_numa_maps_op = { |
1044 | .start = m_start, | 1049 | .start = m_start, |
1045 | .next = m_next, | 1050 | .next = m_next, |
@@ -1049,7 +1054,20 @@ static const struct seq_operations proc_pid_numa_maps_op = { | |||
1049 | 1054 | ||
1050 | static int numa_maps_open(struct inode *inode, struct file *file) | 1055 | static int numa_maps_open(struct inode *inode, struct file *file) |
1051 | { | 1056 | { |
1052 | return do_maps_open(inode, file, &proc_pid_numa_maps_op); | 1057 | struct numa_maps_private *priv; |
1058 | int ret = -ENOMEM; | ||
1059 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1060 | if (priv) { | ||
1061 | priv->proc_maps.pid = proc_pid(inode); | ||
1062 | ret = seq_open(file, &proc_pid_numa_maps_op); | ||
1063 | if (!ret) { | ||
1064 | struct seq_file *m = file->private_data; | ||
1065 | m->private = priv; | ||
1066 | } else { | ||
1067 | kfree(priv); | ||
1068 | } | ||
1069 | } | ||
1070 | return ret; | ||
1053 | } | 1071 | } |
1054 | 1072 | ||
1055 | const struct file_operations proc_numa_maps_operations = { | 1073 | const struct file_operations proc_numa_maps_operations = { |