diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-14 19:35:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-14 19:35:20 -0500 |
commit | 18d40eae7fb60ab1efa2a607b4b8a2d86036876a (patch) | |
tree | b4d5327671ad0ee2d572ab4355e28144b6b509d7 | |
parent | d455df0bcc00733a7d8eec900ed791ccd896a493 (diff) | |
parent | 7c2c11b208be09c156573fc0076b7b3646e05219 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton:
"17 fixes"
* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
arch: define weak abort()
mm, oom_reaper: fix memory corruption
kernel: make groups_sort calling a responsibility group_info allocators
mm/frame_vector.c: release a semaphore in 'get_vaddr_frames()'
tools/slabinfo-gnuplot: force to use bash shell
kcov: fix comparison callback signature
mm/slab.c: do not hash pointers when debugging slab
mm/page_alloc.c: avoid excessive IRQ disabled times in free_unref_page_list()
mm/memory.c: mark wp_huge_pmd() inline to prevent build failure
scripts/faddr2line: fix CROSS_COMPILE unset error
Documentation/vm/zswap.txt: update with same-value filled page feature
exec: avoid gcc-8 warning for get_task_comm
autofs: fix careless error in recent commit
string.h: workaround for increased stack usage
mm/kmemleak.c: make cond_resched() rate-limiting more efficient
lib/rbtree,drm/mm: add rbtree_replace_node_cached()
include/linux/idr.h: add #include <linux/bug.h>
-rw-r--r-- | Documentation/vm/zswap.txt | 22 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_mm.c | 8 | ||||
-rw-r--r-- | fs/autofs4/waitq.c | 1 | ||||
-rw-r--r-- | fs/exec.c | 7 | ||||
-rw-r--r-- | fs/nfsd/auth.c | 3 | ||||
-rw-r--r-- | include/linux/cred.h | 1 | ||||
-rw-r--r-- | include/linux/idr.h | 1 | ||||
-rw-r--r-- | include/linux/oom.h | 9 | ||||
-rw-r--r-- | include/linux/rbtree.h | 2 | ||||
-rw-r--r-- | include/linux/sched.h | 6 | ||||
-rw-r--r-- | include/linux/sched/coredump.h | 1 | ||||
-rw-r--r-- | include/linux/string.h | 5 | ||||
-rw-r--r-- | kernel/exit.c | 8 | ||||
-rw-r--r-- | kernel/groups.c | 5 | ||||
-rw-r--r-- | kernel/kcov.c | 4 | ||||
-rw-r--r-- | kernel/uid16.c | 1 | ||||
-rw-r--r-- | lib/rbtree.c | 10 | ||||
-rw-r--r-- | mm/frame_vector.c | 6 | ||||
-rw-r--r-- | mm/kmemleak.c | 2 | ||||
-rw-r--r-- | mm/memory.c | 3 | ||||
-rw-r--r-- | mm/mmap.c | 10 | ||||
-rw-r--r-- | mm/oom_kill.c | 4 | ||||
-rw-r--r-- | mm/page_alloc.c | 11 | ||||
-rw-r--r-- | mm/slab.c | 23 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_xdr.c | 1 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 1 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 2 | ||||
-rwxr-xr-x | scripts/faddr2line | 8 | ||||
-rw-r--r-- | tools/vm/slabinfo-gnuplot.sh | 2 |
30 files changed, 125 insertions, 43 deletions
diff --git a/Documentation/vm/zswap.txt b/Documentation/vm/zswap.txt index 89fff7d611cc..0b3a1148f9f0 100644 --- a/Documentation/vm/zswap.txt +++ b/Documentation/vm/zswap.txt | |||
@@ -98,5 +98,25 @@ request is made for a page in an old zpool, it is uncompressed using its | |||
98 | original compressor. Once all pages are removed from an old zpool, the zpool | 98 | original compressor. Once all pages are removed from an old zpool, the zpool |
99 | and its compressor are freed. | 99 | and its compressor are freed. |
100 | 100 | ||
101 | Some of the pages in zswap are same-value filled pages (i.e. contents of the | ||
102 | page have same value or repetitive pattern). These pages include zero-filled | ||
103 | pages and they are handled differently. During store operation, a page is | ||
104 | checked if it is a same-value filled page before compressing it. If true, the | ||
105 | compressed length of the page is set to zero and the pattern or same-filled | ||
106 | value is stored. | ||
107 | |||
108 | Same-value filled pages identification feature is enabled by default and can be | ||
109 | disabled at boot time by setting the "same_filled_pages_enabled" attribute to 0, | ||
110 | e.g. zswap.same_filled_pages_enabled=0. It can also be enabled and disabled at | ||
111 | runtime using the sysfs "same_filled_pages_enabled" attribute, e.g. | ||
112 | |||
113 | echo 1 > /sys/module/zswap/parameters/same_filled_pages_enabled | ||
114 | |||
115 | When zswap same-filled page identification is disabled at runtime, it will stop | ||
116 | checking for the same-value filled pages during store operation. However, the | ||
117 | existing pages which are marked as same-value filled pages remain stored | ||
118 | unchanged in zswap until they are either loaded or invalidated. | ||
119 | |||
101 | A debugfs interface is provided for various statistic about pool size, number | 120 | A debugfs interface is provided for various statistic about pool size, number |
102 | of pages stored, and various counters for the reasons pages are rejected. | 121 | of pages stored, same-value filled pages and various counters for the reasons |
122 | pages are rejected. | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index f04db3779b34..59eea9c65d3e 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -263,6 +263,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplis | |||
263 | return retval; | 263 | return retval; |
264 | } | 264 | } |
265 | 265 | ||
266 | groups_sort(group_info); | ||
266 | retval = set_current_groups(group_info); | 267 | retval = set_current_groups(group_info); |
267 | put_group_info(group_info); | 268 | put_group_info(group_info); |
268 | 269 | ||
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 61a1c8ea74bc..c3c79ee6119e 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -575,21 +575,23 @@ EXPORT_SYMBOL(drm_mm_remove_node); | |||
575 | */ | 575 | */ |
576 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) | 576 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
577 | { | 577 | { |
578 | struct drm_mm *mm = old->mm; | ||
579 | |||
578 | DRM_MM_BUG_ON(!old->allocated); | 580 | DRM_MM_BUG_ON(!old->allocated); |
579 | 581 | ||
580 | *new = *old; | 582 | *new = *old; |
581 | 583 | ||
582 | list_replace(&old->node_list, &new->node_list); | 584 | list_replace(&old->node_list, &new->node_list); |
583 | rb_replace_node(&old->rb, &new->rb, &old->mm->interval_tree.rb_root); | 585 | rb_replace_node_cached(&old->rb, &new->rb, &mm->interval_tree); |
584 | 586 | ||
585 | if (drm_mm_hole_follows(old)) { | 587 | if (drm_mm_hole_follows(old)) { |
586 | list_replace(&old->hole_stack, &new->hole_stack); | 588 | list_replace(&old->hole_stack, &new->hole_stack); |
587 | rb_replace_node(&old->rb_hole_size, | 589 | rb_replace_node(&old->rb_hole_size, |
588 | &new->rb_hole_size, | 590 | &new->rb_hole_size, |
589 | &old->mm->holes_size); | 591 | &mm->holes_size); |
590 | rb_replace_node(&old->rb_hole_addr, | 592 | rb_replace_node(&old->rb_hole_addr, |
591 | &new->rb_hole_addr, | 593 | &new->rb_hole_addr, |
592 | &old->mm->holes_addr); | 594 | &mm->holes_addr); |
593 | } | 595 | } |
594 | 596 | ||
595 | old->allocated = false; | 597 | old->allocated = false; |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 8fc41705c7cd..961a12dc6dc8 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -170,7 +170,6 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
170 | 170 | ||
171 | mutex_unlock(&sbi->wq_mutex); | 171 | mutex_unlock(&sbi->wq_mutex); |
172 | 172 | ||
173 | if (autofs4_write(sbi, pipe, &pkt, pktsz)) | ||
174 | switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { | 173 | switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { |
175 | case 0: | 174 | case 0: |
176 | break; | 175 | break; |
@@ -1216,15 +1216,14 @@ killed: | |||
1216 | return -EAGAIN; | 1216 | return -EAGAIN; |
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | char *get_task_comm(char *buf, struct task_struct *tsk) | 1219 | char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk) |
1220 | { | 1220 | { |
1221 | /* buf must be at least sizeof(tsk->comm) in size */ | ||
1222 | task_lock(tsk); | 1221 | task_lock(tsk); |
1223 | strncpy(buf, tsk->comm, sizeof(tsk->comm)); | 1222 | strncpy(buf, tsk->comm, buf_size); |
1224 | task_unlock(tsk); | 1223 | task_unlock(tsk); |
1225 | return buf; | 1224 | return buf; |
1226 | } | 1225 | } |
1227 | EXPORT_SYMBOL_GPL(get_task_comm); | 1226 | EXPORT_SYMBOL_GPL(__get_task_comm); |
1228 | 1227 | ||
1229 | /* | 1228 | /* |
1230 | * These functions flushes out all traces of the currently running executable | 1229 | * These functions flushes out all traces of the currently running executable |
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index 697f8ae7792d..f650e475d8f0 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c | |||
@@ -60,6 +60,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | |||
60 | gi->gid[i] = exp->ex_anon_gid; | 60 | gi->gid[i] = exp->ex_anon_gid; |
61 | else | 61 | else |
62 | gi->gid[i] = rqgi->gid[i]; | 62 | gi->gid[i] = rqgi->gid[i]; |
63 | |||
64 | /* Each thread allocates its own gi, no race */ | ||
65 | groups_sort(gi); | ||
63 | } | 66 | } |
64 | } else { | 67 | } else { |
65 | gi = get_group_info(rqgi); | 68 | gi = get_group_info(rqgi); |
diff --git a/include/linux/cred.h b/include/linux/cred.h index 099058e1178b..631286535d0f 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -83,6 +83,7 @@ extern int set_current_groups(struct group_info *); | |||
83 | extern void set_groups(struct cred *, struct group_info *); | 83 | extern void set_groups(struct cred *, struct group_info *); |
84 | extern int groups_search(const struct group_info *, kgid_t); | 84 | extern int groups_search(const struct group_info *, kgid_t); |
85 | extern bool may_setgroups(void); | 85 | extern bool may_setgroups(void); |
86 | extern void groups_sort(struct group_info *); | ||
86 | 87 | ||
87 | /* | 88 | /* |
88 | * The security context of a task | 89 | * The security context of a task |
diff --git a/include/linux/idr.h b/include/linux/idr.h index 7c3a365f7e12..fa14f834e4ed 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/radix-tree.h> | 15 | #include <linux/radix-tree.h> |
16 | #include <linux/gfp.h> | 16 | #include <linux/gfp.h> |
17 | #include <linux/percpu.h> | 17 | #include <linux/percpu.h> |
18 | #include <linux/bug.h> | ||
18 | 19 | ||
19 | struct idr { | 20 | struct idr { |
20 | struct radix_tree_root idr_rt; | 21 | struct radix_tree_root idr_rt; |
diff --git a/include/linux/oom.h b/include/linux/oom.h index 01c91d874a57..5bad038ac012 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
@@ -67,6 +67,15 @@ static inline bool tsk_is_oom_victim(struct task_struct * tsk) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Use this helper if tsk->mm != mm and the victim mm needs a special | ||
71 | * handling. This is guaranteed to stay true after once set. | ||
72 | */ | ||
73 | static inline bool mm_is_oom_victim(struct mm_struct *mm) | ||
74 | { | ||
75 | return test_bit(MMF_OOM_VICTIM, &mm->flags); | ||
76 | } | ||
77 | |||
78 | /* | ||
70 | * Checks whether a page fault on the given mm is still reliable. | 79 | * Checks whether a page fault on the given mm is still reliable. |
71 | * This is no longer true if the oom reaper started to reap the | 80 | * This is no longer true if the oom reaper started to reap the |
72 | * address space which is reflected by MMF_UNSTABLE flag set in | 81 | * address space which is reflected by MMF_UNSTABLE flag set in |
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index d574361943ea..fcbeed4053ef 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h | |||
@@ -99,6 +99,8 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
99 | struct rb_root *root); | 99 | struct rb_root *root); |
100 | extern void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, | 100 | extern void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, |
101 | struct rb_root *root); | 101 | struct rb_root *root); |
102 | extern void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, | ||
103 | struct rb_root_cached *root); | ||
102 | 104 | ||
103 | static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, | 105 | static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, |
104 | struct rb_node **rb_link) | 106 | struct rb_node **rb_link) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 21991d668d35..5124ba709830 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1503,7 +1503,11 @@ static inline void set_task_comm(struct task_struct *tsk, const char *from) | |||
1503 | __set_task_comm(tsk, from, false); | 1503 | __set_task_comm(tsk, from, false); |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | extern char *get_task_comm(char *to, struct task_struct *tsk); | 1506 | extern char *__get_task_comm(char *to, size_t len, struct task_struct *tsk); |
1507 | #define get_task_comm(buf, tsk) ({ \ | ||
1508 | BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN); \ | ||
1509 | __get_task_comm(buf, sizeof(buf), tsk); \ | ||
1510 | }) | ||
1507 | 1511 | ||
1508 | #ifdef CONFIG_SMP | 1512 | #ifdef CONFIG_SMP |
1509 | void scheduler_ipi(void); | 1513 | void scheduler_ipi(void); |
diff --git a/include/linux/sched/coredump.h b/include/linux/sched/coredump.h index 9c8847395b5e..ec912d01126f 100644 --- a/include/linux/sched/coredump.h +++ b/include/linux/sched/coredump.h | |||
@@ -70,6 +70,7 @@ static inline int get_dumpable(struct mm_struct *mm) | |||
70 | #define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */ | 70 | #define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */ |
71 | #define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */ | 71 | #define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */ |
72 | #define MMF_DISABLE_THP 24 /* disable THP for all VMAs */ | 72 | #define MMF_DISABLE_THP 24 /* disable THP for all VMAs */ |
73 | #define MMF_OOM_VICTIM 25 /* mm is the oom victim */ | ||
73 | #define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP) | 74 | #define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP) |
74 | 75 | ||
75 | #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\ | 76 | #define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\ |
diff --git a/include/linux/string.h b/include/linux/string.h index 410ecf17de3c..cfd83eb2f926 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -259,7 +259,10 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p) | |||
259 | { | 259 | { |
260 | __kernel_size_t ret; | 260 | __kernel_size_t ret; |
261 | size_t p_size = __builtin_object_size(p, 0); | 261 | size_t p_size = __builtin_object_size(p, 0); |
262 | if (p_size == (size_t)-1) | 262 | |
263 | /* Work around gcc excess stack consumption issue */ | ||
264 | if (p_size == (size_t)-1 || | ||
265 | (__builtin_constant_p(p[p_size - 1]) && p[p_size - 1] == '\0')) | ||
263 | return __builtin_strlen(p); | 266 | return __builtin_strlen(p); |
264 | ret = strnlen(p, p_size); | 267 | ret = strnlen(p, p_size); |
265 | if (p_size <= ret) | 268 | if (p_size <= ret) |
diff --git a/kernel/exit.c b/kernel/exit.c index 6b4298a41167..df0c91d5606c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1755,3 +1755,11 @@ Efault: | |||
1755 | return -EFAULT; | 1755 | return -EFAULT; |
1756 | } | 1756 | } |
1757 | #endif | 1757 | #endif |
1758 | |||
1759 | __weak void abort(void) | ||
1760 | { | ||
1761 | BUG(); | ||
1762 | |||
1763 | /* if that doesn't kill us, halt */ | ||
1764 | panic("Oops failed to kill thread"); | ||
1765 | } | ||
diff --git a/kernel/groups.c b/kernel/groups.c index e357bc800111..daae2f2dc6d4 100644 --- a/kernel/groups.c +++ b/kernel/groups.c | |||
@@ -86,11 +86,12 @@ static int gid_cmp(const void *_a, const void *_b) | |||
86 | return gid_gt(a, b) - gid_lt(a, b); | 86 | return gid_gt(a, b) - gid_lt(a, b); |
87 | } | 87 | } |
88 | 88 | ||
89 | static void groups_sort(struct group_info *group_info) | 89 | void groups_sort(struct group_info *group_info) |
90 | { | 90 | { |
91 | sort(group_info->gid, group_info->ngroups, sizeof(*group_info->gid), | 91 | sort(group_info->gid, group_info->ngroups, sizeof(*group_info->gid), |
92 | gid_cmp, NULL); | 92 | gid_cmp, NULL); |
93 | } | 93 | } |
94 | EXPORT_SYMBOL(groups_sort); | ||
94 | 95 | ||
95 | /* a simple bsearch */ | 96 | /* a simple bsearch */ |
96 | int groups_search(const struct group_info *group_info, kgid_t grp) | 97 | int groups_search(const struct group_info *group_info, kgid_t grp) |
@@ -122,7 +123,6 @@ int groups_search(const struct group_info *group_info, kgid_t grp) | |||
122 | void set_groups(struct cred *new, struct group_info *group_info) | 123 | void set_groups(struct cred *new, struct group_info *group_info) |
123 | { | 124 | { |
124 | put_group_info(new->group_info); | 125 | put_group_info(new->group_info); |
125 | groups_sort(group_info); | ||
126 | get_group_info(group_info); | 126 | get_group_info(group_info); |
127 | new->group_info = group_info; | 127 | new->group_info = group_info; |
128 | } | 128 | } |
@@ -206,6 +206,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) | |||
206 | return retval; | 206 | return retval; |
207 | } | 207 | } |
208 | 208 | ||
209 | groups_sort(group_info); | ||
209 | retval = set_current_groups(group_info); | 210 | retval = set_current_groups(group_info); |
210 | put_group_info(group_info); | 211 | put_group_info(group_info); |
211 | 212 | ||
diff --git a/kernel/kcov.c b/kernel/kcov.c index 15f33faf4013..7594c033d98a 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c | |||
@@ -157,7 +157,7 @@ void notrace __sanitizer_cov_trace_cmp2(u16 arg1, u16 arg2) | |||
157 | } | 157 | } |
158 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp2); | 158 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp2); |
159 | 159 | ||
160 | void notrace __sanitizer_cov_trace_cmp4(u16 arg1, u16 arg2) | 160 | void notrace __sanitizer_cov_trace_cmp4(u32 arg1, u32 arg2) |
161 | { | 161 | { |
162 | write_comp_data(KCOV_CMP_SIZE(2), arg1, arg2, _RET_IP_); | 162 | write_comp_data(KCOV_CMP_SIZE(2), arg1, arg2, _RET_IP_); |
163 | } | 163 | } |
@@ -183,7 +183,7 @@ void notrace __sanitizer_cov_trace_const_cmp2(u16 arg1, u16 arg2) | |||
183 | } | 183 | } |
184 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp2); | 184 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp2); |
185 | 185 | ||
186 | void notrace __sanitizer_cov_trace_const_cmp4(u16 arg1, u16 arg2) | 186 | void notrace __sanitizer_cov_trace_const_cmp4(u32 arg1, u32 arg2) |
187 | { | 187 | { |
188 | write_comp_data(KCOV_CMP_SIZE(2) | KCOV_CMP_CONST, arg1, arg2, | 188 | write_comp_data(KCOV_CMP_SIZE(2) | KCOV_CMP_CONST, arg1, arg2, |
189 | _RET_IP_); | 189 | _RET_IP_); |
diff --git a/kernel/uid16.c b/kernel/uid16.c index ce74a4901d2b..ef1da2a5f9bd 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c | |||
@@ -192,6 +192,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) | |||
192 | return retval; | 192 | return retval; |
193 | } | 193 | } |
194 | 194 | ||
195 | groups_sort(group_info); | ||
195 | retval = set_current_groups(group_info); | 196 | retval = set_current_groups(group_info); |
196 | put_group_info(group_info); | 197 | put_group_info(group_info); |
197 | 198 | ||
diff --git a/lib/rbtree.c b/lib/rbtree.c index ba4a9d165f1b..d3ff682fd4b8 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -603,6 +603,16 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
603 | } | 603 | } |
604 | EXPORT_SYMBOL(rb_replace_node); | 604 | EXPORT_SYMBOL(rb_replace_node); |
605 | 605 | ||
606 | void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, | ||
607 | struct rb_root_cached *root) | ||
608 | { | ||
609 | rb_replace_node(victim, new, &root->rb_root); | ||
610 | |||
611 | if (root->rb_leftmost == victim) | ||
612 | root->rb_leftmost = new; | ||
613 | } | ||
614 | EXPORT_SYMBOL(rb_replace_node_cached); | ||
615 | |||
606 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, | 616 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, |
607 | struct rb_root *root) | 617 | struct rb_root *root) |
608 | { | 618 | { |
diff --git a/mm/frame_vector.c b/mm/frame_vector.c index 297c7238f7d4..c64dca6e27c2 100644 --- a/mm/frame_vector.c +++ b/mm/frame_vector.c | |||
@@ -62,8 +62,10 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, | |||
62 | * get_user_pages_longterm() and disallow it for filesystem-dax | 62 | * get_user_pages_longterm() and disallow it for filesystem-dax |
63 | * mappings. | 63 | * mappings. |
64 | */ | 64 | */ |
65 | if (vma_is_fsdax(vma)) | 65 | if (vma_is_fsdax(vma)) { |
66 | return -EOPNOTSUPP; | 66 | ret = -EOPNOTSUPP; |
67 | goto out; | ||
68 | } | ||
67 | 69 | ||
68 | if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) { | 70 | if (!(vma->vm_flags & (VM_IO | VM_PFNMAP))) { |
69 | vec->got_ref = true; | 71 | vec->got_ref = true; |
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 3d4781756d50..d73c14294f3a 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -1523,7 +1523,7 @@ static void kmemleak_scan(void) | |||
1523 | if (page_count(page) == 0) | 1523 | if (page_count(page) == 0) |
1524 | continue; | 1524 | continue; |
1525 | scan_block(page, page + 1, NULL); | 1525 | scan_block(page, page + 1, NULL); |
1526 | if (!(pfn % (MAX_SCAN_SIZE / sizeof(*page)))) | 1526 | if (!(pfn & 63)) |
1527 | cond_resched(); | 1527 | cond_resched(); |
1528 | } | 1528 | } |
1529 | } | 1529 | } |
diff --git a/mm/memory.c b/mm/memory.c index 5eb3d2524bdc..cfaba6287702 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3831,7 +3831,8 @@ static inline int create_huge_pmd(struct vm_fault *vmf) | |||
3831 | return VM_FAULT_FALLBACK; | 3831 | return VM_FAULT_FALLBACK; |
3832 | } | 3832 | } |
3833 | 3833 | ||
3834 | static int wp_huge_pmd(struct vm_fault *vmf, pmd_t orig_pmd) | 3834 | /* `inline' is required to avoid gcc 4.1.2 build error */ |
3835 | static inline int wp_huge_pmd(struct vm_fault *vmf, pmd_t orig_pmd) | ||
3835 | { | 3836 | { |
3836 | if (vma_is_anonymous(vmf->vma)) | 3837 | if (vma_is_anonymous(vmf->vma)) |
3837 | return do_huge_pmd_wp_page(vmf, orig_pmd); | 3838 | return do_huge_pmd_wp_page(vmf, orig_pmd); |
@@ -3019,20 +3019,20 @@ void exit_mmap(struct mm_struct *mm) | |||
3019 | /* Use -1 here to ensure all VMAs in the mm are unmapped */ | 3019 | /* Use -1 here to ensure all VMAs in the mm are unmapped */ |
3020 | unmap_vmas(&tlb, vma, 0, -1); | 3020 | unmap_vmas(&tlb, vma, 0, -1); |
3021 | 3021 | ||
3022 | set_bit(MMF_OOM_SKIP, &mm->flags); | 3022 | if (unlikely(mm_is_oom_victim(mm))) { |
3023 | if (unlikely(tsk_is_oom_victim(current))) { | ||
3024 | /* | 3023 | /* |
3025 | * Wait for oom_reap_task() to stop working on this | 3024 | * Wait for oom_reap_task() to stop working on this |
3026 | * mm. Because MMF_OOM_SKIP is already set before | 3025 | * mm. Because MMF_OOM_SKIP is already set before |
3027 | * calling down_read(), oom_reap_task() will not run | 3026 | * calling down_read(), oom_reap_task() will not run |
3028 | * on this "mm" post up_write(). | 3027 | * on this "mm" post up_write(). |
3029 | * | 3028 | * |
3030 | * tsk_is_oom_victim() cannot be set from under us | 3029 | * mm_is_oom_victim() cannot be set from under us |
3031 | * either because current->mm is already set to NULL | 3030 | * either because victim->mm is already set to NULL |
3032 | * under task_lock before calling mmput and oom_mm is | 3031 | * under task_lock before calling mmput and oom_mm is |
3033 | * set not NULL by the OOM killer only if current->mm | 3032 | * set not NULL by the OOM killer only if victim->mm |
3034 | * is found not NULL while holding the task_lock. | 3033 | * is found not NULL while holding the task_lock. |
3035 | */ | 3034 | */ |
3035 | set_bit(MMF_OOM_SKIP, &mm->flags); | ||
3036 | down_write(&mm->mmap_sem); | 3036 | down_write(&mm->mmap_sem); |
3037 | up_write(&mm->mmap_sem); | 3037 | up_write(&mm->mmap_sem); |
3038 | } | 3038 | } |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index c957be32b27a..29f855551efe 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -683,8 +683,10 @@ static void mark_oom_victim(struct task_struct *tsk) | |||
683 | return; | 683 | return; |
684 | 684 | ||
685 | /* oom_mm is bound to the signal struct life time. */ | 685 | /* oom_mm is bound to the signal struct life time. */ |
686 | if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) | 686 | if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm)) { |
687 | mmgrab(tsk->signal->oom_mm); | 687 | mmgrab(tsk->signal->oom_mm); |
688 | set_bit(MMF_OOM_VICTIM, &mm->flags); | ||
689 | } | ||
688 | 690 | ||
689 | /* | 691 | /* |
690 | * Make sure that the task is woken up from uninterruptible sleep | 692 | * Make sure that the task is woken up from uninterruptible sleep |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 73f5d4556b3d..7e5e775e97f4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2684,6 +2684,7 @@ void free_unref_page_list(struct list_head *list) | |||
2684 | { | 2684 | { |
2685 | struct page *page, *next; | 2685 | struct page *page, *next; |
2686 | unsigned long flags, pfn; | 2686 | unsigned long flags, pfn; |
2687 | int batch_count = 0; | ||
2687 | 2688 | ||
2688 | /* Prepare pages for freeing */ | 2689 | /* Prepare pages for freeing */ |
2689 | list_for_each_entry_safe(page, next, list, lru) { | 2690 | list_for_each_entry_safe(page, next, list, lru) { |
@@ -2700,6 +2701,16 @@ void free_unref_page_list(struct list_head *list) | |||
2700 | set_page_private(page, 0); | 2701 | set_page_private(page, 0); |
2701 | trace_mm_page_free_batched(page); | 2702 | trace_mm_page_free_batched(page); |
2702 | free_unref_page_commit(page, pfn); | 2703 | free_unref_page_commit(page, pfn); |
2704 | |||
2705 | /* | ||
2706 | * Guard against excessive IRQ disabled times when we get | ||
2707 | * a large list of pages to free. | ||
2708 | */ | ||
2709 | if (++batch_count == SWAP_CLUSTER_MAX) { | ||
2710 | local_irq_restore(flags); | ||
2711 | batch_count = 0; | ||
2712 | local_irq_save(flags); | ||
2713 | } | ||
2703 | } | 2714 | } |
2704 | local_irq_restore(flags); | 2715 | local_irq_restore(flags); |
2705 | } | 2716 | } |
@@ -1584,11 +1584,8 @@ static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines) | |||
1584 | *dbg_redzone2(cachep, objp)); | 1584 | *dbg_redzone2(cachep, objp)); |
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | if (cachep->flags & SLAB_STORE_USER) { | 1587 | if (cachep->flags & SLAB_STORE_USER) |
1588 | pr_err("Last user: [<%p>](%pSR)\n", | 1588 | pr_err("Last user: (%pSR)\n", *dbg_userword(cachep, objp)); |
1589 | *dbg_userword(cachep, objp), | ||
1590 | *dbg_userword(cachep, objp)); | ||
1591 | } | ||
1592 | realobj = (char *)objp + obj_offset(cachep); | 1589 | realobj = (char *)objp + obj_offset(cachep); |
1593 | size = cachep->object_size; | 1590 | size = cachep->object_size; |
1594 | for (i = 0; i < size && lines; i += 16, lines--) { | 1591 | for (i = 0; i < size && lines; i += 16, lines--) { |
@@ -1621,7 +1618,7 @@ static void check_poison_obj(struct kmem_cache *cachep, void *objp) | |||
1621 | /* Mismatch ! */ | 1618 | /* Mismatch ! */ |
1622 | /* Print header */ | 1619 | /* Print header */ |
1623 | if (lines == 0) { | 1620 | if (lines == 0) { |
1624 | pr_err("Slab corruption (%s): %s start=%p, len=%d\n", | 1621 | pr_err("Slab corruption (%s): %s start=%px, len=%d\n", |
1625 | print_tainted(), cachep->name, | 1622 | print_tainted(), cachep->name, |
1626 | realobj, size); | 1623 | realobj, size); |
1627 | print_objinfo(cachep, objp, 0); | 1624 | print_objinfo(cachep, objp, 0); |
@@ -1650,13 +1647,13 @@ static void check_poison_obj(struct kmem_cache *cachep, void *objp) | |||
1650 | if (objnr) { | 1647 | if (objnr) { |
1651 | objp = index_to_obj(cachep, page, objnr - 1); | 1648 | objp = index_to_obj(cachep, page, objnr - 1); |
1652 | realobj = (char *)objp + obj_offset(cachep); | 1649 | realobj = (char *)objp + obj_offset(cachep); |
1653 | pr_err("Prev obj: start=%p, len=%d\n", realobj, size); | 1650 | pr_err("Prev obj: start=%px, len=%d\n", realobj, size); |
1654 | print_objinfo(cachep, objp, 2); | 1651 | print_objinfo(cachep, objp, 2); |
1655 | } | 1652 | } |
1656 | if (objnr + 1 < cachep->num) { | 1653 | if (objnr + 1 < cachep->num) { |
1657 | objp = index_to_obj(cachep, page, objnr + 1); | 1654 | objp = index_to_obj(cachep, page, objnr + 1); |
1658 | realobj = (char *)objp + obj_offset(cachep); | 1655 | realobj = (char *)objp + obj_offset(cachep); |
1659 | pr_err("Next obj: start=%p, len=%d\n", realobj, size); | 1656 | pr_err("Next obj: start=%px, len=%d\n", realobj, size); |
1660 | print_objinfo(cachep, objp, 2); | 1657 | print_objinfo(cachep, objp, 2); |
1661 | } | 1658 | } |
1662 | } | 1659 | } |
@@ -2608,7 +2605,7 @@ static void slab_put_obj(struct kmem_cache *cachep, | |||
2608 | /* Verify double free bug */ | 2605 | /* Verify double free bug */ |
2609 | for (i = page->active; i < cachep->num; i++) { | 2606 | for (i = page->active; i < cachep->num; i++) { |
2610 | if (get_free_obj(page, i) == objnr) { | 2607 | if (get_free_obj(page, i) == objnr) { |
2611 | pr_err("slab: double free detected in cache '%s', objp %p\n", | 2608 | pr_err("slab: double free detected in cache '%s', objp %px\n", |
2612 | cachep->name, objp); | 2609 | cachep->name, objp); |
2613 | BUG(); | 2610 | BUG(); |
2614 | } | 2611 | } |
@@ -2772,7 +2769,7 @@ static inline void verify_redzone_free(struct kmem_cache *cache, void *obj) | |||
2772 | else | 2769 | else |
2773 | slab_error(cache, "memory outside object was overwritten"); | 2770 | slab_error(cache, "memory outside object was overwritten"); |
2774 | 2771 | ||
2775 | pr_err("%p: redzone 1:0x%llx, redzone 2:0x%llx\n", | 2772 | pr_err("%px: redzone 1:0x%llx, redzone 2:0x%llx\n", |
2776 | obj, redzone1, redzone2); | 2773 | obj, redzone1, redzone2); |
2777 | } | 2774 | } |
2778 | 2775 | ||
@@ -3078,7 +3075,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, | |||
3078 | if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || | 3075 | if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || |
3079 | *dbg_redzone2(cachep, objp) != RED_INACTIVE) { | 3076 | *dbg_redzone2(cachep, objp) != RED_INACTIVE) { |
3080 | slab_error(cachep, "double free, or memory outside object was overwritten"); | 3077 | slab_error(cachep, "double free, or memory outside object was overwritten"); |
3081 | pr_err("%p: redzone 1:0x%llx, redzone 2:0x%llx\n", | 3078 | pr_err("%px: redzone 1:0x%llx, redzone 2:0x%llx\n", |
3082 | objp, *dbg_redzone1(cachep, objp), | 3079 | objp, *dbg_redzone1(cachep, objp), |
3083 | *dbg_redzone2(cachep, objp)); | 3080 | *dbg_redzone2(cachep, objp)); |
3084 | } | 3081 | } |
@@ -3091,7 +3088,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, | |||
3091 | cachep->ctor(objp); | 3088 | cachep->ctor(objp); |
3092 | if (ARCH_SLAB_MINALIGN && | 3089 | if (ARCH_SLAB_MINALIGN && |
3093 | ((unsigned long)objp & (ARCH_SLAB_MINALIGN-1))) { | 3090 | ((unsigned long)objp & (ARCH_SLAB_MINALIGN-1))) { |
3094 | pr_err("0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n", | 3091 | pr_err("0x%px: not aligned to ARCH_SLAB_MINALIGN=%d\n", |
3095 | objp, (int)ARCH_SLAB_MINALIGN); | 3092 | objp, (int)ARCH_SLAB_MINALIGN); |
3096 | } | 3093 | } |
3097 | return objp; | 3094 | return objp; |
@@ -4283,7 +4280,7 @@ static void show_symbol(struct seq_file *m, unsigned long address) | |||
4283 | return; | 4280 | return; |
4284 | } | 4281 | } |
4285 | #endif | 4282 | #endif |
4286 | seq_printf(m, "%p", (void *)address); | 4283 | seq_printf(m, "%px", (void *)address); |
4287 | } | 4284 | } |
4288 | 4285 | ||
4289 | static int leaks_show(struct seq_file *m, void *p) | 4286 | static int leaks_show(struct seq_file *m, void *p) |
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index c4778cae58ef..444380f968f1 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c | |||
@@ -231,6 +231,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
231 | goto out_free_groups; | 231 | goto out_free_groups; |
232 | creds->cr_group_info->gid[i] = kgid; | 232 | creds->cr_group_info->gid[i] = kgid; |
233 | } | 233 | } |
234 | groups_sort(creds->cr_group_info); | ||
234 | 235 | ||
235 | return 0; | 236 | return 0; |
236 | out_free_groups: | 237 | out_free_groups: |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 5dd4e6c9fef2..26531193fce4 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -481,6 +481,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
481 | goto out; | 481 | goto out; |
482 | rsci.cred.cr_group_info->gid[i] = kgid; | 482 | rsci.cred.cr_group_info->gid[i] = kgid; |
483 | } | 483 | } |
484 | groups_sort(rsci.cred.cr_group_info); | ||
484 | 485 | ||
485 | /* mech name */ | 486 | /* mech name */ |
486 | len = qword_get(&mesg, buf, mlen); | 487 | len = qword_get(&mesg, buf, mlen); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 740b67d5a733..af7f28fb8102 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -520,6 +520,7 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
520 | ug.gi->gid[i] = kgid; | 520 | ug.gi->gid[i] = kgid; |
521 | } | 521 | } |
522 | 522 | ||
523 | groups_sort(ug.gi); | ||
523 | ugp = unix_gid_lookup(cd, uid); | 524 | ugp = unix_gid_lookup(cd, uid); |
524 | if (ugp) { | 525 | if (ugp) { |
525 | struct cache_head *ch; | 526 | struct cache_head *ch; |
@@ -819,6 +820,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
819 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); | 820 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); |
820 | cred->cr_group_info->gid[i] = kgid; | 821 | cred->cr_group_info->gid[i] = kgid; |
821 | } | 822 | } |
823 | groups_sort(cred->cr_group_info); | ||
822 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { | 824 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { |
823 | *authp = rpc_autherr_badverf; | 825 | *authp = rpc_autherr_badverf; |
824 | return SVC_DENIED; | 826 | return SVC_DENIED; |
diff --git a/scripts/faddr2line b/scripts/faddr2line index 39e07d8574dd..7721d5b2b0c0 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line | |||
@@ -44,10 +44,10 @@ | |||
44 | set -o errexit | 44 | set -o errexit |
45 | set -o nounset | 45 | set -o nounset |
46 | 46 | ||
47 | READELF="${CROSS_COMPILE}readelf" | 47 | READELF="${CROSS_COMPILE:-}readelf" |
48 | ADDR2LINE="${CROSS_COMPILE}addr2line" | 48 | ADDR2LINE="${CROSS_COMPILE:-}addr2line" |
49 | SIZE="${CROSS_COMPILE}size" | 49 | SIZE="${CROSS_COMPILE:-}size" |
50 | NM="${CROSS_COMPILE}nm" | 50 | NM="${CROSS_COMPILE:-}nm" |
51 | 51 | ||
52 | command -v awk >/dev/null 2>&1 || die "awk isn't installed" | 52 | command -v awk >/dev/null 2>&1 || die "awk isn't installed" |
53 | command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed" | 53 | command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed" |
diff --git a/tools/vm/slabinfo-gnuplot.sh b/tools/vm/slabinfo-gnuplot.sh index 35b039864b77..0cf28aa6f21c 100644 --- a/tools/vm/slabinfo-gnuplot.sh +++ b/tools/vm/slabinfo-gnuplot.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/bash |
2 | 2 | ||
3 | # Sergey Senozhatsky, 2015 | 3 | # Sergey Senozhatsky, 2015 |
4 | # sergey.senozhatsky.work@gmail.com | 4 | # sergey.senozhatsky.work@gmail.com |