diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-17 19:56:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-17 19:56:17 -0500 |
commit | fa7f578076a8814caa5371e9f4949e408140766d (patch) | |
tree | 8021be6f956e8a259523c394a01183797ce04422 | |
parent | 2dcd9c71c1ffa9a036e09047f60e08383bb0abb6 (diff) | |
parent | d1b069f5febc850556cf49e9bb9092d3179c5be5 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton:
- a bit more MM
- procfs updates
- dynamic-debug fixes
- lib/ updates
- checkpatch
- epoll
- nilfs2
- signals
- rapidio
- PID management cleanup and optimization
- kcov updates
- sysvipc updates
- quite a few misc things all over the place
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (94 commits)
EXPERT Kconfig menu: fix broken EXPERT menu
include/asm-generic/topology.h: remove unused parent_node() macro
arch/tile/include/asm/topology.h: remove unused parent_node() macro
arch/sparc/include/asm/topology_64.h: remove unused parent_node() macro
arch/sh/include/asm/topology.h: remove unused parent_node() macro
arch/ia64/include/asm/topology.h: remove unused parent_node() macro
drivers/pcmcia/sa1111_badge4.c: avoid unused function warning
mm: add infrastructure for get_user_pages_fast() benchmarking
sysvipc: make get_maxid O(1) again
sysvipc: properly name ipc_addid() limit parameter
sysvipc: duplicate lock comments wrt ipc_addid()
sysvipc: unteach ids->next_id for !CHECKPOINT_RESTORE
initramfs: use time64_t timestamps
drivers/watchdog: make use of devm_register_reboot_notifier()
kernel/reboot.c: add devm_register_reboot_notifier()
kcov: update documentation
Makefile: support flag -fsanitizer-coverage=trace-cmp
kcov: support comparison operands collection
kcov: remove pointless current != NULL check
kernel/panic.c: add TAINT_AUX
...
115 files changed, 1892 insertions, 952 deletions
diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst index 12278a926370..fdf72429f801 100644 --- a/Documentation/admin-guide/dynamic-debug-howto.rst +++ b/Documentation/admin-guide/dynamic-debug-howto.rst | |||
@@ -18,7 +18,7 @@ shortcut for ``print_hex_dump(KERN_DEBUG)``. | |||
18 | 18 | ||
19 | For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is | 19 | For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is |
20 | its ``prefix_str`` argument, if it is constant string; or ``hexdump`` | 20 | its ``prefix_str`` argument, if it is constant string; or ``hexdump`` |
21 | in case ``prefix_str`` is build dynamically. | 21 | in case ``prefix_str`` is built dynamically. |
22 | 22 | ||
23 | Dynamic debug has even more useful features: | 23 | Dynamic debug has even more useful features: |
24 | 24 | ||
@@ -197,8 +197,8 @@ line | |||
197 | line number matches the callsite line number exactly. A | 197 | line number matches the callsite line number exactly. A |
198 | range of line numbers matches any callsite between the first | 198 | range of line numbers matches any callsite between the first |
199 | and last line number inclusive. An empty first number means | 199 | and last line number inclusive. An empty first number means |
200 | the first line in the file, an empty line number means the | 200 | the first line in the file, an empty last line number means the |
201 | last number in the file. Examples:: | 201 | last line number in the file. Examples:: |
202 | 202 | ||
203 | line 1603 // exactly line 1603 | 203 | line 1603 // exactly line 1603 |
204 | line 1600-1605 // the six lines from line 1600 to line 1605 | 204 | line 1600-1605 // the six lines from line 1600 to line 1605 |
diff --git a/Documentation/clearing-warn-once.txt b/Documentation/clearing-warn-once.txt new file mode 100644 index 000000000000..5b1f5d547be1 --- /dev/null +++ b/Documentation/clearing-warn-once.txt | |||
@@ -0,0 +1,7 @@ | |||
1 | |||
2 | WARN_ONCE / WARN_ON_ONCE only print a warning once. | ||
3 | |||
4 | echo 1 > /sys/kernel/debug/clear_warn_once | ||
5 | |||
6 | clears the state and allows the warnings to print once again. | ||
7 | This can be useful after test suite runs to reproduce problems. | ||
diff --git a/Documentation/dev-tools/kcov.rst b/Documentation/dev-tools/kcov.rst index 44886c91e112..c2f6452e38ed 100644 --- a/Documentation/dev-tools/kcov.rst +++ b/Documentation/dev-tools/kcov.rst | |||
@@ -12,19 +12,30 @@ To achieve this goal it does not collect coverage in soft/hard interrupts | |||
12 | and instrumentation of some inherently non-deterministic parts of kernel is | 12 | and instrumentation of some inherently non-deterministic parts of kernel is |
13 | disabled (e.g. scheduler, locking). | 13 | disabled (e.g. scheduler, locking). |
14 | 14 | ||
15 | Usage | 15 | kcov is also able to collect comparison operands from the instrumented code |
16 | ----- | 16 | (this feature currently requires that the kernel is compiled with clang). |
17 | |||
18 | Prerequisites | ||
19 | ------------- | ||
17 | 20 | ||
18 | Configure the kernel with:: | 21 | Configure the kernel with:: |
19 | 22 | ||
20 | CONFIG_KCOV=y | 23 | CONFIG_KCOV=y |
21 | 24 | ||
22 | CONFIG_KCOV requires gcc built on revision 231296 or later. | 25 | CONFIG_KCOV requires gcc built on revision 231296 or later. |
26 | |||
27 | If the comparison operands need to be collected, set:: | ||
28 | |||
29 | CONFIG_KCOV_ENABLE_COMPARISONS=y | ||
30 | |||
23 | Profiling data will only become accessible once debugfs has been mounted:: | 31 | Profiling data will only become accessible once debugfs has been mounted:: |
24 | 32 | ||
25 | mount -t debugfs none /sys/kernel/debug | 33 | mount -t debugfs none /sys/kernel/debug |
26 | 34 | ||
27 | The following program demonstrates kcov usage from within a test program: | 35 | Coverage collection |
36 | ------------------- | ||
37 | The following program demonstrates coverage collection from within a test | ||
38 | program using kcov: | ||
28 | 39 | ||
29 | .. code-block:: c | 40 | .. code-block:: c |
30 | 41 | ||
@@ -44,6 +55,9 @@ The following program demonstrates kcov usage from within a test program: | |||
44 | #define KCOV_DISABLE _IO('c', 101) | 55 | #define KCOV_DISABLE _IO('c', 101) |
45 | #define COVER_SIZE (64<<10) | 56 | #define COVER_SIZE (64<<10) |
46 | 57 | ||
58 | #define KCOV_TRACE_PC 0 | ||
59 | #define KCOV_TRACE_CMP 1 | ||
60 | |||
47 | int main(int argc, char **argv) | 61 | int main(int argc, char **argv) |
48 | { | 62 | { |
49 | int fd; | 63 | int fd; |
@@ -64,7 +78,7 @@ The following program demonstrates kcov usage from within a test program: | |||
64 | if ((void*)cover == MAP_FAILED) | 78 | if ((void*)cover == MAP_FAILED) |
65 | perror("mmap"), exit(1); | 79 | perror("mmap"), exit(1); |
66 | /* Enable coverage collection on the current thread. */ | 80 | /* Enable coverage collection on the current thread. */ |
67 | if (ioctl(fd, KCOV_ENABLE, 0)) | 81 | if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_PC)) |
68 | perror("ioctl"), exit(1); | 82 | perror("ioctl"), exit(1); |
69 | /* Reset coverage from the tail of the ioctl() call. */ | 83 | /* Reset coverage from the tail of the ioctl() call. */ |
70 | __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); | 84 | __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); |
@@ -111,3 +125,80 @@ The interface is fine-grained to allow efficient forking of test processes. | |||
111 | That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode, | 125 | That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode, |
112 | mmaps coverage buffer and then forks child processes in a loop. Child processes | 126 | mmaps coverage buffer and then forks child processes in a loop. Child processes |
113 | only need to enable coverage (disable happens automatically on thread end). | 127 | only need to enable coverage (disable happens automatically on thread end). |
128 | |||
129 | Comparison operands collection | ||
130 | ------------------------------ | ||
131 | Comparison operands collection is similar to coverage collection: | ||
132 | |||
133 | .. code-block:: c | ||
134 | |||
135 | /* Same includes and defines as above. */ | ||
136 | |||
137 | /* Number of 64-bit words per record. */ | ||
138 | #define KCOV_WORDS_PER_CMP 4 | ||
139 | |||
140 | /* | ||
141 | * The format for the types of collected comparisons. | ||
142 | * | ||
143 | * Bit 0 shows whether one of the arguments is a compile-time constant. | ||
144 | * Bits 1 & 2 contain log2 of the argument size, up to 8 bytes. | ||
145 | */ | ||
146 | |||
147 | #define KCOV_CMP_CONST (1 << 0) | ||
148 | #define KCOV_CMP_SIZE(n) ((n) << 1) | ||
149 | #define KCOV_CMP_MASK KCOV_CMP_SIZE(3) | ||
150 | |||
151 | int main(int argc, char **argv) | ||
152 | { | ||
153 | int fd; | ||
154 | uint64_t *cover, type, arg1, arg2, is_const, size; | ||
155 | unsigned long n, i; | ||
156 | |||
157 | fd = open("/sys/kernel/debug/kcov", O_RDWR); | ||
158 | if (fd == -1) | ||
159 | perror("open"), exit(1); | ||
160 | if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE)) | ||
161 | perror("ioctl"), exit(1); | ||
162 | /* | ||
163 | * Note that the buffer pointer is of type uint64_t*, because all | ||
164 | * the comparison operands are promoted to uint64_t. | ||
165 | */ | ||
166 | cover = (uint64_t *)mmap(NULL, COVER_SIZE * sizeof(unsigned long), | ||
167 | PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||
168 | if ((void*)cover == MAP_FAILED) | ||
169 | perror("mmap"), exit(1); | ||
170 | /* Note KCOV_TRACE_CMP instead of KCOV_TRACE_PC. */ | ||
171 | if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_CMP)) | ||
172 | perror("ioctl"), exit(1); | ||
173 | __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); | ||
174 | read(-1, NULL, 0); | ||
175 | /* Read number of comparisons collected. */ | ||
176 | n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED); | ||
177 | for (i = 0; i < n; i++) { | ||
178 | type = cover[i * KCOV_WORDS_PER_CMP + 1]; | ||
179 | /* arg1 and arg2 - operands of the comparison. */ | ||
180 | arg1 = cover[i * KCOV_WORDS_PER_CMP + 2]; | ||
181 | arg2 = cover[i * KCOV_WORDS_PER_CMP + 3]; | ||
182 | /* ip - caller address. */ | ||
183 | ip = cover[i * KCOV_WORDS_PER_CMP + 4]; | ||
184 | /* size of the operands. */ | ||
185 | size = 1 << ((type & KCOV_CMP_MASK) >> 1); | ||
186 | /* is_const - true if either operand is a compile-time constant.*/ | ||
187 | is_const = type & KCOV_CMP_CONST; | ||
188 | printf("ip: 0x%lx type: 0x%lx, arg1: 0x%lx, arg2: 0x%lx, " | ||
189 | "size: %lu, %s\n", | ||
190 | ip, type, arg1, arg2, size, | ||
191 | is_const ? "const" : "non-const"); | ||
192 | } | ||
193 | if (ioctl(fd, KCOV_DISABLE, 0)) | ||
194 | perror("ioctl"), exit(1); | ||
195 | /* Free resources. */ | ||
196 | if (munmap(cover, COVER_SIZE * sizeof(unsigned long))) | ||
197 | perror("munmap"), exit(1); | ||
198 | if (close(fd)) | ||
199 | perror("close"), exit(1); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | Note that the kcov modes (coverage collection or comparison operands) are | ||
204 | mutually exclusive. | ||
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index ec571b9bb18a..2a84bb334894 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -181,6 +181,7 @@ read the file /proc/PID/status: | |||
181 | VmPTE: 20 kb | 181 | VmPTE: 20 kb |
182 | VmSwap: 0 kB | 182 | VmSwap: 0 kB |
183 | HugetlbPages: 0 kB | 183 | HugetlbPages: 0 kB |
184 | CoreDumping: 0 | ||
184 | Threads: 1 | 185 | Threads: 1 |
185 | SigQ: 0/28578 | 186 | SigQ: 0/28578 |
186 | SigPnd: 0000000000000000 | 187 | SigPnd: 0000000000000000 |
@@ -253,6 +254,8 @@ Table 1-2: Contents of the status files (as of 4.8) | |||
253 | VmSwap amount of swap used by anonymous private data | 254 | VmSwap amount of swap used by anonymous private data |
254 | (shmem swap usage is not included) | 255 | (shmem swap usage is not included) |
255 | HugetlbPages size of hugetlb memory portions | 256 | HugetlbPages size of hugetlb memory portions |
257 | CoreDumping process's memory is currently being dumped | ||
258 | (killing the process may lead to a corrupted core) | ||
256 | Threads number of threads | 259 | Threads number of threads |
257 | SigQ number of signals queued/max. number for queue | 260 | SigQ number of signals queued/max. number for queue |
258 | SigPnd bitmap of pending signals for the thread | 261 | SigPnd bitmap of pending signals for the thread |
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 055c8b3e1018..b920423f88cb 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -818,7 +818,7 @@ tooling to work, you can do: | |||
818 | swappiness | 818 | swappiness |
819 | 819 | ||
820 | This control is used to define how aggressive the kernel will swap | 820 | This control is used to define how aggressive the kernel will swap |
821 | memory pages. Higher values will increase agressiveness, lower values | 821 | memory pages. Higher values will increase aggressiveness, lower values |
822 | decrease the amount of swap. A value of 0 instructs the kernel not to | 822 | decrease the amount of swap. A value of 0 instructs the kernel not to |
823 | initiate swap until the amount of free and file-backed pages is less | 823 | initiate swap until the amount of free and file-backed pages is less |
824 | than the high water mark in a zone. | 824 | than the high water mark in a zone. |
@@ -375,8 +375,6 @@ CFLAGS_KERNEL = | |||
375 | AFLAGS_KERNEL = | 375 | AFLAGS_KERNEL = |
376 | LDFLAGS_vmlinux = | 376 | LDFLAGS_vmlinux = |
377 | CFLAGS_GCOV := -fprofile-arcs -ftest-coverage -fno-tree-loop-im $(call cc-disable-warning,maybe-uninitialized,) | 377 | CFLAGS_GCOV := -fprofile-arcs -ftest-coverage -fno-tree-loop-im $(call cc-disable-warning,maybe-uninitialized,) |
378 | CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) | ||
379 | |||
380 | 378 | ||
381 | # Use USERINCLUDE when you must reference the UAPI directories only. | 379 | # Use USERINCLUDE when you must reference the UAPI directories only. |
382 | USERINCLUDE := \ | 380 | USERINCLUDE := \ |
@@ -659,6 +657,7 @@ ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLA | |||
659 | KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO | 657 | KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO |
660 | endif | 658 | endif |
661 | 659 | ||
660 | include scripts/Makefile.kcov | ||
662 | include scripts/Makefile.gcc-plugins | 661 | include scripts/Makefile.gcc-plugins |
663 | 662 | ||
664 | ifdef CONFIG_READABLE_ASM | 663 | ifdef CONFIG_READABLE_ASM |
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index 3ad8f6988363..82f9bf702804 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h | |||
@@ -34,13 +34,6 @@ | |||
34 | &node_to_cpu_mask[node]) | 34 | &node_to_cpu_mask[node]) |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * Returns the number of the node containing Node 'nid'. | ||
38 | * Not implemented here. Multi-level hierarchies detected with | ||
39 | * the help of node_distance(). | ||
40 | */ | ||
41 | #define parent_node(nid) (nid) | ||
42 | |||
43 | /* | ||
44 | * Determines the node for a given pci bus | 37 | * Determines the node for a given pci bus |
45 | */ | 38 | */ |
46 | #define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node | 39 | #define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node |
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index f7693f49c573..f4db2168d1b8 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c | |||
@@ -31,8 +31,8 @@ void foo(void) | |||
31 | DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe)); | 31 | DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe)); |
32 | DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info)); | 32 | DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info)); |
33 | 33 | ||
34 | BUILD_BUG_ON(sizeof(struct upid) != 32); | 34 | BUILD_BUG_ON(sizeof(struct upid) != 16); |
35 | DEFINE(IA64_UPID_SHIFT, 5); | 35 | DEFINE(IA64_UPID_SHIFT, 4); |
36 | 36 | ||
37 | BLANK(); | 37 | BLANK(); |
38 | 38 | ||
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c index f23781d6bbb3..f0bfa1448744 100644 --- a/arch/mn10300/mm/fault.c +++ b/arch/mn10300/mm/fault.c | |||
@@ -60,7 +60,7 @@ void bust_spinlocks(int yes) | |||
60 | void do_BUG(const char *file, int line) | 60 | void do_BUG(const char *file, int line) |
61 | { | 61 | { |
62 | bust_spinlocks(1); | 62 | bust_spinlocks(1); |
63 | printk(KERN_EMERG "------------[ cut here ]------------\n"); | 63 | printk(KERN_EMERG CUT_HERE); |
64 | printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); | 64 | printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); |
65 | } | 65 | } |
66 | 66 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 1fbb5da17dd2..e47761cdcb98 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private) | |||
1093 | LOAD_INT(c), LOAD_FRAC(c), | 1093 | LOAD_INT(c), LOAD_FRAC(c), |
1094 | count_active_contexts(), | 1094 | count_active_contexts(), |
1095 | atomic_read(&nr_spu_contexts), | 1095 | atomic_read(&nr_spu_contexts), |
1096 | task_active_pid_ns(current)->last_pid); | 1096 | idr_get_cursor(&task_active_pid_ns(current)->idr)); |
1097 | return 0; | 1097 | return 0; |
1098 | } | 1098 | } |
1099 | 1099 | ||
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index f2d9d3079d4e..627ce8e75e01 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c | |||
@@ -104,6 +104,18 @@ static void error(char *x) | |||
104 | while(1); /* Halt */ | 104 | while(1); /* Halt */ |
105 | } | 105 | } |
106 | 106 | ||
107 | unsigned long __stack_chk_guard; | ||
108 | |||
109 | void __stack_chk_guard_setup(void) | ||
110 | { | ||
111 | __stack_chk_guard = 0x000a0dff; | ||
112 | } | ||
113 | |||
114 | void __stack_chk_fail(void) | ||
115 | { | ||
116 | error("stack-protector: Kernel stack is corrupted\n"); | ||
117 | } | ||
118 | |||
107 | #ifdef CONFIG_SUPERH64 | 119 | #ifdef CONFIG_SUPERH64 |
108 | #define stackalign 8 | 120 | #define stackalign 8 |
109 | #else | 121 | #else |
@@ -118,6 +130,8 @@ void decompress_kernel(void) | |||
118 | { | 130 | { |
119 | unsigned long output_addr; | 131 | unsigned long output_addr; |
120 | 132 | ||
133 | __stack_chk_guard_setup(); | ||
134 | |||
121 | #ifdef CONFIG_SUPERH64 | 135 | #ifdef CONFIG_SUPERH64 |
122 | output_addr = (CONFIG_MEMORY_START + 0x2000); | 136 | output_addr = (CONFIG_MEMORY_START + 0x2000); |
123 | #else | 137 | #else |
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index 9a32eb4098df..1db470e02456 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #ifdef CONFIG_NUMA | 5 | #ifdef CONFIG_NUMA |
6 | 6 | ||
7 | #define cpu_to_node(cpu) ((void)(cpu),0) | 7 | #define cpu_to_node(cpu) ((void)(cpu),0) |
8 | #define parent_node(node) ((void)(node),0) | ||
9 | 8 | ||
10 | #define cpumask_of_node(node) ((void)node, cpu_online_mask) | 9 | #define cpumask_of_node(node) ((void)node, cpu_online_mask) |
11 | 10 | ||
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index 3831b1911a19..34c628a22ea5 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h | |||
@@ -11,8 +11,6 @@ static inline int cpu_to_node(int cpu) | |||
11 | return numa_cpu_lookup_table[cpu]; | 11 | return numa_cpu_lookup_table[cpu]; |
12 | } | 12 | } |
13 | 13 | ||
14 | #define parent_node(node) (node) | ||
15 | |||
16 | #define cpumask_of_node(node) ((node) == -1 ? \ | 14 | #define cpumask_of_node(node) ((node) == -1 ? \ |
17 | cpu_all_mask : \ | 15 | cpu_all_mask : \ |
18 | &numa_cpumask_lookup_table[node]) | 16 | &numa_cpumask_lookup_table[node]) |
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h index b11d5fcd2c41..635a0a4596f0 100644 --- a/arch/tile/include/asm/topology.h +++ b/arch/tile/include/asm/topology.h | |||
@@ -29,12 +29,6 @@ static inline int cpu_to_node(int cpu) | |||
29 | return cpu_2_node[cpu]; | 29 | return cpu_2_node[cpu]; |
30 | } | 30 | } |
31 | 31 | ||
32 | /* | ||
33 | * Returns the number of the node containing Node 'node'. | ||
34 | * This architecture is flat, so it is a pretty simple function! | ||
35 | */ | ||
36 | #define parent_node(node) (node) | ||
37 | |||
38 | /* Returns a bitmask of CPUs on Node 'node'. */ | 32 | /* Returns a bitmask of CPUs on Node 'node'. */ |
39 | static inline const struct cpumask *cpumask_of_node(int node) | 33 | static inline const struct cpumask *cpumask_of_node(int node) |
40 | { | 34 | { |
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index b0f7af872bb5..7eebbdfbcacd 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c | |||
@@ -63,9 +63,11 @@ void lkdtm_BUG(void) | |||
63 | BUG(); | 63 | BUG(); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int warn_counter; | ||
67 | |||
66 | void lkdtm_WARNING(void) | 68 | void lkdtm_WARNING(void) |
67 | { | 69 | { |
68 | WARN_ON(1); | 70 | WARN(1, "Warning message trigger count: %d\n", warn_counter++); |
69 | } | 71 | } |
70 | 72 | ||
71 | void lkdtm_EXCEPTION(void) | 73 | void lkdtm_EXCEPTION(void) |
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c index 2f490930430d..93a5c7423d80 100644 --- a/drivers/pcmcia/sa1111_badge4.c +++ b/drivers/pcmcia/sa1111_badge4.c | |||
@@ -144,6 +144,7 @@ int pcmcia_badge4_init(struct sa1111_dev *dev) | |||
144 | sa11xx_drv_pcmcia_add_one); | 144 | sa11xx_drv_pcmcia_add_one); |
145 | } | 145 | } |
146 | 146 | ||
147 | #ifndef MODULE | ||
147 | static int __init pcmv_setup(char *s) | 148 | static int __init pcmv_setup(char *s) |
148 | { | 149 | { |
149 | int v[4]; | 150 | int v[4]; |
@@ -158,3 +159,4 @@ static int __init pcmv_setup(char *s) | |||
158 | } | 159 | } |
159 | 160 | ||
160 | __setup("pcmv=", pcmv_setup); | 161 | __setup("pcmv=", pcmv_setup); |
162 | #endif | ||
diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 665d9e94a7e1..ec4bc1515f0d 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c | |||
@@ -959,9 +959,10 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, | |||
959 | 959 | ||
960 | nents = dma_map_sg(chan->device->dev, | 960 | nents = dma_map_sg(chan->device->dev, |
961 | req->sgt.sgl, req->sgt.nents, dir); | 961 | req->sgt.sgl, req->sgt.nents, dir); |
962 | if (nents == -EFAULT) { | 962 | if (nents == 0) { |
963 | rmcd_error("Failed to map SG list"); | 963 | rmcd_error("Failed to map SG list"); |
964 | return -EFAULT; | 964 | ret = -EFAULT; |
965 | goto err_pg; | ||
965 | } | 966 | } |
966 | 967 | ||
967 | ret = do_dma_request(req, xfer, sync, nents); | 968 | ret = do_dma_request(req, xfer, sync, nents); |
diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c index e67b923b1ca6..4931ed790428 100644 --- a/drivers/rapidio/switches/idt_gen2.c +++ b/drivers/rapidio/switches/idt_gen2.c | |||
@@ -458,7 +458,7 @@ static void idtg2_remove(struct rio_dev *rdev) | |||
458 | idtg2_sysfs(rdev, false); | 458 | idtg2_sysfs(rdev, false); |
459 | } | 459 | } |
460 | 460 | ||
461 | static struct rio_device_id idtg2_id_table[] = { | 461 | static const struct rio_device_id idtg2_id_table[] = { |
462 | {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)}, | 462 | {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)}, |
463 | {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)}, | 463 | {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)}, |
464 | {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)}, | 464 | {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)}, |
diff --git a/drivers/rapidio/switches/idt_gen3.c b/drivers/rapidio/switches/idt_gen3.c index c5923a547bed..85a3908294d9 100644 --- a/drivers/rapidio/switches/idt_gen3.c +++ b/drivers/rapidio/switches/idt_gen3.c | |||
@@ -348,7 +348,7 @@ static void idtg3_shutdown(struct rio_dev *rdev) | |||
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | static struct rio_device_id idtg3_id_table[] = { | 351 | static const struct rio_device_id idtg3_id_table[] = { |
352 | {RIO_DEVICE(RIO_DID_IDTRXS1632, RIO_VID_IDT)}, | 352 | {RIO_DEVICE(RIO_DID_IDTRXS1632, RIO_VID_IDT)}, |
353 | {RIO_DEVICE(RIO_DID_IDTRXS2448, RIO_VID_IDT)}, | 353 | {RIO_DEVICE(RIO_DID_IDTRXS2448, RIO_VID_IDT)}, |
354 | { 0, } /* terminate list */ | 354 | { 0, } /* terminate list */ |
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index 7fbb60d31796..4058ce2c76fa 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c | |||
@@ -168,7 +168,7 @@ static void idtcps_remove(struct rio_dev *rdev) | |||
168 | spin_unlock(&rdev->rswitch->lock); | 168 | spin_unlock(&rdev->rswitch->lock); |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct rio_device_id idtcps_id_table[] = { | 171 | static const struct rio_device_id idtcps_id_table[] = { |
172 | {RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)}, | 172 | {RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)}, |
173 | {RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)}, | 173 | {RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)}, |
174 | {RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)}, | 174 | {RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)}, |
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index 8a43561b9d17..1214628b7ded 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c | |||
@@ -169,7 +169,7 @@ static void tsi568_remove(struct rio_dev *rdev) | |||
169 | spin_unlock(&rdev->rswitch->lock); | 169 | spin_unlock(&rdev->rswitch->lock); |
170 | } | 170 | } |
171 | 171 | ||
172 | static struct rio_device_id tsi568_id_table[] = { | 172 | static const struct rio_device_id tsi568_id_table[] = { |
173 | {RIO_DEVICE(RIO_DID_TSI568, RIO_VID_TUNDRA)}, | 173 | {RIO_DEVICE(RIO_DID_TSI568, RIO_VID_TUNDRA)}, |
174 | { 0, } /* terminate list */ | 174 | { 0, } /* terminate list */ |
175 | }; | 175 | }; |
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 2700d15f7584..9f063e214836 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c | |||
@@ -336,7 +336,7 @@ static void tsi57x_remove(struct rio_dev *rdev) | |||
336 | spin_unlock(&rdev->rswitch->lock); | 336 | spin_unlock(&rdev->rswitch->lock); |
337 | } | 337 | } |
338 | 338 | ||
339 | static struct rio_device_id tsi57x_id_table[] = { | 339 | static const struct rio_device_id tsi57x_id_table[] = { |
340 | {RIO_DEVICE(RIO_DID_TSI572, RIO_VID_TUNDRA)}, | 340 | {RIO_DEVICE(RIO_DID_TSI572, RIO_VID_TUNDRA)}, |
341 | {RIO_DEVICE(RIO_DID_TSI574, RIO_VID_TUNDRA)}, | 341 | {RIO_DEVICE(RIO_DID_TSI574, RIO_VID_TUNDRA)}, |
342 | {RIO_DEVICE(RIO_DID_TSI577, RIO_VID_TUNDRA)}, | 342 | {RIO_DEVICE(RIO_DID_TSI577, RIO_VID_TUNDRA)}, |
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 74265b2f806c..8a8d952f8df9 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c | |||
@@ -137,25 +137,6 @@ int watchdog_init_timeout(struct watchdog_device *wdd, | |||
137 | } | 137 | } |
138 | EXPORT_SYMBOL_GPL(watchdog_init_timeout); | 138 | EXPORT_SYMBOL_GPL(watchdog_init_timeout); |
139 | 139 | ||
140 | static int watchdog_reboot_notifier(struct notifier_block *nb, | ||
141 | unsigned long code, void *data) | ||
142 | { | ||
143 | struct watchdog_device *wdd = container_of(nb, struct watchdog_device, | ||
144 | reboot_nb); | ||
145 | |||
146 | if (code == SYS_DOWN || code == SYS_HALT) { | ||
147 | if (watchdog_active(wdd)) { | ||
148 | int ret; | ||
149 | |||
150 | ret = wdd->ops->stop(wdd); | ||
151 | if (ret) | ||
152 | return NOTIFY_BAD; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | return NOTIFY_DONE; | ||
157 | } | ||
158 | |||
159 | static int watchdog_restart_notifier(struct notifier_block *nb, | 140 | static int watchdog_restart_notifier(struct notifier_block *nb, |
160 | unsigned long action, void *data) | 141 | unsigned long action, void *data) |
161 | { | 142 | { |
@@ -244,19 +225,6 @@ static int __watchdog_register_device(struct watchdog_device *wdd) | |||
244 | } | 225 | } |
245 | } | 226 | } |
246 | 227 | ||
247 | if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) { | ||
248 | wdd->reboot_nb.notifier_call = watchdog_reboot_notifier; | ||
249 | |||
250 | ret = register_reboot_notifier(&wdd->reboot_nb); | ||
251 | if (ret) { | ||
252 | pr_err("watchdog%d: Cannot register reboot notifier (%d)\n", | ||
253 | wdd->id, ret); | ||
254 | watchdog_dev_unregister(wdd); | ||
255 | ida_simple_remove(&watchdog_ida, wdd->id); | ||
256 | return ret; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | if (wdd->ops->restart) { | 228 | if (wdd->ops->restart) { |
261 | wdd->restart_nb.notifier_call = watchdog_restart_notifier; | 229 | wdd->restart_nb.notifier_call = watchdog_restart_notifier; |
262 | 230 | ||
@@ -302,9 +270,6 @@ static void __watchdog_unregister_device(struct watchdog_device *wdd) | |||
302 | if (wdd->ops->restart) | 270 | if (wdd->ops->restart) |
303 | unregister_restart_handler(&wdd->restart_nb); | 271 | unregister_restart_handler(&wdd->restart_nb); |
304 | 272 | ||
305 | if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) | ||
306 | unregister_reboot_notifier(&wdd->reboot_nb); | ||
307 | |||
308 | watchdog_dev_unregister(wdd); | 273 | watchdog_dev_unregister(wdd); |
309 | ida_simple_remove(&watchdog_ida, wdd->id); | 274 | ida_simple_remove(&watchdog_ida, wdd->id); |
310 | } | 275 | } |
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 0826e663bd5a..1e971a50d7fb 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/miscdevice.h> /* For handling misc devices */ | 42 | #include <linux/miscdevice.h> /* For handling misc devices */ |
43 | #include <linux/module.h> /* For module stuff/... */ | 43 | #include <linux/module.h> /* For module stuff/... */ |
44 | #include <linux/mutex.h> /* For mutexes */ | 44 | #include <linux/mutex.h> /* For mutexes */ |
45 | #include <linux/reboot.h> /* For reboot notifier */ | ||
45 | #include <linux/slab.h> /* For memory functions */ | 46 | #include <linux/slab.h> /* For memory functions */ |
46 | #include <linux/types.h> /* For standard types (like size_t) */ | 47 | #include <linux/types.h> /* For standard types (like size_t) */ |
47 | #include <linux/watchdog.h> /* For watchdog specific items */ | 48 | #include <linux/watchdog.h> /* For watchdog specific items */ |
@@ -1016,6 +1017,25 @@ static struct class watchdog_class = { | |||
1016 | .dev_groups = wdt_groups, | 1017 | .dev_groups = wdt_groups, |
1017 | }; | 1018 | }; |
1018 | 1019 | ||
1020 | static int watchdog_reboot_notifier(struct notifier_block *nb, | ||
1021 | unsigned long code, void *data) | ||
1022 | { | ||
1023 | struct watchdog_device *wdd; | ||
1024 | |||
1025 | wdd = container_of(nb, struct watchdog_device, reboot_nb); | ||
1026 | if (code == SYS_DOWN || code == SYS_HALT) { | ||
1027 | if (watchdog_active(wdd)) { | ||
1028 | int ret; | ||
1029 | |||
1030 | ret = wdd->ops->stop(wdd); | ||
1031 | if (ret) | ||
1032 | return NOTIFY_BAD; | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | return NOTIFY_DONE; | ||
1037 | } | ||
1038 | |||
1019 | /* | 1039 | /* |
1020 | * watchdog_dev_register: register a watchdog device | 1040 | * watchdog_dev_register: register a watchdog device |
1021 | * @wdd: watchdog device | 1041 | * @wdd: watchdog device |
@@ -1049,6 +1069,18 @@ int watchdog_dev_register(struct watchdog_device *wdd) | |||
1049 | if (ret) { | 1069 | if (ret) { |
1050 | device_destroy(&watchdog_class, devno); | 1070 | device_destroy(&watchdog_class, devno); |
1051 | watchdog_cdev_unregister(wdd); | 1071 | watchdog_cdev_unregister(wdd); |
1072 | return ret; | ||
1073 | } | ||
1074 | |||
1075 | if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) { | ||
1076 | wdd->reboot_nb.notifier_call = watchdog_reboot_notifier; | ||
1077 | |||
1078 | ret = devm_register_reboot_notifier(dev, &wdd->reboot_nb); | ||
1079 | if (ret) { | ||
1080 | pr_err("watchdog%d: Cannot register reboot notifier (%d)\n", | ||
1081 | wdd->id, ret); | ||
1082 | watchdog_dev_unregister(wdd); | ||
1083 | } | ||
1052 | } | 1084 | } |
1053 | 1085 | ||
1054 | return ret; | 1086 | return ret; |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 4ac49d038bf3..8fc41705c7cd 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -81,7 +81,8 @@ static int autofs4_write(struct autofs_sb_info *sbi, | |||
81 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | 81 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
82 | } | 82 | } |
83 | 83 | ||
84 | return (bytes > 0); | 84 | /* if 'wr' returned 0 (impossible) we assume -EIO (safe) */ |
85 | return bytes == 0 ? 0 : wr < 0 ? wr : -EIO; | ||
85 | } | 86 | } |
86 | 87 | ||
87 | static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | 88 | static void autofs4_notify_daemon(struct autofs_sb_info *sbi, |
@@ -95,6 +96,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
95 | } pkt; | 96 | } pkt; |
96 | struct file *pipe = NULL; | 97 | struct file *pipe = NULL; |
97 | size_t pktsz; | 98 | size_t pktsz; |
99 | int ret; | ||
98 | 100 | ||
99 | pr_debug("wait id = 0x%08lx, name = %.*s, type=%d\n", | 101 | pr_debug("wait id = 0x%08lx, name = %.*s, type=%d\n", |
100 | (unsigned long) wq->wait_queue_token, | 102 | (unsigned long) wq->wait_queue_token, |
@@ -169,7 +171,18 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
169 | mutex_unlock(&sbi->wq_mutex); | 171 | mutex_unlock(&sbi->wq_mutex); |
170 | 172 | ||
171 | if (autofs4_write(sbi, pipe, &pkt, pktsz)) | 173 | if (autofs4_write(sbi, pipe, &pkt, pktsz)) |
174 | switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) { | ||
175 | case 0: | ||
176 | break; | ||
177 | case -ENOMEM: | ||
178 | case -ERESTARTSYS: | ||
179 | /* Just fail this one */ | ||
180 | autofs4_wait_release(sbi, wq->wait_queue_token, ret); | ||
181 | break; | ||
182 | default: | ||
172 | autofs4_catatonic_mode(sbi); | 183 | autofs4_catatonic_mode(sbi); |
184 | break; | ||
185 | } | ||
173 | fput(pipe); | 186 | fput(pipe); |
174 | } | 187 | } |
175 | 188 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 396a3c075fd4..afd548ebc328 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -276,12 +276,6 @@ static DEFINE_MUTEX(epmutex); | |||
276 | /* Used to check for epoll file descriptor inclusion loops */ | 276 | /* Used to check for epoll file descriptor inclusion loops */ |
277 | static struct nested_calls poll_loop_ncalls; | 277 | static struct nested_calls poll_loop_ncalls; |
278 | 278 | ||
279 | /* Used for safe wake up implementation */ | ||
280 | static struct nested_calls poll_safewake_ncalls; | ||
281 | |||
282 | /* Used to call file's f_op->poll() under the nested calls boundaries */ | ||
283 | static struct nested_calls poll_readywalk_ncalls; | ||
284 | |||
285 | /* Slab cache used to allocate "struct epitem" */ | 279 | /* Slab cache used to allocate "struct epitem" */ |
286 | static struct kmem_cache *epi_cache __read_mostly; | 280 | static struct kmem_cache *epi_cache __read_mostly; |
287 | 281 | ||
@@ -551,40 +545,21 @@ out_unlock: | |||
551 | * this special case of epoll. | 545 | * this special case of epoll. |
552 | */ | 546 | */ |
553 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 547 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
554 | static inline void ep_wake_up_nested(wait_queue_head_t *wqueue, | 548 | |
555 | unsigned long events, int subclass) | 549 | static struct nested_calls poll_safewake_ncalls; |
550 | |||
551 | static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests) | ||
556 | { | 552 | { |
557 | unsigned long flags; | 553 | unsigned long flags; |
554 | wait_queue_head_t *wqueue = (wait_queue_head_t *)cookie; | ||
558 | 555 | ||
559 | spin_lock_irqsave_nested(&wqueue->lock, flags, subclass); | 556 | spin_lock_irqsave_nested(&wqueue->lock, flags, call_nests + 1); |
560 | wake_up_locked_poll(wqueue, events); | 557 | wake_up_locked_poll(wqueue, POLLIN); |
561 | spin_unlock_irqrestore(&wqueue->lock, flags); | 558 | spin_unlock_irqrestore(&wqueue->lock, flags); |
562 | } | ||
563 | #else | ||
564 | static inline void ep_wake_up_nested(wait_queue_head_t *wqueue, | ||
565 | unsigned long events, int subclass) | ||
566 | { | ||
567 | wake_up_poll(wqueue, events); | ||
568 | } | ||
569 | #endif | ||
570 | 559 | ||
571 | static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests) | ||
572 | { | ||
573 | ep_wake_up_nested((wait_queue_head_t *) cookie, POLLIN, | ||
574 | 1 + call_nests); | ||
575 | return 0; | 560 | return 0; |
576 | } | 561 | } |
577 | 562 | ||
578 | /* | ||
579 | * Perform a safe wake up of the poll wait list. The problem is that | ||
580 | * with the new callback'd wake up system, it is possible that the | ||
581 | * poll callback is reentered from inside the call to wake_up() done | ||
582 | * on the poll wait queue head. The rule is that we cannot reenter the | ||
583 | * wake up code from the same task more than EP_MAX_NESTS times, | ||
584 | * and we cannot reenter the same wait queue head at all. This will | ||
585 | * enable to have a hierarchy of epoll file descriptor of no more than | ||
586 | * EP_MAX_NESTS deep. | ||
587 | */ | ||
588 | static void ep_poll_safewake(wait_queue_head_t *wq) | 563 | static void ep_poll_safewake(wait_queue_head_t *wq) |
589 | { | 564 | { |
590 | int this_cpu = get_cpu(); | 565 | int this_cpu = get_cpu(); |
@@ -595,6 +570,15 @@ static void ep_poll_safewake(wait_queue_head_t *wq) | |||
595 | put_cpu(); | 570 | put_cpu(); |
596 | } | 571 | } |
597 | 572 | ||
573 | #else | ||
574 | |||
575 | static void ep_poll_safewake(wait_queue_head_t *wq) | ||
576 | { | ||
577 | wake_up_poll(wq, POLLIN); | ||
578 | } | ||
579 | |||
580 | #endif | ||
581 | |||
598 | static void ep_remove_wait_queue(struct eppoll_entry *pwq) | 582 | static void ep_remove_wait_queue(struct eppoll_entry *pwq) |
599 | { | 583 | { |
600 | wait_queue_head_t *whead; | 584 | wait_queue_head_t *whead; |
@@ -880,11 +864,33 @@ static int ep_eventpoll_release(struct inode *inode, struct file *file) | |||
880 | return 0; | 864 | return 0; |
881 | } | 865 | } |
882 | 866 | ||
883 | static inline unsigned int ep_item_poll(struct epitem *epi, poll_table *pt) | 867 | static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, |
868 | void *priv); | ||
869 | static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, | ||
870 | poll_table *pt); | ||
871 | |||
872 | /* | ||
873 | * Differs from ep_eventpoll_poll() in that internal callers already have | ||
874 | * the ep->mtx so we need to start from depth=1, such that mutex_lock_nested() | ||
875 | * is correctly annotated. | ||
876 | */ | ||
877 | static unsigned int ep_item_poll(struct epitem *epi, poll_table *pt, int depth) | ||
884 | { | 878 | { |
879 | struct eventpoll *ep; | ||
880 | bool locked; | ||
881 | |||
885 | pt->_key = epi->event.events; | 882 | pt->_key = epi->event.events; |
883 | if (!is_file_epoll(epi->ffd.file)) | ||
884 | return epi->ffd.file->f_op->poll(epi->ffd.file, pt) & | ||
885 | epi->event.events; | ||
886 | |||
887 | ep = epi->ffd.file->private_data; | ||
888 | poll_wait(epi->ffd.file, &ep->poll_wait, pt); | ||
889 | locked = pt && (pt->_qproc == ep_ptable_queue_proc); | ||
886 | 890 | ||
887 | return epi->ffd.file->f_op->poll(epi->ffd.file, pt) & epi->event.events; | 891 | return ep_scan_ready_list(epi->ffd.file->private_data, |
892 | ep_read_events_proc, &depth, depth, | ||
893 | locked) & epi->event.events; | ||
888 | } | 894 | } |
889 | 895 | ||
890 | static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | 896 | static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, |
@@ -892,13 +898,15 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | |||
892 | { | 898 | { |
893 | struct epitem *epi, *tmp; | 899 | struct epitem *epi, *tmp; |
894 | poll_table pt; | 900 | poll_table pt; |
901 | int depth = *(int *)priv; | ||
895 | 902 | ||
896 | init_poll_funcptr(&pt, NULL); | 903 | init_poll_funcptr(&pt, NULL); |
904 | depth++; | ||
897 | 905 | ||
898 | list_for_each_entry_safe(epi, tmp, head, rdllink) { | 906 | list_for_each_entry_safe(epi, tmp, head, rdllink) { |
899 | if (ep_item_poll(epi, &pt)) | 907 | if (ep_item_poll(epi, &pt, depth)) { |
900 | return POLLIN | POLLRDNORM; | 908 | return POLLIN | POLLRDNORM; |
901 | else { | 909 | } else { |
902 | /* | 910 | /* |
903 | * Item has been dropped into the ready list by the poll | 911 | * Item has been dropped into the ready list by the poll |
904 | * callback, but it's not actually ready, as far as | 912 | * callback, but it's not actually ready, as far as |
@@ -912,48 +920,20 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head, | |||
912 | return 0; | 920 | return 0; |
913 | } | 921 | } |
914 | 922 | ||
915 | static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, | ||
916 | poll_table *pt); | ||
917 | |||
918 | struct readyevents_arg { | ||
919 | struct eventpoll *ep; | ||
920 | bool locked; | ||
921 | }; | ||
922 | |||
923 | static int ep_poll_readyevents_proc(void *priv, void *cookie, int call_nests) | ||
924 | { | ||
925 | struct readyevents_arg *arg = priv; | ||
926 | |||
927 | return ep_scan_ready_list(arg->ep, ep_read_events_proc, NULL, | ||
928 | call_nests + 1, arg->locked); | ||
929 | } | ||
930 | |||
931 | static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) | 923 | static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait) |
932 | { | 924 | { |
933 | int pollflags; | ||
934 | struct eventpoll *ep = file->private_data; | 925 | struct eventpoll *ep = file->private_data; |
935 | struct readyevents_arg arg; | 926 | int depth = 0; |
936 | |||
937 | /* | ||
938 | * During ep_insert() we already hold the ep->mtx for the tfile. | ||
939 | * Prevent re-aquisition. | ||
940 | */ | ||
941 | arg.locked = wait && (wait->_qproc == ep_ptable_queue_proc); | ||
942 | arg.ep = ep; | ||
943 | 927 | ||
944 | /* Insert inside our poll wait queue */ | 928 | /* Insert inside our poll wait queue */ |
945 | poll_wait(file, &ep->poll_wait, wait); | 929 | poll_wait(file, &ep->poll_wait, wait); |
946 | 930 | ||
947 | /* | 931 | /* |
948 | * Proceed to find out if wanted events are really available inside | 932 | * Proceed to find out if wanted events are really available inside |
949 | * the ready list. This need to be done under ep_call_nested() | 933 | * the ready list. |
950 | * supervision, since the call to f_op->poll() done on listed files | ||
951 | * could re-enter here. | ||
952 | */ | 934 | */ |
953 | pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS, | 935 | return ep_scan_ready_list(ep, ep_read_events_proc, |
954 | ep_poll_readyevents_proc, &arg, ep, current); | 936 | &depth, depth, false); |
955 | |||
956 | return pollflags != -1 ? pollflags : 0; | ||
957 | } | 937 | } |
958 | 938 | ||
959 | #ifdef CONFIG_PROC_FS | 939 | #ifdef CONFIG_PROC_FS |
@@ -1472,7 +1452,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1472 | * this operation completes, the poll callback can start hitting | 1452 | * this operation completes, the poll callback can start hitting |
1473 | * the new item. | 1453 | * the new item. |
1474 | */ | 1454 | */ |
1475 | revents = ep_item_poll(epi, &epq.pt); | 1455 | revents = ep_item_poll(epi, &epq.pt, 1); |
1476 | 1456 | ||
1477 | /* | 1457 | /* |
1478 | * We have to check if something went wrong during the poll wait queue | 1458 | * We have to check if something went wrong during the poll wait queue |
@@ -1606,7 +1586,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
1606 | * Get current event bits. We can safely use the file* here because | 1586 | * Get current event bits. We can safely use the file* here because |
1607 | * its usage count has been increased by the caller of this function. | 1587 | * its usage count has been increased by the caller of this function. |
1608 | */ | 1588 | */ |
1609 | revents = ep_item_poll(epi, &pt); | 1589 | revents = ep_item_poll(epi, &pt, 1); |
1610 | 1590 | ||
1611 | /* | 1591 | /* |
1612 | * If the item is "hot" and it is not registered inside the ready | 1592 | * If the item is "hot" and it is not registered inside the ready |
@@ -1674,7 +1654,7 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head, | |||
1674 | 1654 | ||
1675 | list_del_init(&epi->rdllink); | 1655 | list_del_init(&epi->rdllink); |
1676 | 1656 | ||
1677 | revents = ep_item_poll(epi, &pt); | 1657 | revents = ep_item_poll(epi, &pt, 1); |
1678 | 1658 | ||
1679 | /* | 1659 | /* |
1680 | * If the event mask intersect the caller-requested one, | 1660 | * If the event mask intersect the caller-requested one, |
@@ -2313,11 +2293,10 @@ static int __init eventpoll_init(void) | |||
2313 | */ | 2293 | */ |
2314 | ep_nested_calls_init(&poll_loop_ncalls); | 2294 | ep_nested_calls_init(&poll_loop_ncalls); |
2315 | 2295 | ||
2296 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
2316 | /* Initialize the structure used to perform safe poll wait head wake ups */ | 2297 | /* Initialize the structure used to perform safe poll wait head wake ups */ |
2317 | ep_nested_calls_init(&poll_safewake_ncalls); | 2298 | ep_nested_calls_init(&poll_safewake_ncalls); |
2318 | 2299 | #endif | |
2319 | /* Initialize the structure used to perform file's f_op->poll() calls */ | ||
2320 | ep_nested_calls_init(&poll_readywalk_ncalls); | ||
2321 | 2300 | ||
2322 | /* | 2301 | /* |
2323 | * We can have many thousands of epitems, so prevent this from | 2302 | * We can have many thousands of epitems, so prevent this from |
@@ -2327,11 +2306,11 @@ static int __init eventpoll_init(void) | |||
2327 | 2306 | ||
2328 | /* Allocates slab cache used to allocate "struct epitem" items */ | 2307 | /* Allocates slab cache used to allocate "struct epitem" items */ |
2329 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), | 2308 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), |
2330 | 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); | 2309 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL); |
2331 | 2310 | ||
2332 | /* Allocates slab cache used to allocate "struct eppoll_entry" */ | 2311 | /* Allocates slab cache used to allocate "struct eppoll_entry" */ |
2333 | pwq_cache = kmem_cache_create("eventpoll_pwq", | 2312 | pwq_cache = kmem_cache_create("eventpoll_pwq", |
2334 | sizeof(struct eppoll_entry), 0, SLAB_PANIC, NULL); | 2313 | sizeof(struct eppoll_entry), 0, SLAB_PANIC|SLAB_ACCOUNT, NULL); |
2335 | 2314 | ||
2336 | return 0; | 2315 | return 0; |
2337 | } | 2316 | } |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 81cecbe6d7cf..b833ffeee1e1 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -291,7 +291,6 @@ static int fat_parse_long(struct inode *dir, loff_t *pos, | |||
291 | } | 291 | } |
292 | } | 292 | } |
293 | parse_long: | 293 | parse_long: |
294 | slots = 0; | ||
295 | ds = (struct msdos_dir_slot *)*de; | 294 | ds = (struct msdos_dir_slot *)*de; |
296 | id = ds->id; | 295 | id = ds->id; |
297 | if (!(id & 0x40)) | 296 | if (!(id & 0x40)) |
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index 8aec5e732abf..b63a4df7327b 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c | |||
@@ -98,13 +98,11 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) | |||
98 | void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, | 98 | void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, |
99 | struct hfs_bnode *src_node, int src, int len) | 99 | struct hfs_bnode *src_node, int src, int len) |
100 | { | 100 | { |
101 | struct hfs_btree *tree; | ||
102 | struct page *src_page, *dst_page; | 101 | struct page *src_page, *dst_page; |
103 | 102 | ||
104 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); | 103 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); |
105 | if (!len) | 104 | if (!len) |
106 | return; | 105 | return; |
107 | tree = src_node->tree; | ||
108 | src += src_node->page_offset; | 106 | src += src_node->page_offset; |
109 | dst += dst_node->page_offset; | 107 | dst += dst_node->page_offset; |
110 | src_page = src_node->page[0]; | 108 | src_page = src_node->page[0]; |
@@ -237,7 +235,6 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) | |||
237 | 235 | ||
238 | static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | 236 | static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) |
239 | { | 237 | { |
240 | struct super_block *sb; | ||
241 | struct hfs_bnode *node, *node2; | 238 | struct hfs_bnode *node, *node2; |
242 | struct address_space *mapping; | 239 | struct address_space *mapping; |
243 | struct page *page; | 240 | struct page *page; |
@@ -249,7 +246,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
249 | return NULL; | 246 | return NULL; |
250 | } | 247 | } |
251 | 248 | ||
252 | sb = tree->inode->i_sb; | ||
253 | size = sizeof(struct hfs_bnode) + tree->pages_per_bnode * | 249 | size = sizeof(struct hfs_bnode) + tree->pages_per_bnode * |
254 | sizeof(struct page *); | 250 | sizeof(struct page *); |
255 | node = kzalloc(size, GFP_KERNEL); | 251 | node = kzalloc(size, GFP_KERNEL); |
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index d77015c3f22c..177fae4e6581 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c | |||
@@ -127,14 +127,12 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) | |||
127 | void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, | 127 | void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, |
128 | struct hfs_bnode *src_node, int src, int len) | 128 | struct hfs_bnode *src_node, int src, int len) |
129 | { | 129 | { |
130 | struct hfs_btree *tree; | ||
131 | struct page **src_page, **dst_page; | 130 | struct page **src_page, **dst_page; |
132 | int l; | 131 | int l; |
133 | 132 | ||
134 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); | 133 | hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); |
135 | if (!len) | 134 | if (!len) |
136 | return; | 135 | return; |
137 | tree = src_node->tree; | ||
138 | src += src_node->page_offset; | 136 | src += src_node->page_offset; |
139 | dst += dst_node->page_offset; | 137 | dst += dst_node->page_offset; |
140 | src_page = src_node->page + (src >> PAGE_SHIFT); | 138 | src_page = src_node->page + (src >> PAGE_SHIFT); |
@@ -401,7 +399,6 @@ struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid) | |||
401 | 399 | ||
402 | static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | 400 | static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) |
403 | { | 401 | { |
404 | struct super_block *sb; | ||
405 | struct hfs_bnode *node, *node2; | 402 | struct hfs_bnode *node, *node2; |
406 | struct address_space *mapping; | 403 | struct address_space *mapping; |
407 | struct page *page; | 404 | struct page *page; |
@@ -414,7 +411,6 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) | |||
414 | return NULL; | 411 | return NULL; |
415 | } | 412 | } |
416 | 413 | ||
417 | sb = tree->inode->i_sb; | ||
418 | size = sizeof(struct hfs_bnode) + tree->pages_per_bnode * | 414 | size = sizeof(struct hfs_bnode) + tree->pages_per_bnode * |
419 | sizeof(struct page *); | 415 | sizeof(struct page *); |
420 | node = kzalloc(size, GFP_KERNEL); | 416 | node = kzalloc(size, GFP_KERNEL); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 515d13c196da..1a2894aa0194 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -150,7 +150,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry, | |||
150 | if (err) | 150 | if (err) |
151 | return err; | 151 | return err; |
152 | 152 | ||
153 | inode = nilfs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 153 | inode = nilfs_new_inode(dir, S_IFLNK | 0777); |
154 | err = PTR_ERR(inode); | 154 | err = PTR_ERR(inode); |
155 | if (IS_ERR(inode)) | 155 | if (IS_ERR(inode)) |
156 | goto out; | 156 | goto out; |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index f65392fecb5c..f572538dcc4f 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -1954,8 +1954,6 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, | |||
1954 | err, ii->vfs_inode.i_ino); | 1954 | err, ii->vfs_inode.i_ino); |
1955 | return err; | 1955 | return err; |
1956 | } | 1956 | } |
1957 | mark_buffer_dirty(ibh); | ||
1958 | nilfs_mdt_mark_dirty(ifile); | ||
1959 | spin_lock(&nilfs->ns_inode_lock); | 1957 | spin_lock(&nilfs->ns_inode_lock); |
1960 | if (likely(!ii->i_bh)) | 1958 | if (likely(!ii->i_bh)) |
1961 | ii->i_bh = ibh; | 1959 | ii->i_bh = ibh; |
@@ -1964,6 +1962,10 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, | |||
1964 | goto retry; | 1962 | goto retry; |
1965 | } | 1963 | } |
1966 | 1964 | ||
1965 | // Always redirty the buffer to avoid race condition | ||
1966 | mark_buffer_dirty(ii->i_bh); | ||
1967 | nilfs_mdt_mark_dirty(ifile); | ||
1968 | |||
1967 | clear_bit(NILFS_I_QUEUED, &ii->i_state); | 1969 | clear_bit(NILFS_I_QUEUED, &ii->i_state); |
1968 | set_bit(NILFS_I_BUSY, &ii->i_state); | 1970 | set_bit(NILFS_I_BUSY, &ii->i_state); |
1969 | list_move_tail(&ii->i_dirty, &sci->sc_dirty_files); | 1971 | list_move_tail(&ii->i_dirty, &sci->sc_dirty_files); |
@@ -2400,11 +2402,11 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | |||
2400 | return err; | 2402 | return err; |
2401 | } | 2403 | } |
2402 | 2404 | ||
2403 | static void nilfs_construction_timeout(unsigned long data) | 2405 | static void nilfs_construction_timeout(struct timer_list *t) |
2404 | { | 2406 | { |
2405 | struct task_struct *p = (struct task_struct *)data; | 2407 | struct nilfs_sc_info *sci = from_timer(sci, t, sc_timer); |
2406 | 2408 | ||
2407 | wake_up_process(p); | 2409 | wake_up_process(sci->sc_timer_task); |
2408 | } | 2410 | } |
2409 | 2411 | ||
2410 | static void | 2412 | static void |
@@ -2542,8 +2544,7 @@ static int nilfs_segctor_thread(void *arg) | |||
2542 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; | 2544 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
2543 | int timeout = 0; | 2545 | int timeout = 0; |
2544 | 2546 | ||
2545 | sci->sc_timer.data = (unsigned long)current; | 2547 | sci->sc_timer_task = current; |
2546 | sci->sc_timer.function = nilfs_construction_timeout; | ||
2547 | 2548 | ||
2548 | /* start sync. */ | 2549 | /* start sync. */ |
2549 | sci->sc_task = current; | 2550 | sci->sc_task = current; |
@@ -2674,7 +2675,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, | |||
2674 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2675 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
2675 | INIT_LIST_HEAD(&sci->sc_iput_queue); | 2676 | INIT_LIST_HEAD(&sci->sc_iput_queue); |
2676 | INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func); | 2677 | INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func); |
2677 | init_timer(&sci->sc_timer); | 2678 | timer_setup(&sci->sc_timer, nilfs_construction_timeout, 0); |
2678 | 2679 | ||
2679 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; | 2680 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; |
2680 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; | 2681 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; |
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 1060949d7dd2..84084a4d9b3e 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -180,6 +180,7 @@ struct nilfs_sc_info { | |||
180 | unsigned long sc_watermark; | 180 | unsigned long sc_watermark; |
181 | 181 | ||
182 | struct timer_list sc_timer; | 182 | struct timer_list sc_timer; |
183 | struct task_struct *sc_timer_task; | ||
183 | struct task_struct *sc_task; | 184 | struct task_struct *sc_task; |
184 | }; | 185 | }; |
185 | 186 | ||
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 1541a1e9221a..1341a41e7b43 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
@@ -630,22 +630,22 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | |||
630 | } | 630 | } |
631 | 631 | ||
632 | /** | 632 | /** |
633 | * nilfs_sufile_truncate_range - truncate range of segment array | 633 | * nilfs_sufile_truncate_range - truncate range of segment array |
634 | * @sufile: inode of segment usage file | 634 | * @sufile: inode of segment usage file |
635 | * @start: start segment number (inclusive) | 635 | * @start: start segment number (inclusive) |
636 | * @end: end segment number (inclusive) | 636 | * @end: end segment number (inclusive) |
637 | * | 637 | * |
638 | * Return Value: On success, 0 is returned. On error, one of the | 638 | * Return Value: On success, 0 is returned. On error, one of the |
639 | * following negative error codes is returned. | 639 | * following negative error codes is returned. |
640 | * | 640 | * |
641 | * %-EIO - I/O error. | 641 | * %-EIO - I/O error. |
642 | * | 642 | * |
643 | * %-ENOMEM - Insufficient amount of memory available. | 643 | * %-ENOMEM - Insufficient amount of memory available. |
644 | * | 644 | * |
645 | * %-EINVAL - Invalid number of segments specified | 645 | * %-EINVAL - Invalid number of segments specified |
646 | * | 646 | * |
647 | * %-EBUSY - Dirty or active segments are present in the range | 647 | * %-EBUSY - Dirty or active segments are present in the range |
648 | */ | 648 | */ |
649 | static int nilfs_sufile_truncate_range(struct inode *sufile, | 649 | static int nilfs_sufile_truncate_range(struct inode *sufile, |
650 | __u64 start, __u64 end) | 650 | __u64 start, __u64 end) |
651 | { | 651 | { |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 4fc018dfcfae..3ce20cd44a20 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -160,7 +160,6 @@ struct inode *nilfs_alloc_inode(struct super_block *sb) | |||
160 | ii->i_bh = NULL; | 160 | ii->i_bh = NULL; |
161 | ii->i_state = 0; | 161 | ii->i_state = 0; |
162 | ii->i_cno = 0; | 162 | ii->i_cno = 0; |
163 | ii->vfs_inode.i_version = 1; | ||
164 | nilfs_mapping_init(&ii->i_btnode_cache, &ii->vfs_inode); | 163 | nilfs_mapping_init(&ii->i_btnode_cache, &ii->vfs_inode); |
165 | return &ii->vfs_inode; | 164 | return &ii->vfs_inode; |
166 | } | 165 | } |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 2dd75bf619ad..afebb5067cec 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -737,7 +737,7 @@ struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno) | |||
737 | } else if (cno > root->cno) { | 737 | } else if (cno > root->cno) { |
738 | n = n->rb_right; | 738 | n = n->rb_right; |
739 | } else { | 739 | } else { |
740 | atomic_inc(&root->count); | 740 | refcount_inc(&root->count); |
741 | spin_unlock(&nilfs->ns_cptree_lock); | 741 | spin_unlock(&nilfs->ns_cptree_lock); |
742 | return root; | 742 | return root; |
743 | } | 743 | } |
@@ -776,7 +776,7 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) | |||
776 | } else if (cno > root->cno) { | 776 | } else if (cno > root->cno) { |
777 | p = &(*p)->rb_right; | 777 | p = &(*p)->rb_right; |
778 | } else { | 778 | } else { |
779 | atomic_inc(&root->count); | 779 | refcount_inc(&root->count); |
780 | spin_unlock(&nilfs->ns_cptree_lock); | 780 | spin_unlock(&nilfs->ns_cptree_lock); |
781 | kfree(new); | 781 | kfree(new); |
782 | return root; | 782 | return root; |
@@ -786,7 +786,7 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) | |||
786 | new->cno = cno; | 786 | new->cno = cno; |
787 | new->ifile = NULL; | 787 | new->ifile = NULL; |
788 | new->nilfs = nilfs; | 788 | new->nilfs = nilfs; |
789 | atomic_set(&new->count, 1); | 789 | refcount_set(&new->count, 1); |
790 | atomic64_set(&new->inodes_count, 0); | 790 | atomic64_set(&new->inodes_count, 0); |
791 | atomic64_set(&new->blocks_count, 0); | 791 | atomic64_set(&new->blocks_count, 0); |
792 | 792 | ||
@@ -806,7 +806,7 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) | |||
806 | 806 | ||
807 | void nilfs_put_root(struct nilfs_root *root) | 807 | void nilfs_put_root(struct nilfs_root *root) |
808 | { | 808 | { |
809 | if (atomic_dec_and_test(&root->count)) { | 809 | if (refcount_dec_and_test(&root->count)) { |
810 | struct the_nilfs *nilfs = root->nilfs; | 810 | struct the_nilfs *nilfs = root->nilfs; |
811 | 811 | ||
812 | nilfs_sysfs_delete_snapshot_group(root); | 812 | nilfs_sysfs_delete_snapshot_group(root); |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index b305c6f033e7..883d732b0259 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
28 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/refcount.h> | ||
30 | 31 | ||
31 | struct nilfs_sc_info; | 32 | struct nilfs_sc_info; |
32 | struct nilfs_sysfs_dev_subgroups; | 33 | struct nilfs_sysfs_dev_subgroups; |
@@ -246,7 +247,7 @@ struct nilfs_root { | |||
246 | __u64 cno; | 247 | __u64 cno; |
247 | struct rb_node rb_node; | 248 | struct rb_node rb_node; |
248 | 249 | ||
249 | atomic_t count; | 250 | refcount_t count; |
250 | struct the_nilfs *nilfs; | 251 | struct the_nilfs *nilfs; |
251 | struct inode *ifile; | 252 | struct inode *ifile; |
252 | 253 | ||
@@ -299,7 +300,7 @@ void nilfs_swap_super_block(struct the_nilfs *); | |||
299 | 300 | ||
300 | static inline void nilfs_get_root(struct nilfs_root *root) | 301 | static inline void nilfs_get_root(struct nilfs_root *root) |
301 | { | 302 | { |
302 | atomic_inc(&root->count); | 303 | refcount_inc(&root->count); |
303 | } | 304 | } |
304 | 305 | ||
305 | static inline int nilfs_valid_fs(struct the_nilfs *nilfs) | 306 | static inline int nilfs_valid_fs(struct the_nilfs *nilfs) |
@@ -1018,13 +1018,19 @@ const struct file_operations pipefifo_fops = { | |||
1018 | 1018 | ||
1019 | /* | 1019 | /* |
1020 | * Currently we rely on the pipe array holding a power-of-2 number | 1020 | * Currently we rely on the pipe array holding a power-of-2 number |
1021 | * of pages. | 1021 | * of pages. Returns 0 on error. |
1022 | */ | 1022 | */ |
1023 | static inline unsigned int round_pipe_size(unsigned int size) | 1023 | unsigned int round_pipe_size(unsigned int size) |
1024 | { | 1024 | { |
1025 | unsigned long nr_pages; | 1025 | unsigned long nr_pages; |
1026 | 1026 | ||
1027 | if (size < pipe_min_size) | ||
1028 | size = pipe_min_size; | ||
1029 | |||
1027 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1030 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1031 | if (nr_pages == 0) | ||
1032 | return 0; | ||
1033 | |||
1028 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; | 1034 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; |
1029 | } | 1035 | } |
1030 | 1036 | ||
@@ -1040,6 +1046,8 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) | |||
1040 | long ret = 0; | 1046 | long ret = 0; |
1041 | 1047 | ||
1042 | size = round_pipe_size(arg); | 1048 | size = round_pipe_size(arg); |
1049 | if (size == 0) | ||
1050 | return -EINVAL; | ||
1043 | nr_pages = size >> PAGE_SHIFT; | 1051 | nr_pages = size >> PAGE_SHIFT; |
1044 | 1052 | ||
1045 | if (!nr_pages) | 1053 | if (!nr_pages) |
@@ -1117,20 +1125,13 @@ out_revert_acct: | |||
1117 | } | 1125 | } |
1118 | 1126 | ||
1119 | /* | 1127 | /* |
1120 | * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax | 1128 | * This should work even if CONFIG_PROC_FS isn't set, as proc_dopipe_max_size |
1121 | * will return an error. | 1129 | * will return an error. |
1122 | */ | 1130 | */ |
1123 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | 1131 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, |
1124 | size_t *lenp, loff_t *ppos) | 1132 | size_t *lenp, loff_t *ppos) |
1125 | { | 1133 | { |
1126 | int ret; | 1134 | return proc_dopipe_max_size(table, write, buf, lenp, ppos); |
1127 | |||
1128 | ret = proc_dointvec_minmax(table, write, buf, lenp, ppos); | ||
1129 | if (ret < 0 || !write) | ||
1130 | return ret; | ||
1131 | |||
1132 | pipe_max_size = round_pipe_size(pipe_max_size); | ||
1133 | return ret; | ||
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | /* | 1137 | /* |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index f7456c4e7d0f..ead487e80510 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -21,6 +21,7 @@ proc-y += loadavg.o | |||
21 | proc-y += meminfo.o | 21 | proc-y += meminfo.o |
22 | proc-y += stat.o | 22 | proc-y += stat.o |
23 | proc-y += uptime.o | 23 | proc-y += uptime.o |
24 | proc-y += util.o | ||
24 | proc-y += version.o | 25 | proc-y += version.o |
25 | proc-y += softirqs.o | 26 | proc-y += softirqs.o |
26 | proc-y += namespaces.o | 27 | proc-y += namespaces.o |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 6f6fc1672ad1..79375fc115d2 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -366,6 +366,11 @@ static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) | |||
366 | cpumask_pr_args(&task->cpus_allowed)); | 366 | cpumask_pr_args(&task->cpus_allowed)); |
367 | } | 367 | } |
368 | 368 | ||
369 | static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm) | ||
370 | { | ||
371 | seq_printf(m, "CoreDumping:\t%d\n", !!mm->core_state); | ||
372 | } | ||
373 | |||
369 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | 374 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
370 | struct pid *pid, struct task_struct *task) | 375 | struct pid *pid, struct task_struct *task) |
371 | { | 376 | { |
@@ -376,6 +381,7 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | |||
376 | 381 | ||
377 | if (mm) { | 382 | if (mm) { |
378 | task_mem(m, mm); | 383 | task_mem(m, mm); |
384 | task_core_dumping(m, mm); | ||
379 | mmput(mm); | 385 | mmput(mm); |
380 | } | 386 | } |
381 | task_sig(m, task); | 387 | task_sig(m, task); |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index a34195e92b20..9aad373cf11d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -103,28 +103,7 @@ static inline struct task_struct *get_proc_task(struct inode *inode) | |||
103 | void task_dump_owner(struct task_struct *task, mode_t mode, | 103 | void task_dump_owner(struct task_struct *task, mode_t mode, |
104 | kuid_t *ruid, kgid_t *rgid); | 104 | kuid_t *ruid, kgid_t *rgid); |
105 | 105 | ||
106 | static inline unsigned name_to_int(const struct qstr *qstr) | 106 | unsigned name_to_int(const struct qstr *qstr); |
107 | { | ||
108 | const char *name = qstr->name; | ||
109 | int len = qstr->len; | ||
110 | unsigned n = 0; | ||
111 | |||
112 | if (len > 1 && *name == '0') | ||
113 | goto out; | ||
114 | while (len-- > 0) { | ||
115 | unsigned c = *name++ - '0'; | ||
116 | if (c > 9) | ||
117 | goto out; | ||
118 | if (n >= (~0U-9)/10) | ||
119 | goto out; | ||
120 | n *= 10; | ||
121 | n += c; | ||
122 | } | ||
123 | return n; | ||
124 | out: | ||
125 | return ~0U; | ||
126 | } | ||
127 | |||
128 | /* | 107 | /* |
129 | * Offset of the first process in the /proc root directory.. | 108 | * Offset of the first process in the /proc root directory.. |
130 | */ | 109 | */ |
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c index 9bc5c58c00ee..a000d7547479 100644 --- a/fs/proc/loadavg.c +++ b/fs/proc/loadavg.c | |||
@@ -24,7 +24,7 @@ static int loadavg_proc_show(struct seq_file *m, void *v) | |||
24 | LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]), | 24 | LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]), |
25 | LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]), | 25 | LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]), |
26 | nr_running(), nr_threads, | 26 | nr_running(), nr_threads, |
27 | task_active_pid_ns(current)->last_pid); | 27 | idr_get_cursor(&task_active_pid_ns(current)->idr)); |
28 | return 0; | 28 | return 0; |
29 | } | 29 | } |
30 | 30 | ||
diff --git a/fs/proc/util.c b/fs/proc/util.c new file mode 100644 index 000000000000..b161cfa0f9fa --- /dev/null +++ b/fs/proc/util.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include <linux/dcache.h> | ||
2 | |||
3 | unsigned name_to_int(const struct qstr *qstr) | ||
4 | { | ||
5 | const char *name = qstr->name; | ||
6 | int len = qstr->len; | ||
7 | unsigned n = 0; | ||
8 | |||
9 | if (len > 1 && *name == '0') | ||
10 | goto out; | ||
11 | do { | ||
12 | unsigned c = *name++ - '0'; | ||
13 | if (c > 9) | ||
14 | goto out; | ||
15 | if (n >= (~0U-9)/10) | ||
16 | goto out; | ||
17 | n *= 10; | ||
18 | n += c; | ||
19 | } while (--len > 0); | ||
20 | return n; | ||
21 | out: | ||
22 | return ~0U; | ||
23 | } | ||
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index af2cc94a61bf..963b755d19b0 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h | |||
@@ -4,6 +4,8 @@ | |||
4 | 4 | ||
5 | #include <linux/compiler.h> | 5 | #include <linux/compiler.h> |
6 | 6 | ||
7 | #define CUT_HERE "------------[ cut here ]------------\n" | ||
8 | |||
7 | #ifdef CONFIG_GENERIC_BUG | 9 | #ifdef CONFIG_GENERIC_BUG |
8 | #define BUGFLAG_WARNING (1 << 0) | 10 | #define BUGFLAG_WARNING (1 << 0) |
9 | #define BUGFLAG_ONCE (1 << 1) | 11 | #define BUGFLAG_ONCE (1 << 1) |
@@ -90,10 +92,11 @@ extern void warn_slowpath_null(const char *file, const int line); | |||
90 | #define __WARN_printf_taint(taint, arg...) \ | 92 | #define __WARN_printf_taint(taint, arg...) \ |
91 | warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg) | 93 | warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg) |
92 | #else | 94 | #else |
95 | extern __printf(1, 2) void __warn_printk(const char *fmt, ...); | ||
93 | #define __WARN() __WARN_TAINT(TAINT_WARN) | 96 | #define __WARN() __WARN_TAINT(TAINT_WARN) |
94 | #define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) | 97 | #define __WARN_printf(arg...) do { __warn_printk(arg); __WARN(); } while (0) |
95 | #define __WARN_printf_taint(taint, arg...) \ | 98 | #define __WARN_printf_taint(taint, arg...) \ |
96 | do { printk(arg); __WARN_TAINT(taint); } while (0) | 99 | do { __warn_printk(arg); __WARN_TAINT(taint); } while (0) |
97 | #endif | 100 | #endif |
98 | 101 | ||
99 | /* used internally by panic.c */ | 102 | /* used internally by panic.c */ |
@@ -130,7 +133,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint, | |||
130 | 133 | ||
131 | #ifndef WARN_ON_ONCE | 134 | #ifndef WARN_ON_ONCE |
132 | #define WARN_ON_ONCE(condition) ({ \ | 135 | #define WARN_ON_ONCE(condition) ({ \ |
133 | static bool __section(.data.unlikely) __warned; \ | 136 | static bool __section(.data.once) __warned; \ |
134 | int __ret_warn_once = !!(condition); \ | 137 | int __ret_warn_once = !!(condition); \ |
135 | \ | 138 | \ |
136 | if (unlikely(__ret_warn_once && !__warned)) { \ | 139 | if (unlikely(__ret_warn_once && !__warned)) { \ |
@@ -142,7 +145,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint, | |||
142 | #endif | 145 | #endif |
143 | 146 | ||
144 | #define WARN_ONCE(condition, format...) ({ \ | 147 | #define WARN_ONCE(condition, format...) ({ \ |
145 | static bool __section(.data.unlikely) __warned; \ | 148 | static bool __section(.data.once) __warned; \ |
146 | int __ret_warn_once = !!(condition); \ | 149 | int __ret_warn_once = !!(condition); \ |
147 | \ | 150 | \ |
148 | if (unlikely(__ret_warn_once && !__warned)) { \ | 151 | if (unlikely(__ret_warn_once && !__warned)) { \ |
@@ -153,7 +156,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint, | |||
153 | }) | 156 | }) |
154 | 157 | ||
155 | #define WARN_TAINT_ONCE(condition, taint, format...) ({ \ | 158 | #define WARN_TAINT_ONCE(condition, taint, format...) ({ \ |
156 | static bool __section(.data.unlikely) __warned; \ | 159 | static bool __section(.data.once) __warned; \ |
157 | int __ret_warn_once = !!(condition); \ | 160 | int __ret_warn_once = !!(condition); \ |
158 | \ | 161 | \ |
159 | if (unlikely(__ret_warn_once && !__warned)) { \ | 162 | if (unlikely(__ret_warn_once && !__warned)) { \ |
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 6d9576931084..03cc5f9bba71 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h | |||
@@ -44,6 +44,7 @@ extern char __entry_text_start[], __entry_text_end[]; | |||
44 | extern char __start_rodata[], __end_rodata[]; | 44 | extern char __start_rodata[], __end_rodata[]; |
45 | extern char __irqentry_text_start[], __irqentry_text_end[]; | 45 | extern char __irqentry_text_start[], __irqentry_text_end[]; |
46 | extern char __softirqentry_text_start[], __softirqentry_text_end[]; | 46 | extern char __softirqentry_text_start[], __softirqentry_text_end[]; |
47 | extern char __start_once[], __end_once[]; | ||
47 | 48 | ||
48 | /* Start and end of .ctors section - used for constructor calls. */ | 49 | /* Start and end of .ctors section - used for constructor calls. */ |
49 | extern char __ctors_start[], __ctors_end[]; | 50 | extern char __ctors_start[], __ctors_end[]; |
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h index 5d2add1a6c96..238873739550 100644 --- a/include/asm-generic/topology.h +++ b/include/asm-generic/topology.h | |||
@@ -44,9 +44,6 @@ | |||
44 | #define cpu_to_mem(cpu) ((void)(cpu),0) | 44 | #define cpu_to_mem(cpu) ((void)(cpu),0) |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifndef parent_node | ||
48 | #define parent_node(node) ((void)(node),0) | ||
49 | #endif | ||
50 | #ifndef cpumask_of_node | 47 | #ifndef cpumask_of_node |
51 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 48 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
52 | #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) | 49 | #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index bdcd1caae092..ee8b707d9fa9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -223,6 +223,9 @@ | |||
223 | MEM_KEEP(init.data) \ | 223 | MEM_KEEP(init.data) \ |
224 | MEM_KEEP(exit.data) \ | 224 | MEM_KEEP(exit.data) \ |
225 | *(.data.unlikely) \ | 225 | *(.data.unlikely) \ |
226 | VMLINUX_SYMBOL(__start_once) = .; \ | ||
227 | *(.data.once) \ | ||
228 | VMLINUX_SYMBOL(__end_once) = .; \ | ||
226 | STRUCT_ALIGN(); \ | 229 | STRUCT_ALIGN(); \ |
227 | *(__tracepoints) \ | 230 | *(__tracepoints) \ |
228 | /* implement dynamic printk debug */ \ | 231 | /* implement dynamic printk debug */ \ |
diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index f2deb71958b2..1030651f8309 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #ifndef _LINUX_BITFIELD_H | 15 | #ifndef _LINUX_BITFIELD_H |
16 | #define _LINUX_BITFIELD_H | 16 | #define _LINUX_BITFIELD_H |
17 | 17 | ||
18 | #include <linux/bug.h> | 18 | #include <linux/build_bug.h> |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Bitfield access macros | 21 | * Bitfield access macros |
diff --git a/include/linux/bug.h b/include/linux/bug.h index da4231c905c8..fe5916550da8 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h | |||
@@ -43,6 +43,8 @@ enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs); | |||
43 | /* These are defined by the architecture */ | 43 | /* These are defined by the architecture */ |
44 | int is_valid_bugaddr(unsigned long addr); | 44 | int is_valid_bugaddr(unsigned long addr); |
45 | 45 | ||
46 | void generic_bug_clear_once(void); | ||
47 | |||
46 | #else /* !CONFIG_GENERIC_BUG */ | 48 | #else /* !CONFIG_GENERIC_BUG */ |
47 | 49 | ||
48 | static inline enum bug_trap_type report_bug(unsigned long bug_addr, | 50 | static inline enum bug_trap_type report_bug(unsigned long bug_addr, |
@@ -51,6 +53,9 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, | |||
51 | return BUG_TRAP_TYPE_BUG; | 53 | return BUG_TRAP_TYPE_BUG; |
52 | } | 54 | } |
53 | 55 | ||
56 | |||
57 | static inline void generic_bug_clear_once(void) {} | ||
58 | |||
54 | #endif /* CONFIG_GENERIC_BUG */ | 59 | #endif /* CONFIG_GENERIC_BUG */ |
55 | 60 | ||
56 | /* | 61 | /* |
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index a06583e41f80..3b609edffa8f 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h | |||
@@ -16,3 +16,6 @@ | |||
16 | * with any version that can compile the kernel | 16 | * with any version that can compile the kernel |
17 | */ | 17 | */ |
18 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | 18 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) |
19 | |||
20 | #define randomized_struct_fields_start struct { | ||
21 | #define randomized_struct_fields_end }; | ||
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 6dfec4d638df..872f930f1b06 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/spinlock_types.h> | 34 | #include <linux/spinlock_types.h> |
35 | #include <linux/atomic.h> | ||
35 | 36 | ||
36 | struct device; | 37 | struct device; |
37 | struct device_node; | 38 | struct device_node; |
@@ -71,7 +72,7 @@ struct gen_pool { | |||
71 | */ | 72 | */ |
72 | struct gen_pool_chunk { | 73 | struct gen_pool_chunk { |
73 | struct list_head next_chunk; /* next chunk in pool */ | 74 | struct list_head next_chunk; /* next chunk in pool */ |
74 | atomic_t avail; | 75 | atomic_long_t avail; |
75 | phys_addr_t phys_addr; /* physical starting address of memory chunk */ | 76 | phys_addr_t phys_addr; /* physical starting address of memory chunk */ |
76 | unsigned long start_addr; /* start address of memory chunk */ | 77 | unsigned long start_addr; /* start address of memory chunk */ |
77 | unsigned long end_addr; /* end address of memory chunk (inclusive) */ | 78 | unsigned long end_addr; /* end address of memory chunk (inclusive) */ |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 8062e6cc607c..6a532629c983 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -105,7 +105,6 @@ extern struct group_info init_groups; | |||
105 | .numbers = { { \ | 105 | .numbers = { { \ |
106 | .nr = 0, \ | 106 | .nr = 0, \ |
107 | .ns = &init_pid_ns, \ | 107 | .ns = &init_pid_ns, \ |
108 | .pid_chain = { .next = NULL, .pprev = NULL }, \ | ||
109 | }, } \ | 108 | }, } \ |
110 | } | 109 | } |
111 | 110 | ||
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index d29e1e21bf3f..b1d861caca16 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h | |||
@@ -42,18 +42,21 @@ | |||
42 | */ | 42 | */ |
43 | #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ | 43 | #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ |
44 | ({ \ | 44 | ({ \ |
45 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | 45 | u64 __timeout_us = (timeout_us); \ |
46 | might_sleep_if(sleep_us); \ | 46 | unsigned long __sleep_us = (sleep_us); \ |
47 | ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ | ||
48 | might_sleep_if((__sleep_us) != 0); \ | ||
47 | for (;;) { \ | 49 | for (;;) { \ |
48 | (val) = op(addr); \ | 50 | (val) = op(addr); \ |
49 | if (cond) \ | 51 | if (cond) \ |
50 | break; \ | 52 | break; \ |
51 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | 53 | if (__timeout_us && \ |
54 | ktime_compare(ktime_get(), __timeout) > 0) { \ | ||
52 | (val) = op(addr); \ | 55 | (val) = op(addr); \ |
53 | break; \ | 56 | break; \ |
54 | } \ | 57 | } \ |
55 | if (sleep_us) \ | 58 | if (__sleep_us) \ |
56 | usleep_range((sleep_us >> 2) + 1, sleep_us); \ | 59 | usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ |
57 | } \ | 60 | } \ |
58 | (cond) ? 0 : -ETIMEDOUT; \ | 61 | (cond) ? 0 : -ETIMEDOUT; \ |
59 | }) | 62 | }) |
@@ -77,17 +80,20 @@ | |||
77 | */ | 80 | */ |
78 | #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \ | 81 | #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \ |
79 | ({ \ | 82 | ({ \ |
80 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | 83 | u64 __timeout_us = (timeout_us); \ |
84 | unsigned long __delay_us = (delay_us); \ | ||
85 | ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ | ||
81 | for (;;) { \ | 86 | for (;;) { \ |
82 | (val) = op(addr); \ | 87 | (val) = op(addr); \ |
83 | if (cond) \ | 88 | if (cond) \ |
84 | break; \ | 89 | break; \ |
85 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | 90 | if (__timeout_us && \ |
91 | ktime_compare(ktime_get(), __timeout) > 0) { \ | ||
86 | (val) = op(addr); \ | 92 | (val) = op(addr); \ |
87 | break; \ | 93 | break; \ |
88 | } \ | 94 | } \ |
89 | if (delay_us) \ | 95 | if (__delay_us) \ |
90 | udelay(delay_us); \ | 96 | udelay(__delay_us); \ |
91 | } \ | 97 | } \ |
92 | (cond) ? 0 : -ETIMEDOUT; \ | 98 | (cond) ? 0 : -ETIMEDOUT; \ |
93 | }) | 99 | }) |
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index 474812abe773..b5630c8eb2f3 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h | |||
@@ -19,7 +19,10 @@ struct ipc_ids { | |||
19 | bool tables_initialized; | 19 | bool tables_initialized; |
20 | struct rw_semaphore rwsem; | 20 | struct rw_semaphore rwsem; |
21 | struct idr ipcs_idr; | 21 | struct idr ipcs_idr; |
22 | int max_id; | ||
23 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
22 | int next_id; | 24 | int next_id; |
25 | #endif | ||
23 | struct rhashtable key_ht; | 26 | struct rhashtable key_ht; |
24 | }; | 27 | }; |
25 | 28 | ||
diff --git a/include/linux/kcov.h b/include/linux/kcov.h index f5d8ce4f4f86..3ecf6f5e3a5f 100644 --- a/include/linux/kcov.h +++ b/include/linux/kcov.h | |||
@@ -8,19 +8,23 @@ struct task_struct; | |||
8 | 8 | ||
9 | #ifdef CONFIG_KCOV | 9 | #ifdef CONFIG_KCOV |
10 | 10 | ||
11 | void kcov_task_init(struct task_struct *t); | ||
12 | void kcov_task_exit(struct task_struct *t); | ||
13 | |||
14 | enum kcov_mode { | 11 | enum kcov_mode { |
15 | /* Coverage collection is not enabled yet. */ | 12 | /* Coverage collection is not enabled yet. */ |
16 | KCOV_MODE_DISABLED = 0, | 13 | KCOV_MODE_DISABLED = 0, |
14 | /* KCOV was initialized, but tracing mode hasn't been chosen yet. */ | ||
15 | KCOV_MODE_INIT = 1, | ||
17 | /* | 16 | /* |
18 | * Tracing coverage collection mode. | 17 | * Tracing coverage collection mode. |
19 | * Covered PCs are collected in a per-task buffer. | 18 | * Covered PCs are collected in a per-task buffer. |
20 | */ | 19 | */ |
21 | KCOV_MODE_TRACE = 1, | 20 | KCOV_MODE_TRACE_PC = 2, |
21 | /* Collecting comparison operands mode. */ | ||
22 | KCOV_MODE_TRACE_CMP = 3, | ||
22 | }; | 23 | }; |
23 | 24 | ||
25 | void kcov_task_init(struct task_struct *t); | ||
26 | void kcov_task_exit(struct task_struct *t); | ||
27 | |||
24 | #else | 28 | #else |
25 | 29 | ||
26 | static inline void kcov_task_init(struct task_struct *t) {} | 30 | static inline void kcov_task_init(struct task_struct *t) {} |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4b484ab9e163..ce51455e2adf 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -549,7 +549,8 @@ extern enum system_states { | |||
549 | #define TAINT_UNSIGNED_MODULE 13 | 549 | #define TAINT_UNSIGNED_MODULE 13 |
550 | #define TAINT_SOFTLOCKUP 14 | 550 | #define TAINT_SOFTLOCKUP 14 |
551 | #define TAINT_LIVEPATCH 15 | 551 | #define TAINT_LIVEPATCH 15 |
552 | #define TAINT_FLAGS_COUNT 16 | 552 | #define TAINT_AUX 16 |
553 | #define TAINT_FLAGS_COUNT 17 | ||
553 | 554 | ||
554 | struct taint_flag { | 555 | struct taint_flag { |
555 | char c_true; /* character printed when tainted */ | 556 | char c_true; /* character printed when tainted */ |
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 15cab3967d6d..1fbde8a880d9 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h | |||
@@ -104,9 +104,16 @@ extern nodemask_t _unused_nodemask_arg_; | |||
104 | * | 104 | * |
105 | * Can be used to provide arguments for '%*pb[l]' when printing a nodemask. | 105 | * Can be used to provide arguments for '%*pb[l]' when printing a nodemask. |
106 | */ | 106 | */ |
107 | #define nodemask_pr_args(maskp) \ | 107 | #define nodemask_pr_args(maskp) __nodemask_pr_numnodes(maskp), \ |
108 | ((maskp) != NULL) ? MAX_NUMNODES : 0, \ | 108 | __nodemask_pr_bits(maskp) |
109 | ((maskp) != NULL) ? (maskp)->bits : NULL | 109 | static inline unsigned int __nodemask_pr_numnodes(const nodemask_t *m) |
110 | { | ||
111 | return m ? MAX_NUMNODES : 0; | ||
112 | } | ||
113 | static inline const unsigned long *__nodemask_pr_bits(const nodemask_t *m) | ||
114 | { | ||
115 | return m ? m->bits : NULL; | ||
116 | } | ||
110 | 117 | ||
111 | /* | 118 | /* |
112 | * The inline keyword gives the compiler room to decide to inline, or | 119 | * The inline keyword gives the compiler room to decide to inline, or |
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h index e942558b3585..9132c5cb41f1 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h | |||
@@ -96,6 +96,17 @@ void set_pfnblock_flags_mask(struct page *page, | |||
96 | #define set_pageblock_skip(page) \ | 96 | #define set_pageblock_skip(page) \ |
97 | set_pageblock_flags_group(page, 1, PB_migrate_skip, \ | 97 | set_pageblock_flags_group(page, 1, PB_migrate_skip, \ |
98 | PB_migrate_skip) | 98 | PB_migrate_skip) |
99 | #else | ||
100 | static inline bool get_pageblock_skip(struct page *page) | ||
101 | { | ||
102 | return false; | ||
103 | } | ||
104 | static inline void clear_pageblock_skip(struct page *page) | ||
105 | { | ||
106 | } | ||
107 | static inline void set_pageblock_skip(struct page *page) | ||
108 | { | ||
109 | } | ||
99 | #endif /* CONFIG_COMPACTION */ | 110 | #endif /* CONFIG_COMPACTION */ |
100 | 111 | ||
101 | #endif /* PAGEBLOCK_FLAGS_H */ | 112 | #endif /* PAGEBLOCK_FLAGS_H */ |
diff --git a/include/linux/pid.h b/include/linux/pid.h index dfd684ce0787..7633d55d9a24 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h | |||
@@ -51,10 +51,8 @@ enum pid_type | |||
51 | */ | 51 | */ |
52 | 52 | ||
53 | struct upid { | 53 | struct upid { |
54 | /* Try to keep pid_chain in the same cacheline as nr for find_vpid */ | ||
55 | int nr; | 54 | int nr; |
56 | struct pid_namespace *ns; | 55 | struct pid_namespace *ns; |
57 | struct hlist_node pid_chain; | ||
58 | }; | 56 | }; |
59 | 57 | ||
60 | struct pid | 58 | struct pid |
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index c78af6061644..49538b172483 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h | |||
@@ -10,15 +10,8 @@ | |||
10 | #include <linux/nsproxy.h> | 10 | #include <linux/nsproxy.h> |
11 | #include <linux/kref.h> | 11 | #include <linux/kref.h> |
12 | #include <linux/ns_common.h> | 12 | #include <linux/ns_common.h> |
13 | #include <linux/idr.h> | ||
13 | 14 | ||
14 | struct pidmap { | ||
15 | atomic_t nr_free; | ||
16 | void *page; | ||
17 | }; | ||
18 | |||
19 | #define BITS_PER_PAGE (PAGE_SIZE * 8) | ||
20 | #define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) | ||
21 | #define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE) | ||
22 | 15 | ||
23 | struct fs_pin; | 16 | struct fs_pin; |
24 | 17 | ||
@@ -30,10 +23,9 @@ enum { /* definitions for pid_namespace's hide_pid field */ | |||
30 | 23 | ||
31 | struct pid_namespace { | 24 | struct pid_namespace { |
32 | struct kref kref; | 25 | struct kref kref; |
33 | struct pidmap pidmap[PIDMAP_ENTRIES]; | 26 | struct idr idr; |
34 | struct rcu_head rcu; | 27 | struct rcu_head rcu; |
35 | int last_pid; | 28 | unsigned int pid_allocated; |
36 | unsigned int nr_hashed; | ||
37 | struct task_struct *child_reaper; | 29 | struct task_struct *child_reaper; |
38 | struct kmem_cache *pid_cachep; | 30 | struct kmem_cache *pid_cachep; |
39 | unsigned int level; | 31 | unsigned int level; |
@@ -57,7 +49,7 @@ struct pid_namespace { | |||
57 | 49 | ||
58 | extern struct pid_namespace init_pid_ns; | 50 | extern struct pid_namespace init_pid_ns; |
59 | 51 | ||
60 | #define PIDNS_HASH_ADDING (1U << 31) | 52 | #define PIDNS_ADDING (1U << 31) |
61 | 53 | ||
62 | #ifdef CONFIG_PID_NS | 54 | #ifdef CONFIG_PID_NS |
63 | static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) | 55 | static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) |
@@ -106,6 +98,6 @@ static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) | |||
106 | 98 | ||
107 | extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk); | 99 | extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk); |
108 | void pidhash_init(void); | 100 | void pidhash_init(void); |
109 | void pidmap_init(void); | 101 | void pid_idr_init(void); |
110 | 102 | ||
111 | #endif /* _LINUX_PID_NS_H */ | 103 | #endif /* _LINUX_PID_NS_H */ |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 6a80cfc63e0c..2dc5e9870fcd 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -191,5 +191,6 @@ long pipe_fcntl(struct file *, unsigned int, unsigned long arg); | |||
191 | struct pipe_inode_info *get_pipe_info(struct file *file); | 191 | struct pipe_inode_info *get_pipe_info(struct file *file); |
192 | 192 | ||
193 | int create_pipe_files(struct file **, int); | 193 | int create_pipe_files(struct file **, int); |
194 | unsigned int round_pipe_size(unsigned int size); | ||
194 | 195 | ||
195 | #endif | 196 | #endif |
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 0ca448c1cb42..23a9c89c7ad9 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -22,7 +22,6 @@ | |||
22 | #define _LINUX_RADIX_TREE_H | 22 | #define _LINUX_RADIX_TREE_H |
23 | 23 | ||
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <linux/bug.h> | ||
26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
27 | #include <linux/list.h> | 26 | #include <linux/list.h> |
28 | #include <linux/preempt.h> | 27 | #include <linux/preempt.h> |
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index d03da0eb95ca..e63799a6e895 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <linux/notifier.h> | 6 | #include <linux/notifier.h> |
7 | #include <uapi/linux/reboot.h> | 7 | #include <uapi/linux/reboot.h> |
8 | 8 | ||
9 | struct device; | ||
10 | |||
9 | #define SYS_DOWN 0x0001 /* Notify of system down */ | 11 | #define SYS_DOWN 0x0001 /* Notify of system down */ |
10 | #define SYS_RESTART SYS_DOWN | 12 | #define SYS_RESTART SYS_DOWN |
11 | #define SYS_HALT 0x0002 /* Notify of system halt */ | 13 | #define SYS_HALT 0x0002 /* Notify of system halt */ |
@@ -39,6 +41,8 @@ extern int reboot_force; | |||
39 | extern int register_reboot_notifier(struct notifier_block *); | 41 | extern int register_reboot_notifier(struct notifier_block *); |
40 | extern int unregister_reboot_notifier(struct notifier_block *); | 42 | extern int unregister_reboot_notifier(struct notifier_block *); |
41 | 43 | ||
44 | extern int devm_register_reboot_notifier(struct device *, struct notifier_block *); | ||
45 | |||
42 | extern int register_restart_handler(struct notifier_block *); | 46 | extern int register_restart_handler(struct notifier_block *); |
43 | extern int unregister_restart_handler(struct notifier_block *); | 47 | extern int unregister_restart_handler(struct notifier_block *); |
44 | extern void do_kernel_restart(char *cmd); | 48 | extern void do_kernel_restart(char *cmd); |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index b769ecfcc3bd..992bc9948232 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -51,6 +51,9 @@ extern int proc_dointvec_minmax(struct ctl_table *, int, | |||
51 | extern int proc_douintvec_minmax(struct ctl_table *table, int write, | 51 | extern int proc_douintvec_minmax(struct ctl_table *table, int write, |
52 | void __user *buffer, size_t *lenp, | 52 | void __user *buffer, size_t *lenp, |
53 | loff_t *ppos); | 53 | loff_t *ppos); |
54 | extern int proc_dopipe_max_size(struct ctl_table *table, int write, | ||
55 | void __user *buffer, size_t *lenp, | ||
56 | loff_t *ppos); | ||
54 | extern int proc_dointvec_jiffies(struct ctl_table *, int, | 57 | extern int proc_dointvec_jiffies(struct ctl_table *, int, |
55 | void __user *, size_t *, loff_t *); | 58 | void __user *, size_t *, loff_t *); |
56 | extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, | 59 | extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, |
diff --git a/include/uapi/linux/kcov.h b/include/uapi/linux/kcov.h index 33eabbb8ada1..9529867717a8 100644 --- a/include/uapi/linux/kcov.h +++ b/include/uapi/linux/kcov.h | |||
@@ -8,4 +8,28 @@ | |||
8 | #define KCOV_ENABLE _IO('c', 100) | 8 | #define KCOV_ENABLE _IO('c', 100) |
9 | #define KCOV_DISABLE _IO('c', 101) | 9 | #define KCOV_DISABLE _IO('c', 101) |
10 | 10 | ||
11 | enum { | ||
12 | /* | ||
13 | * Tracing coverage collection mode. | ||
14 | * Covered PCs are collected in a per-task buffer. | ||
15 | * In new KCOV version the mode is chosen by calling | ||
16 | * ioctl(fd, KCOV_ENABLE, mode). In older versions the mode argument | ||
17 | * was supposed to be 0 in such a call. So, for reasons of backward | ||
18 | * compatibility, we have chosen the value KCOV_TRACE_PC to be 0. | ||
19 | */ | ||
20 | KCOV_TRACE_PC = 0, | ||
21 | /* Collecting comparison operands mode. */ | ||
22 | KCOV_TRACE_CMP = 1, | ||
23 | }; | ||
24 | |||
25 | /* | ||
26 | * The format for the types of collected comparisons. | ||
27 | * | ||
28 | * Bit 0 shows whether one of the arguments is a compile-time constant. | ||
29 | * Bits 1 & 2 contain log2 of the argument size, up to 8 bytes. | ||
30 | */ | ||
31 | #define KCOV_CMP_CONST (1 << 0) | ||
32 | #define KCOV_CMP_SIZE(n) ((n) << 1) | ||
33 | #define KCOV_CMP_MASK KCOV_CMP_SIZE(3) | ||
34 | |||
11 | #endif /* _LINUX_KCOV_IOCTLS_H */ | 35 | #endif /* _LINUX_KCOV_IOCTLS_H */ |
diff --git a/init/Kconfig b/init/Kconfig index 7d5a6fbac56a..2934249fba46 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -283,19 +283,6 @@ config CROSS_MEMORY_ATTACH | |||
283 | to directly read from or write to another process' address space. | 283 | to directly read from or write to another process' address space. |
284 | See the man page for more details. | 284 | See the man page for more details. |
285 | 285 | ||
286 | config FHANDLE | ||
287 | bool "open by fhandle syscalls" if EXPERT | ||
288 | select EXPORTFS | ||
289 | default y | ||
290 | help | ||
291 | If you say Y here, a user level program will be able to map | ||
292 | file names to handle and then later use the handle for | ||
293 | different file system operations. This is useful in implementing | ||
294 | userspace file servers, which now track files using handles instead | ||
295 | of names. The handle would remain the same even if file names | ||
296 | get renamed. Enables open_by_handle_at(2) and name_to_handle_at(2) | ||
297 | syscalls. | ||
298 | |||
299 | config USELIB | 286 | config USELIB |
300 | bool "uselib syscall" | 287 | bool "uselib syscall" |
301 | def_bool ALPHA || M68K || SPARC || X86_32 || IA32_EMULATION | 288 | def_bool ALPHA || M68K || SPARC || X86_32 || IA32_EMULATION |
@@ -883,18 +870,6 @@ config SOCK_CGROUP_DATA | |||
883 | 870 | ||
884 | endif # CGROUPS | 871 | endif # CGROUPS |
885 | 872 | ||
886 | config CHECKPOINT_RESTORE | ||
887 | bool "Checkpoint/restore support" if EXPERT | ||
888 | select PROC_CHILDREN | ||
889 | default n | ||
890 | help | ||
891 | Enables additional kernel features in a sake of checkpoint/restore. | ||
892 | In particular it adds auxiliary prctl codes to setup process text, | ||
893 | data and heap segment sizes, and a few additional /proc filesystem | ||
894 | entries. | ||
895 | |||
896 | If unsure, say N here. | ||
897 | |||
898 | menuconfig NAMESPACES | 873 | menuconfig NAMESPACES |
899 | bool "Namespaces support" if EXPERT | 874 | bool "Namespaces support" if EXPERT |
900 | depends on MULTIUSER | 875 | depends on MULTIUSER |
@@ -1163,6 +1138,19 @@ config SYSCTL_SYSCALL | |||
1163 | 1138 | ||
1164 | If unsure say N here. | 1139 | If unsure say N here. |
1165 | 1140 | ||
1141 | config FHANDLE | ||
1142 | bool "open by fhandle syscalls" if EXPERT | ||
1143 | select EXPORTFS | ||
1144 | default y | ||
1145 | help | ||
1146 | If you say Y here, a user level program will be able to map | ||
1147 | file names to handle and then later use the handle for | ||
1148 | different file system operations. This is useful in implementing | ||
1149 | userspace file servers, which now track files using handles instead | ||
1150 | of names. The handle would remain the same even if file names | ||
1151 | get renamed. Enables open_by_handle_at(2) and name_to_handle_at(2) | ||
1152 | syscalls. | ||
1153 | |||
1166 | config POSIX_TIMERS | 1154 | config POSIX_TIMERS |
1167 | bool "Posix Clocks & timers" if EXPERT | 1155 | bool "Posix Clocks & timers" if EXPERT |
1168 | default y | 1156 | default y |
@@ -1180,54 +1168,6 @@ config POSIX_TIMERS | |||
1180 | 1168 | ||
1181 | If unsure say y. | 1169 | If unsure say y. |
1182 | 1170 | ||
1183 | config KALLSYMS | ||
1184 | bool "Load all symbols for debugging/ksymoops" if EXPERT | ||
1185 | default y | ||
1186 | help | ||
1187 | Say Y here to let the kernel print out symbolic crash information and | ||
1188 | symbolic stack backtraces. This increases the size of the kernel | ||
1189 | somewhat, as all symbols have to be loaded into the kernel image. | ||
1190 | |||
1191 | config KALLSYMS_ALL | ||
1192 | bool "Include all symbols in kallsyms" | ||
1193 | depends on DEBUG_KERNEL && KALLSYMS | ||
1194 | help | ||
1195 | Normally kallsyms only contains the symbols of functions for nicer | ||
1196 | OOPS messages and backtraces (i.e., symbols from the text and inittext | ||
1197 | sections). This is sufficient for most cases. And only in very rare | ||
1198 | cases (e.g., when a debugger is used) all symbols are required (e.g., | ||
1199 | names of variables from the data sections, etc). | ||
1200 | |||
1201 | This option makes sure that all symbols are loaded into the kernel | ||
1202 | image (i.e., symbols from all sections) in cost of increased kernel | ||
1203 | size (depending on the kernel configuration, it may be 300KiB or | ||
1204 | something like this). | ||
1205 | |||
1206 | Say N unless you really need all symbols. | ||
1207 | |||
1208 | config KALLSYMS_ABSOLUTE_PERCPU | ||
1209 | bool | ||
1210 | depends on KALLSYMS | ||
1211 | default X86_64 && SMP | ||
1212 | |||
1213 | config KALLSYMS_BASE_RELATIVE | ||
1214 | bool | ||
1215 | depends on KALLSYMS | ||
1216 | default !IA64 && !(TILE && 64BIT) | ||
1217 | help | ||
1218 | Instead of emitting them as absolute values in the native word size, | ||
1219 | emit the symbol references in the kallsyms table as 32-bit entries, | ||
1220 | each containing a relative value in the range [base, base + U32_MAX] | ||
1221 | or, when KALLSYMS_ABSOLUTE_PERCPU is in effect, each containing either | ||
1222 | an absolute value in the range [0, S32_MAX] or a relative value in the | ||
1223 | range [base, base + S32_MAX], where base is the lowest relative symbol | ||
1224 | address encountered in the image. | ||
1225 | |||
1226 | On 64-bit builds, this reduces the size of the address table by 50%, | ||
1227 | but more importantly, it results in entries whose values are build | ||
1228 | time constants, and no relocation pass is required at runtime to fix | ||
1229 | up the entries based on the runtime load address of the kernel. | ||
1230 | |||
1231 | config PRINTK | 1171 | config PRINTK |
1232 | default y | 1172 | default y |
1233 | bool "Enable support for printk" if EXPERT | 1173 | bool "Enable support for printk" if EXPERT |
@@ -1339,16 +1279,6 @@ config EVENTFD | |||
1339 | 1279 | ||
1340 | If unsure, say Y. | 1280 | If unsure, say Y. |
1341 | 1281 | ||
1342 | # syscall, maps, verifier | ||
1343 | config BPF_SYSCALL | ||
1344 | bool "Enable bpf() system call" | ||
1345 | select ANON_INODES | ||
1346 | select BPF | ||
1347 | default n | ||
1348 | help | ||
1349 | Enable the bpf() system call that allows to manipulate eBPF | ||
1350 | programs and maps via file descriptors. | ||
1351 | |||
1352 | config SHMEM | 1282 | config SHMEM |
1353 | bool "Use full shmem filesystem" if EXPERT | 1283 | bool "Use full shmem filesystem" if EXPERT |
1354 | default y | 1284 | default y |
@@ -1378,14 +1308,6 @@ config ADVISE_SYSCALLS | |||
1378 | applications use these syscalls, you can disable this option to save | 1308 | applications use these syscalls, you can disable this option to save |
1379 | space. | 1309 | space. |
1380 | 1310 | ||
1381 | config USERFAULTFD | ||
1382 | bool "Enable userfaultfd() system call" | ||
1383 | select ANON_INODES | ||
1384 | depends on MMU | ||
1385 | help | ||
1386 | Enable the userfaultfd() system call that allows to intercept and | ||
1387 | handle page faults in userland. | ||
1388 | |||
1389 | config MEMBARRIER | 1311 | config MEMBARRIER |
1390 | bool "Enable membarrier() system call" if EXPERT | 1312 | bool "Enable membarrier() system call" if EXPERT |
1391 | default y | 1313 | default y |
@@ -1398,6 +1320,86 @@ config MEMBARRIER | |||
1398 | 1320 | ||
1399 | If unsure, say Y. | 1321 | If unsure, say Y. |
1400 | 1322 | ||
1323 | config CHECKPOINT_RESTORE | ||
1324 | bool "Checkpoint/restore support" if EXPERT | ||
1325 | select PROC_CHILDREN | ||
1326 | default n | ||
1327 | help | ||
1328 | Enables additional kernel features in a sake of checkpoint/restore. | ||
1329 | In particular it adds auxiliary prctl codes to setup process text, | ||
1330 | data and heap segment sizes, and a few additional /proc filesystem | ||
1331 | entries. | ||
1332 | |||
1333 | If unsure, say N here. | ||
1334 | |||
1335 | config KALLSYMS | ||
1336 | bool "Load all symbols for debugging/ksymoops" if EXPERT | ||
1337 | default y | ||
1338 | help | ||
1339 | Say Y here to let the kernel print out symbolic crash information and | ||
1340 | symbolic stack backtraces. This increases the size of the kernel | ||
1341 | somewhat, as all symbols have to be loaded into the kernel image. | ||
1342 | |||
1343 | config KALLSYMS_ALL | ||
1344 | bool "Include all symbols in kallsyms" | ||
1345 | depends on DEBUG_KERNEL && KALLSYMS | ||
1346 | help | ||
1347 | Normally kallsyms only contains the symbols of functions for nicer | ||
1348 | OOPS messages and backtraces (i.e., symbols from the text and inittext | ||
1349 | sections). This is sufficient for most cases. And only in very rare | ||
1350 | cases (e.g., when a debugger is used) all symbols are required (e.g., | ||
1351 | names of variables from the data sections, etc). | ||
1352 | |||
1353 | This option makes sure that all symbols are loaded into the kernel | ||
1354 | image (i.e., symbols from all sections) in cost of increased kernel | ||
1355 | size (depending on the kernel configuration, it may be 300KiB or | ||
1356 | something like this). | ||
1357 | |||
1358 | Say N unless you really need all symbols. | ||
1359 | |||
1360 | config KALLSYMS_ABSOLUTE_PERCPU | ||
1361 | bool | ||
1362 | depends on KALLSYMS | ||
1363 | default X86_64 && SMP | ||
1364 | |||
1365 | config KALLSYMS_BASE_RELATIVE | ||
1366 | bool | ||
1367 | depends on KALLSYMS | ||
1368 | default !IA64 && !(TILE && 64BIT) | ||
1369 | help | ||
1370 | Instead of emitting them as absolute values in the native word size, | ||
1371 | emit the symbol references in the kallsyms table as 32-bit entries, | ||
1372 | each containing a relative value in the range [base, base + U32_MAX] | ||
1373 | or, when KALLSYMS_ABSOLUTE_PERCPU is in effect, each containing either | ||
1374 | an absolute value in the range [0, S32_MAX] or a relative value in the | ||
1375 | range [base, base + S32_MAX], where base is the lowest relative symbol | ||
1376 | address encountered in the image. | ||
1377 | |||
1378 | On 64-bit builds, this reduces the size of the address table by 50%, | ||
1379 | but more importantly, it results in entries whose values are build | ||
1380 | time constants, and no relocation pass is required at runtime to fix | ||
1381 | up the entries based on the runtime load address of the kernel. | ||
1382 | |||
1383 | # end of the "standard kernel features (expert users)" menu | ||
1384 | |||
1385 | # syscall, maps, verifier | ||
1386 | config BPF_SYSCALL | ||
1387 | bool "Enable bpf() system call" | ||
1388 | select ANON_INODES | ||
1389 | select BPF | ||
1390 | default n | ||
1391 | help | ||
1392 | Enable the bpf() system call that allows to manipulate eBPF | ||
1393 | programs and maps via file descriptors. | ||
1394 | |||
1395 | config USERFAULTFD | ||
1396 | bool "Enable userfaultfd() system call" | ||
1397 | select ANON_INODES | ||
1398 | depends on MMU | ||
1399 | help | ||
1400 | Enable the userfaultfd() system call that allows to intercept and | ||
1401 | handle page faults in userland. | ||
1402 | |||
1401 | config EMBEDDED | 1403 | config EMBEDDED |
1402 | bool "Embedded system" | 1404 | bool "Embedded system" |
1403 | option allnoconfig_y | 1405 | option allnoconfig_y |
diff --git a/init/initramfs.c b/init/initramfs.c index 7046feffef6b..7e99a0038942 100644 --- a/init/initramfs.c +++ b/init/initramfs.c | |||
@@ -109,7 +109,7 @@ static void __init free_hash(void) | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | static long __init do_utime(char *filename, time_t mtime) | 112 | static long __init do_utime(char *filename, time64_t mtime) |
113 | { | 113 | { |
114 | struct timespec64 t[2]; | 114 | struct timespec64 t[2]; |
115 | 115 | ||
@@ -125,10 +125,10 @@ static __initdata LIST_HEAD(dir_list); | |||
125 | struct dir_entry { | 125 | struct dir_entry { |
126 | struct list_head list; | 126 | struct list_head list; |
127 | char *name; | 127 | char *name; |
128 | time_t mtime; | 128 | time64_t mtime; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static void __init dir_add(const char *name, time_t mtime) | 131 | static void __init dir_add(const char *name, time64_t mtime) |
132 | { | 132 | { |
133 | struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL); | 133 | struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL); |
134 | if (!de) | 134 | if (!de) |
@@ -150,7 +150,7 @@ static void __init dir_utime(void) | |||
150 | } | 150 | } |
151 | } | 151 | } |
152 | 152 | ||
153 | static __initdata time_t mtime; | 153 | static __initdata time64_t mtime; |
154 | 154 | ||
155 | /* cpio header parsing */ | 155 | /* cpio header parsing */ |
156 | 156 | ||
@@ -177,7 +177,7 @@ static void __init parse_header(char *s) | |||
177 | uid = parsed[2]; | 177 | uid = parsed[2]; |
178 | gid = parsed[3]; | 178 | gid = parsed[3]; |
179 | nlink = parsed[4]; | 179 | nlink = parsed[4]; |
180 | mtime = parsed[5]; | 180 | mtime = parsed[5]; /* breaks in y2106 */ |
181 | body_len = parsed[6]; | 181 | body_len = parsed[6]; |
182 | major = parsed[7]; | 182 | major = parsed[7]; |
183 | minor = parsed[8]; | 183 | minor = parsed[8]; |
diff --git a/init/main.c b/init/main.c index 859a786f7c0a..dfec3809e740 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -562,7 +562,6 @@ asmlinkage __visible void __init start_kernel(void) | |||
562 | * kmem_cache_init() | 562 | * kmem_cache_init() |
563 | */ | 563 | */ |
564 | setup_log_buf(0); | 564 | setup_log_buf(0); |
565 | pidhash_init(); | ||
566 | vfs_caches_init_early(); | 565 | vfs_caches_init_early(); |
567 | sort_main_extable(); | 566 | sort_main_extable(); |
568 | trap_init(); | 567 | trap_init(); |
@@ -669,7 +668,7 @@ asmlinkage __visible void __init start_kernel(void) | |||
669 | if (late_time_init) | 668 | if (late_time_init) |
670 | late_time_init(); | 669 | late_time_init(); |
671 | calibrate_delay(); | 670 | calibrate_delay(); |
672 | pidmap_init(); | 671 | pid_idr_init(); |
673 | anon_vma_init(); | 672 | anon_vma_init(); |
674 | #ifdef CONFIG_X86 | 673 | #ifdef CONFIG_X86 |
675 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | 674 | if (efi_enabled(EFI_RUNTIME_SERVICES)) |
diff --git a/init/version.c b/init/version.c index 5606341e9efd..bfb4e3f4955e 100644 --- a/init/version.c +++ b/init/version.c | |||
@@ -7,7 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <generated/compile.h> | 9 | #include <generated/compile.h> |
10 | #include <linux/module.h> | 10 | #include <linux/export.h> |
11 | #include <linux/uts.h> | 11 | #include <linux/uts.h> |
12 | #include <linux/utsname.h> | 12 | #include <linux/utsname.h> |
13 | #include <generated/utsrelease.h> | 13 | #include <generated/utsrelease.h> |
@@ -515,6 +515,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) | |||
515 | sma->sem_nsems = nsems; | 515 | sma->sem_nsems = nsems; |
516 | sma->sem_ctime = ktime_get_real_seconds(); | 516 | sma->sem_ctime = ktime_get_real_seconds(); |
517 | 517 | ||
518 | /* ipc_addid() locks sma upon success. */ | ||
518 | retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); | 519 | retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); |
519 | if (retval < 0) { | 520 | if (retval < 0) { |
520 | call_rcu(&sma->sem_perm.rcu, sem_rcu_free); | 521 | call_rcu(&sma->sem_perm.rcu, sem_rcu_free); |
@@ -601,6 +601,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
601 | shp->shm_file = file; | 601 | shp->shm_file = file; |
602 | shp->shm_creator = current; | 602 | shp->shm_creator = current; |
603 | 603 | ||
604 | /* ipc_addid() locks shp upon success. */ | ||
604 | error = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); | 605 | error = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni); |
605 | if (error < 0) | 606 | if (error < 0) |
606 | goto no_id; | 607 | goto no_id; |
diff --git a/ipc/util.c b/ipc/util.c index 79b30eee32cd..ff045fec8d83 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -116,13 +116,16 @@ int ipc_init_ids(struct ipc_ids *ids) | |||
116 | int err; | 116 | int err; |
117 | ids->in_use = 0; | 117 | ids->in_use = 0; |
118 | ids->seq = 0; | 118 | ids->seq = 0; |
119 | ids->next_id = -1; | ||
120 | init_rwsem(&ids->rwsem); | 119 | init_rwsem(&ids->rwsem); |
121 | err = rhashtable_init(&ids->key_ht, &ipc_kht_params); | 120 | err = rhashtable_init(&ids->key_ht, &ipc_kht_params); |
122 | if (err) | 121 | if (err) |
123 | return err; | 122 | return err; |
124 | idr_init(&ids->ipcs_idr); | 123 | idr_init(&ids->ipcs_idr); |
125 | ids->tables_initialized = true; | 124 | ids->tables_initialized = true; |
125 | ids->max_id = -1; | ||
126 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
127 | ids->next_id = -1; | ||
128 | #endif | ||
126 | return 0; | 129 | return 0; |
127 | } | 130 | } |
128 | 131 | ||
@@ -186,41 +189,51 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) | |||
186 | return NULL; | 189 | return NULL; |
187 | } | 190 | } |
188 | 191 | ||
189 | /** | 192 | #ifdef CONFIG_CHECKPOINT_RESTORE |
190 | * ipc_get_maxid - get the last assigned id | 193 | /* |
191 | * @ids: ipc identifier set | 194 | * Specify desired id for next allocated IPC object. |
192 | * | ||
193 | * Called with ipc_ids.rwsem held. | ||
194 | */ | 195 | */ |
195 | int ipc_get_maxid(struct ipc_ids *ids) | 196 | #define ipc_idr_alloc(ids, new) \ |
197 | idr_alloc(&(ids)->ipcs_idr, (new), \ | ||
198 | (ids)->next_id < 0 ? 0 : ipcid_to_idx((ids)->next_id),\ | ||
199 | 0, GFP_NOWAIT) | ||
200 | |||
201 | static inline int ipc_buildid(int id, struct ipc_ids *ids, | ||
202 | struct kern_ipc_perm *new) | ||
196 | { | 203 | { |
197 | struct kern_ipc_perm *ipc; | 204 | if (ids->next_id < 0) { /* default, behave as !CHECKPOINT_RESTORE */ |
198 | int max_id = -1; | 205 | new->seq = ids->seq++; |
199 | int total, id; | 206 | if (ids->seq > IPCID_SEQ_MAX) |
207 | ids->seq = 0; | ||
208 | } else { | ||
209 | new->seq = ipcid_to_seqx(ids->next_id); | ||
210 | ids->next_id = -1; | ||
211 | } | ||
200 | 212 | ||
201 | if (ids->in_use == 0) | 213 | return SEQ_MULTIPLIER * new->seq + id; |
202 | return -1; | 214 | } |
203 | 215 | ||
204 | if (ids->in_use == IPCMNI) | 216 | #else |
205 | return IPCMNI - 1; | 217 | #define ipc_idr_alloc(ids, new) \ |
218 | idr_alloc(&(ids)->ipcs_idr, (new), 0, 0, GFP_NOWAIT) | ||
206 | 219 | ||
207 | /* Look for the last assigned id */ | 220 | static inline int ipc_buildid(int id, struct ipc_ids *ids, |
208 | total = 0; | 221 | struct kern_ipc_perm *new) |
209 | for (id = 0; id < IPCMNI && total < ids->in_use; id++) { | 222 | { |
210 | ipc = idr_find(&ids->ipcs_idr, id); | 223 | new->seq = ids->seq++; |
211 | if (ipc != NULL) { | 224 | if (ids->seq > IPCID_SEQ_MAX) |
212 | max_id = id; | 225 | ids->seq = 0; |
213 | total++; | 226 | |
214 | } | 227 | return SEQ_MULTIPLIER * new->seq + id; |
215 | } | ||
216 | return max_id; | ||
217 | } | 228 | } |
218 | 229 | ||
230 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | ||
231 | |||
219 | /** | 232 | /** |
220 | * ipc_addid - add an ipc identifier | 233 | * ipc_addid - add an ipc identifier |
221 | * @ids: ipc identifier set | 234 | * @ids: ipc identifier set |
222 | * @new: new ipc permission set | 235 | * @new: new ipc permission set |
223 | * @size: limit for the number of used ids | 236 | * @limit: limit for the number of used ids |
224 | * | 237 | * |
225 | * Add an entry 'new' to the ipc ids idr. The permissions object is | 238 | * Add an entry 'new' to the ipc ids idr. The permissions object is |
226 | * initialised and the first free entry is set up and the id assigned | 239 | * initialised and the first free entry is set up and the id assigned |
@@ -229,17 +242,16 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
229 | * | 242 | * |
230 | * Called with writer ipc_ids.rwsem held. | 243 | * Called with writer ipc_ids.rwsem held. |
231 | */ | 244 | */ |
232 | int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | 245 | int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit) |
233 | { | 246 | { |
234 | kuid_t euid; | 247 | kuid_t euid; |
235 | kgid_t egid; | 248 | kgid_t egid; |
236 | int id, err; | 249 | int id, err; |
237 | int next_id = ids->next_id; | ||
238 | 250 | ||
239 | if (size > IPCMNI) | 251 | if (limit > IPCMNI) |
240 | size = IPCMNI; | 252 | limit = IPCMNI; |
241 | 253 | ||
242 | if (!ids->tables_initialized || ids->in_use >= size) | 254 | if (!ids->tables_initialized || ids->in_use >= limit) |
243 | return -ENOSPC; | 255 | return -ENOSPC; |
244 | 256 | ||
245 | idr_preload(GFP_KERNEL); | 257 | idr_preload(GFP_KERNEL); |
@@ -254,9 +266,7 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | |||
254 | new->cuid = new->uid = euid; | 266 | new->cuid = new->uid = euid; |
255 | new->gid = new->cgid = egid; | 267 | new->gid = new->cgid = egid; |
256 | 268 | ||
257 | id = idr_alloc(&ids->ipcs_idr, new, | 269 | id = ipc_idr_alloc(ids, new); |
258 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, | ||
259 | GFP_NOWAIT); | ||
260 | idr_preload_end(); | 270 | idr_preload_end(); |
261 | 271 | ||
262 | if (id >= 0 && new->key != IPC_PRIVATE) { | 272 | if (id >= 0 && new->key != IPC_PRIVATE) { |
@@ -274,17 +284,11 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | |||
274 | } | 284 | } |
275 | 285 | ||
276 | ids->in_use++; | 286 | ids->in_use++; |
287 | if (id > ids->max_id) | ||
288 | ids->max_id = id; | ||
277 | 289 | ||
278 | if (next_id < 0) { | 290 | new->id = ipc_buildid(id, ids, new); |
279 | new->seq = ids->seq++; | ||
280 | if (ids->seq > IPCID_SEQ_MAX) | ||
281 | ids->seq = 0; | ||
282 | } else { | ||
283 | new->seq = ipcid_to_seqx(next_id); | ||
284 | ids->next_id = -1; | ||
285 | } | ||
286 | 291 | ||
287 | new->id = ipc_buildid(id, new->seq); | ||
288 | return id; | 292 | return id; |
289 | } | 293 | } |
290 | 294 | ||
@@ -429,6 +433,15 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) | |||
429 | ipc_kht_remove(ids, ipcp); | 433 | ipc_kht_remove(ids, ipcp); |
430 | ids->in_use--; | 434 | ids->in_use--; |
431 | ipcp->deleted = true; | 435 | ipcp->deleted = true; |
436 | |||
437 | if (unlikely(lid == ids->max_id)) { | ||
438 | do { | ||
439 | lid--; | ||
440 | if (lid == -1) | ||
441 | break; | ||
442 | } while (!idr_find(&ids->ipcs_idr, lid)); | ||
443 | ids->max_id = lid; | ||
444 | } | ||
432 | } | 445 | } |
433 | 446 | ||
434 | /** | 447 | /** |
diff --git a/ipc/util.h b/ipc/util.h index 579112d90016..89b8ec176fc4 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/unistd.h> | 14 | #include <linux/unistd.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/ipc_namespace.h> | ||
16 | 17 | ||
17 | #define SEQ_MULTIPLIER (IPCMNI) | 18 | #define SEQ_MULTIPLIER (IPCMNI) |
18 | 19 | ||
@@ -99,9 +100,6 @@ void __init ipc_init_proc_interface(const char *path, const char *header, | |||
99 | /* must be called with ids->rwsem acquired for writing */ | 100 | /* must be called with ids->rwsem acquired for writing */ |
100 | int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); | 101 | int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); |
101 | 102 | ||
102 | /* must be called with ids->rwsem acquired for reading */ | ||
103 | int ipc_get_maxid(struct ipc_ids *); | ||
104 | |||
105 | /* must be called with both locks acquired. */ | 103 | /* must be called with both locks acquired. */ |
106 | void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); | 104 | void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); |
107 | 105 | ||
@@ -111,6 +109,23 @@ void ipc_set_key_private(struct ipc_ids *, struct kern_ipc_perm *); | |||
111 | /* must be called with ipcp locked */ | 109 | /* must be called with ipcp locked */ |
112 | int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg); | 110 | int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg); |
113 | 111 | ||
112 | /** | ||
113 | * ipc_get_maxid - get the last assigned id | ||
114 | * @ids: ipc identifier set | ||
115 | * | ||
116 | * Called with ipc_ids.rwsem held for reading. | ||
117 | */ | ||
118 | static inline int ipc_get_maxid(struct ipc_ids *ids) | ||
119 | { | ||
120 | if (ids->in_use == 0) | ||
121 | return -1; | ||
122 | |||
123 | if (ids->in_use == IPCMNI) | ||
124 | return IPCMNI - 1; | ||
125 | |||
126 | return ids->max_id; | ||
127 | } | ||
128 | |||
114 | /* | 129 | /* |
115 | * For allocation that need to be freed by RCU. | 130 | * For allocation that need to be freed by RCU. |
116 | * Objects are reference counted, they start with reference count 1. | 131 | * Objects are reference counted, they start with reference count 1. |
@@ -146,11 +161,6 @@ extern struct msg_msg *load_msg(const void __user *src, size_t len); | |||
146 | extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst); | 161 | extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst); |
147 | extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len); | 162 | extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len); |
148 | 163 | ||
149 | static inline int ipc_buildid(int id, int seq) | ||
150 | { | ||
151 | return SEQ_MULTIPLIER * seq + id; | ||
152 | } | ||
153 | |||
154 | static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) | 164 | static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) |
155 | { | 165 | { |
156 | return uid / SEQ_MULTIPLIER != ipcp->seq; | 166 | return uid / SEQ_MULTIPLIER != ipcp->seq; |
diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 6db80fc0810b..b3663896278e 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c | |||
@@ -108,7 +108,8 @@ static int __init parse_crashkernel_mem(char *cmdline, | |||
108 | return -EINVAL; | 108 | return -EINVAL; |
109 | } | 109 | } |
110 | } | 110 | } |
111 | } | 111 | } else |
112 | pr_info("crashkernel size resulted in zero bytes\n"); | ||
112 | 113 | ||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
diff --git a/kernel/fork.c b/kernel/fork.c index 4e55eedba8d6..432eadf6b58c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1871,7 +1871,7 @@ static __latent_entropy struct task_struct *copy_process( | |||
1871 | retval = -ERESTARTNOINTR; | 1871 | retval = -ERESTARTNOINTR; |
1872 | goto bad_fork_cancel_cgroup; | 1872 | goto bad_fork_cancel_cgroup; |
1873 | } | 1873 | } |
1874 | if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) { | 1874 | if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) { |
1875 | retval = -ENOMEM; | 1875 | retval = -ENOMEM; |
1876 | goto bad_fork_cancel_cgroup; | 1876 | goto bad_fork_cancel_cgroup; |
1877 | } | 1877 | } |
diff --git a/kernel/kcov.c b/kernel/kcov.c index fc6af9e1308b..15f33faf4013 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c | |||
@@ -22,13 +22,21 @@ | |||
22 | #include <linux/kcov.h> | 22 | #include <linux/kcov.h> |
23 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
24 | 24 | ||
25 | /* Number of 64-bit words written per one comparison: */ | ||
26 | #define KCOV_WORDS_PER_CMP 4 | ||
27 | |||
25 | /* | 28 | /* |
26 | * kcov descriptor (one per opened debugfs file). | 29 | * kcov descriptor (one per opened debugfs file). |
27 | * State transitions of the descriptor: | 30 | * State transitions of the descriptor: |
28 | * - initial state after open() | 31 | * - initial state after open() |
29 | * - then there must be a single ioctl(KCOV_INIT_TRACE) call | 32 | * - then there must be a single ioctl(KCOV_INIT_TRACE) call |
30 | * - then, mmap() call (several calls are allowed but not useful) | 33 | * - then, mmap() call (several calls are allowed but not useful) |
31 | * - then, repeated enable/disable for a task (only one task a time allowed) | 34 | * - then, ioctl(KCOV_ENABLE, arg), where arg is |
35 | * KCOV_TRACE_PC - to trace only the PCs | ||
36 | * or | ||
37 | * KCOV_TRACE_CMP - to trace only the comparison operands | ||
38 | * - then, ioctl(KCOV_DISABLE) to disable the task. | ||
39 | * Enabling/disabling ioctls can be repeated (only one task a time allowed). | ||
32 | */ | 40 | */ |
33 | struct kcov { | 41 | struct kcov { |
34 | /* | 42 | /* |
@@ -48,51 +56,176 @@ struct kcov { | |||
48 | struct task_struct *t; | 56 | struct task_struct *t; |
49 | }; | 57 | }; |
50 | 58 | ||
51 | /* | 59 | static bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) |
52 | * Entry point from instrumented code. | ||
53 | * This is called once per basic-block/edge. | ||
54 | */ | ||
55 | void notrace __sanitizer_cov_trace_pc(void) | ||
56 | { | 60 | { |
57 | struct task_struct *t; | ||
58 | enum kcov_mode mode; | 61 | enum kcov_mode mode; |
59 | 62 | ||
60 | t = current; | ||
61 | /* | 63 | /* |
62 | * We are interested in code coverage as a function of a syscall inputs, | 64 | * We are interested in code coverage as a function of a syscall inputs, |
63 | * so we ignore code executed in interrupts. | 65 | * so we ignore code executed in interrupts. |
64 | */ | 66 | */ |
65 | if (!t || !in_task()) | 67 | if (!in_task()) |
66 | return; | 68 | return false; |
67 | mode = READ_ONCE(t->kcov_mode); | 69 | mode = READ_ONCE(t->kcov_mode); |
68 | if (mode == KCOV_MODE_TRACE) { | 70 | /* |
69 | unsigned long *area; | 71 | * There is some code that runs in interrupts but for which |
70 | unsigned long pos; | 72 | * in_interrupt() returns false (e.g. preempt_schedule_irq()). |
71 | unsigned long ip = _RET_IP_; | 73 | * READ_ONCE()/barrier() effectively provides load-acquire wrt |
74 | * interrupts, there are paired barrier()/WRITE_ONCE() in | ||
75 | * kcov_ioctl_locked(). | ||
76 | */ | ||
77 | barrier(); | ||
78 | return mode == needed_mode; | ||
79 | } | ||
72 | 80 | ||
81 | static unsigned long canonicalize_ip(unsigned long ip) | ||
82 | { | ||
73 | #ifdef CONFIG_RANDOMIZE_BASE | 83 | #ifdef CONFIG_RANDOMIZE_BASE |
74 | ip -= kaslr_offset(); | 84 | ip -= kaslr_offset(); |
75 | #endif | 85 | #endif |
86 | return ip; | ||
87 | } | ||
76 | 88 | ||
77 | /* | 89 | /* |
78 | * There is some code that runs in interrupts but for which | 90 | * Entry point from instrumented code. |
79 | * in_interrupt() returns false (e.g. preempt_schedule_irq()). | 91 | * This is called once per basic-block/edge. |
80 | * READ_ONCE()/barrier() effectively provides load-acquire wrt | 92 | */ |
81 | * interrupts, there are paired barrier()/WRITE_ONCE() in | 93 | void notrace __sanitizer_cov_trace_pc(void) |
82 | * kcov_ioctl_locked(). | 94 | { |
83 | */ | 95 | struct task_struct *t; |
84 | barrier(); | 96 | unsigned long *area; |
85 | area = t->kcov_area; | 97 | unsigned long ip = canonicalize_ip(_RET_IP_); |
86 | /* The first word is number of subsequent PCs. */ | 98 | unsigned long pos; |
87 | pos = READ_ONCE(area[0]) + 1; | 99 | |
88 | if (likely(pos < t->kcov_size)) { | 100 | t = current; |
89 | area[pos] = ip; | 101 | if (!check_kcov_mode(KCOV_MODE_TRACE_PC, t)) |
90 | WRITE_ONCE(area[0], pos); | 102 | return; |
91 | } | 103 | |
104 | area = t->kcov_area; | ||
105 | /* The first 64-bit word is the number of subsequent PCs. */ | ||
106 | pos = READ_ONCE(area[0]) + 1; | ||
107 | if (likely(pos < t->kcov_size)) { | ||
108 | area[pos] = ip; | ||
109 | WRITE_ONCE(area[0], pos); | ||
92 | } | 110 | } |
93 | } | 111 | } |
94 | EXPORT_SYMBOL(__sanitizer_cov_trace_pc); | 112 | EXPORT_SYMBOL(__sanitizer_cov_trace_pc); |
95 | 113 | ||
114 | #ifdef CONFIG_KCOV_ENABLE_COMPARISONS | ||
115 | static void write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip) | ||
116 | { | ||
117 | struct task_struct *t; | ||
118 | u64 *area; | ||
119 | u64 count, start_index, end_pos, max_pos; | ||
120 | |||
121 | t = current; | ||
122 | if (!check_kcov_mode(KCOV_MODE_TRACE_CMP, t)) | ||
123 | return; | ||
124 | |||
125 | ip = canonicalize_ip(ip); | ||
126 | |||
127 | /* | ||
128 | * We write all comparison arguments and types as u64. | ||
129 | * The buffer was allocated for t->kcov_size unsigned longs. | ||
130 | */ | ||
131 | area = (u64 *)t->kcov_area; | ||
132 | max_pos = t->kcov_size * sizeof(unsigned long); | ||
133 | |||
134 | count = READ_ONCE(area[0]); | ||
135 | |||
136 | /* Every record is KCOV_WORDS_PER_CMP 64-bit words. */ | ||
137 | start_index = 1 + count * KCOV_WORDS_PER_CMP; | ||
138 | end_pos = (start_index + KCOV_WORDS_PER_CMP) * sizeof(u64); | ||
139 | if (likely(end_pos <= max_pos)) { | ||
140 | area[start_index] = type; | ||
141 | area[start_index + 1] = arg1; | ||
142 | area[start_index + 2] = arg2; | ||
143 | area[start_index + 3] = ip; | ||
144 | WRITE_ONCE(area[0], count + 1); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | void notrace __sanitizer_cov_trace_cmp1(u8 arg1, u8 arg2) | ||
149 | { | ||
150 | write_comp_data(KCOV_CMP_SIZE(0), arg1, arg2, _RET_IP_); | ||
151 | } | ||
152 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp1); | ||
153 | |||
154 | void notrace __sanitizer_cov_trace_cmp2(u16 arg1, u16 arg2) | ||
155 | { | ||
156 | write_comp_data(KCOV_CMP_SIZE(1), arg1, arg2, _RET_IP_); | ||
157 | } | ||
158 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp2); | ||
159 | |||
160 | void notrace __sanitizer_cov_trace_cmp4(u16 arg1, u16 arg2) | ||
161 | { | ||
162 | write_comp_data(KCOV_CMP_SIZE(2), arg1, arg2, _RET_IP_); | ||
163 | } | ||
164 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp4); | ||
165 | |||
166 | void notrace __sanitizer_cov_trace_cmp8(u64 arg1, u64 arg2) | ||
167 | { | ||
168 | write_comp_data(KCOV_CMP_SIZE(3), arg1, arg2, _RET_IP_); | ||
169 | } | ||
170 | EXPORT_SYMBOL(__sanitizer_cov_trace_cmp8); | ||
171 | |||
172 | void notrace __sanitizer_cov_trace_const_cmp1(u8 arg1, u8 arg2) | ||
173 | { | ||
174 | write_comp_data(KCOV_CMP_SIZE(0) | KCOV_CMP_CONST, arg1, arg2, | ||
175 | _RET_IP_); | ||
176 | } | ||
177 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp1); | ||
178 | |||
179 | void notrace __sanitizer_cov_trace_const_cmp2(u16 arg1, u16 arg2) | ||
180 | { | ||
181 | write_comp_data(KCOV_CMP_SIZE(1) | KCOV_CMP_CONST, arg1, arg2, | ||
182 | _RET_IP_); | ||
183 | } | ||
184 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp2); | ||
185 | |||
186 | void notrace __sanitizer_cov_trace_const_cmp4(u16 arg1, u16 arg2) | ||
187 | { | ||
188 | write_comp_data(KCOV_CMP_SIZE(2) | KCOV_CMP_CONST, arg1, arg2, | ||
189 | _RET_IP_); | ||
190 | } | ||
191 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp4); | ||
192 | |||
193 | void notrace __sanitizer_cov_trace_const_cmp8(u64 arg1, u64 arg2) | ||
194 | { | ||
195 | write_comp_data(KCOV_CMP_SIZE(3) | KCOV_CMP_CONST, arg1, arg2, | ||
196 | _RET_IP_); | ||
197 | } | ||
198 | EXPORT_SYMBOL(__sanitizer_cov_trace_const_cmp8); | ||
199 | |||
200 | void notrace __sanitizer_cov_trace_switch(u64 val, u64 *cases) | ||
201 | { | ||
202 | u64 i; | ||
203 | u64 count = cases[0]; | ||
204 | u64 size = cases[1]; | ||
205 | u64 type = KCOV_CMP_CONST; | ||
206 | |||
207 | switch (size) { | ||
208 | case 8: | ||
209 | type |= KCOV_CMP_SIZE(0); | ||
210 | break; | ||
211 | case 16: | ||
212 | type |= KCOV_CMP_SIZE(1); | ||
213 | break; | ||
214 | case 32: | ||
215 | type |= KCOV_CMP_SIZE(2); | ||
216 | break; | ||
217 | case 64: | ||
218 | type |= KCOV_CMP_SIZE(3); | ||
219 | break; | ||
220 | default: | ||
221 | return; | ||
222 | } | ||
223 | for (i = 0; i < count; i++) | ||
224 | write_comp_data(type, cases[i + 2], val, _RET_IP_); | ||
225 | } | ||
226 | EXPORT_SYMBOL(__sanitizer_cov_trace_switch); | ||
227 | #endif /* ifdef CONFIG_KCOV_ENABLE_COMPARISONS */ | ||
228 | |||
96 | static void kcov_get(struct kcov *kcov) | 229 | static void kcov_get(struct kcov *kcov) |
97 | { | 230 | { |
98 | atomic_inc(&kcov->refcount); | 231 | atomic_inc(&kcov->refcount); |
@@ -129,6 +262,7 @@ void kcov_task_exit(struct task_struct *t) | |||
129 | /* Just to not leave dangling references behind. */ | 262 | /* Just to not leave dangling references behind. */ |
130 | kcov_task_init(t); | 263 | kcov_task_init(t); |
131 | kcov->t = NULL; | 264 | kcov->t = NULL; |
265 | kcov->mode = KCOV_MODE_INIT; | ||
132 | spin_unlock(&kcov->lock); | 266 | spin_unlock(&kcov->lock); |
133 | kcov_put(kcov); | 267 | kcov_put(kcov); |
134 | } | 268 | } |
@@ -147,7 +281,7 @@ static int kcov_mmap(struct file *filep, struct vm_area_struct *vma) | |||
147 | 281 | ||
148 | spin_lock(&kcov->lock); | 282 | spin_lock(&kcov->lock); |
149 | size = kcov->size * sizeof(unsigned long); | 283 | size = kcov->size * sizeof(unsigned long); |
150 | if (kcov->mode == KCOV_MODE_DISABLED || vma->vm_pgoff != 0 || | 284 | if (kcov->mode != KCOV_MODE_INIT || vma->vm_pgoff != 0 || |
151 | vma->vm_end - vma->vm_start != size) { | 285 | vma->vm_end - vma->vm_start != size) { |
152 | res = -EINVAL; | 286 | res = -EINVAL; |
153 | goto exit; | 287 | goto exit; |
@@ -176,6 +310,7 @@ static int kcov_open(struct inode *inode, struct file *filep) | |||
176 | kcov = kzalloc(sizeof(*kcov), GFP_KERNEL); | 310 | kcov = kzalloc(sizeof(*kcov), GFP_KERNEL); |
177 | if (!kcov) | 311 | if (!kcov) |
178 | return -ENOMEM; | 312 | return -ENOMEM; |
313 | kcov->mode = KCOV_MODE_DISABLED; | ||
179 | atomic_set(&kcov->refcount, 1); | 314 | atomic_set(&kcov->refcount, 1); |
180 | spin_lock_init(&kcov->lock); | 315 | spin_lock_init(&kcov->lock); |
181 | filep->private_data = kcov; | 316 | filep->private_data = kcov; |
@@ -211,7 +346,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, | |||
211 | if (size < 2 || size > INT_MAX / sizeof(unsigned long)) | 346 | if (size < 2 || size > INT_MAX / sizeof(unsigned long)) |
212 | return -EINVAL; | 347 | return -EINVAL; |
213 | kcov->size = size; | 348 | kcov->size = size; |
214 | kcov->mode = KCOV_MODE_TRACE; | 349 | kcov->mode = KCOV_MODE_INIT; |
215 | return 0; | 350 | return 0; |
216 | case KCOV_ENABLE: | 351 | case KCOV_ENABLE: |
217 | /* | 352 | /* |
@@ -221,17 +356,25 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, | |||
221 | * at task exit or voluntary by KCOV_DISABLE. After that it can | 356 | * at task exit or voluntary by KCOV_DISABLE. After that it can |
222 | * be enabled for another task. | 357 | * be enabled for another task. |
223 | */ | 358 | */ |
224 | unused = arg; | 359 | if (kcov->mode != KCOV_MODE_INIT || !kcov->area) |
225 | if (unused != 0 || kcov->mode == KCOV_MODE_DISABLED || | ||
226 | kcov->area == NULL) | ||
227 | return -EINVAL; | 360 | return -EINVAL; |
228 | if (kcov->t != NULL) | 361 | if (kcov->t != NULL) |
229 | return -EBUSY; | 362 | return -EBUSY; |
363 | if (arg == KCOV_TRACE_PC) | ||
364 | kcov->mode = KCOV_MODE_TRACE_PC; | ||
365 | else if (arg == KCOV_TRACE_CMP) | ||
366 | #ifdef CONFIG_KCOV_ENABLE_COMPARISONS | ||
367 | kcov->mode = KCOV_MODE_TRACE_CMP; | ||
368 | #else | ||
369 | return -ENOTSUPP; | ||
370 | #endif | ||
371 | else | ||
372 | return -EINVAL; | ||
230 | t = current; | 373 | t = current; |
231 | /* Cache in task struct for performance. */ | 374 | /* Cache in task struct for performance. */ |
232 | t->kcov_size = kcov->size; | 375 | t->kcov_size = kcov->size; |
233 | t->kcov_area = kcov->area; | 376 | t->kcov_area = kcov->area; |
234 | /* See comment in __sanitizer_cov_trace_pc(). */ | 377 | /* See comment in check_kcov_mode(). */ |
235 | barrier(); | 378 | barrier(); |
236 | WRITE_ONCE(t->kcov_mode, kcov->mode); | 379 | WRITE_ONCE(t->kcov_mode, kcov->mode); |
237 | t->kcov = kcov; | 380 | t->kcov = kcov; |
@@ -249,6 +392,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, | |||
249 | return -EINVAL; | 392 | return -EINVAL; |
250 | kcov_task_init(t); | 393 | kcov_task_init(t); |
251 | kcov->t = NULL; | 394 | kcov->t = NULL; |
395 | kcov->mode = KCOV_MODE_INIT; | ||
252 | kcov_put(kcov); | 396 | kcov_put(kcov); |
253 | return 0; | 397 | return 0; |
254 | default: | 398 | default: |
diff --git a/kernel/panic.c b/kernel/panic.c index bdd18afa19a4..2cfef408fec9 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/console.h> | 27 | #include <linux/console.h> |
28 | #include <linux/bug.h> | 28 | #include <linux/bug.h> |
29 | #include <linux/ratelimit.h> | 29 | #include <linux/ratelimit.h> |
30 | #include <linux/debugfs.h> | ||
31 | #include <asm/sections.h> | ||
30 | 32 | ||
31 | #define PANIC_TIMER_STEP 100 | 33 | #define PANIC_TIMER_STEP 100 |
32 | #define PANIC_BLINK_SPD 18 | 34 | #define PANIC_BLINK_SPD 18 |
@@ -322,6 +324,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = { | |||
322 | { 'E', ' ', true }, /* TAINT_UNSIGNED_MODULE */ | 324 | { 'E', ' ', true }, /* TAINT_UNSIGNED_MODULE */ |
323 | { 'L', ' ', false }, /* TAINT_SOFTLOCKUP */ | 325 | { 'L', ' ', false }, /* TAINT_SOFTLOCKUP */ |
324 | { 'K', ' ', true }, /* TAINT_LIVEPATCH */ | 326 | { 'K', ' ', true }, /* TAINT_LIVEPATCH */ |
327 | { 'X', ' ', true }, /* TAINT_AUX */ | ||
325 | }; | 328 | }; |
326 | 329 | ||
327 | /** | 330 | /** |
@@ -343,6 +346,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = { | |||
343 | * 'E' - Unsigned module has been loaded. | 346 | * 'E' - Unsigned module has been loaded. |
344 | * 'L' - A soft lockup has previously occurred. | 347 | * 'L' - A soft lockup has previously occurred. |
345 | * 'K' - Kernel has been live patched. | 348 | * 'K' - Kernel has been live patched. |
349 | * 'X' - Auxiliary taint, for distros' use. | ||
346 | * | 350 | * |
347 | * The string is overwritten by the next call to print_tainted(). | 351 | * The string is overwritten by the next call to print_tainted(). |
348 | */ | 352 | */ |
@@ -518,7 +522,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, | |||
518 | { | 522 | { |
519 | disable_trace_on_warning(); | 523 | disable_trace_on_warning(); |
520 | 524 | ||
521 | pr_warn("------------[ cut here ]------------\n"); | 525 | if (args) |
526 | pr_warn(CUT_HERE); | ||
522 | 527 | ||
523 | if (file) | 528 | if (file) |
524 | pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", | 529 | pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", |
@@ -582,9 +587,49 @@ EXPORT_SYMBOL(warn_slowpath_fmt_taint); | |||
582 | 587 | ||
583 | void warn_slowpath_null(const char *file, int line) | 588 | void warn_slowpath_null(const char *file, int line) |
584 | { | 589 | { |
590 | pr_warn(CUT_HERE); | ||
585 | __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); | 591 | __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); |
586 | } | 592 | } |
587 | EXPORT_SYMBOL(warn_slowpath_null); | 593 | EXPORT_SYMBOL(warn_slowpath_null); |
594 | #else | ||
595 | void __warn_printk(const char *fmt, ...) | ||
596 | { | ||
597 | va_list args; | ||
598 | |||
599 | pr_warn(CUT_HERE); | ||
600 | |||
601 | va_start(args, fmt); | ||
602 | vprintk(fmt, args); | ||
603 | va_end(args); | ||
604 | } | ||
605 | EXPORT_SYMBOL(__warn_printk); | ||
606 | #endif | ||
607 | |||
608 | #ifdef CONFIG_BUG | ||
609 | |||
610 | /* Support resetting WARN*_ONCE state */ | ||
611 | |||
612 | static int clear_warn_once_set(void *data, u64 val) | ||
613 | { | ||
614 | generic_bug_clear_once(); | ||
615 | memset(__start_once, 0, __end_once - __start_once); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | DEFINE_SIMPLE_ATTRIBUTE(clear_warn_once_fops, | ||
620 | NULL, | ||
621 | clear_warn_once_set, | ||
622 | "%lld\n"); | ||
623 | |||
624 | static __init int register_warn_debugfs(void) | ||
625 | { | ||
626 | /* Don't care about failure */ | ||
627 | debugfs_create_file("clear_warn_once", 0200, NULL, | ||
628 | NULL, &clear_warn_once_fops); | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | device_initcall(register_warn_debugfs); | ||
588 | #endif | 633 | #endif |
589 | 634 | ||
590 | #ifdef CONFIG_CC_STACKPROTECTOR | 635 | #ifdef CONFIG_CC_STACKPROTECTOR |
diff --git a/kernel/pid.c b/kernel/pid.c index 020dedbdf066..b13b624e2c49 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -39,11 +39,8 @@ | |||
39 | #include <linux/proc_ns.h> | 39 | #include <linux/proc_ns.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/sched/task.h> | 41 | #include <linux/sched/task.h> |
42 | #include <linux/idr.h> | ||
42 | 43 | ||
43 | #define pid_hashfn(nr, ns) \ | ||
44 | hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) | ||
45 | static struct hlist_head *pid_hash; | ||
46 | static unsigned int pidhash_shift = 4; | ||
47 | struct pid init_struct_pid = INIT_STRUCT_PID; | 44 | struct pid init_struct_pid = INIT_STRUCT_PID; |
48 | 45 | ||
49 | int pid_max = PID_MAX_DEFAULT; | 46 | int pid_max = PID_MAX_DEFAULT; |
@@ -53,15 +50,6 @@ int pid_max = PID_MAX_DEFAULT; | |||
53 | int pid_max_min = RESERVED_PIDS + 1; | 50 | int pid_max_min = RESERVED_PIDS + 1; |
54 | int pid_max_max = PID_MAX_LIMIT; | 51 | int pid_max_max = PID_MAX_LIMIT; |
55 | 52 | ||
56 | static inline int mk_pid(struct pid_namespace *pid_ns, | ||
57 | struct pidmap *map, int off) | ||
58 | { | ||
59 | return (map - pid_ns->pidmap)*BITS_PER_PAGE + off; | ||
60 | } | ||
61 | |||
62 | #define find_next_offset(map, off) \ | ||
63 | find_next_zero_bit((map)->page, BITS_PER_PAGE, off) | ||
64 | |||
65 | /* | 53 | /* |
66 | * PID-map pages start out as NULL, they get allocated upon | 54 | * PID-map pages start out as NULL, they get allocated upon |
67 | * first use and are never deallocated. This way a low pid_max | 55 | * first use and are never deallocated. This way a low pid_max |
@@ -70,11 +58,8 @@ static inline int mk_pid(struct pid_namespace *pid_ns, | |||
70 | */ | 58 | */ |
71 | struct pid_namespace init_pid_ns = { | 59 | struct pid_namespace init_pid_ns = { |
72 | .kref = KREF_INIT(2), | 60 | .kref = KREF_INIT(2), |
73 | .pidmap = { | 61 | .idr = IDR_INIT, |
74 | [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } | 62 | .pid_allocated = PIDNS_ADDING, |
75 | }, | ||
76 | .last_pid = 0, | ||
77 | .nr_hashed = PIDNS_HASH_ADDING, | ||
78 | .level = 0, | 63 | .level = 0, |
79 | .child_reaper = &init_task, | 64 | .child_reaper = &init_task, |
80 | .user_ns = &init_user_ns, | 65 | .user_ns = &init_user_ns, |
@@ -101,138 +86,6 @@ EXPORT_SYMBOL_GPL(init_pid_ns); | |||
101 | 86 | ||
102 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); | 87 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); |
103 | 88 | ||
104 | static void free_pidmap(struct upid *upid) | ||
105 | { | ||
106 | int nr = upid->nr; | ||
107 | struct pidmap *map = upid->ns->pidmap + nr / BITS_PER_PAGE; | ||
108 | int offset = nr & BITS_PER_PAGE_MASK; | ||
109 | |||
110 | clear_bit(offset, map->page); | ||
111 | atomic_inc(&map->nr_free); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * If we started walking pids at 'base', is 'a' seen before 'b'? | ||
116 | */ | ||
117 | static int pid_before(int base, int a, int b) | ||
118 | { | ||
119 | /* | ||
120 | * This is the same as saying | ||
121 | * | ||
122 | * (a - base + MAXUINT) % MAXUINT < (b - base + MAXUINT) % MAXUINT | ||
123 | * and that mapping orders 'a' and 'b' with respect to 'base'. | ||
124 | */ | ||
125 | return (unsigned)(a - base) < (unsigned)(b - base); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * We might be racing with someone else trying to set pid_ns->last_pid | ||
130 | * at the pid allocation time (there's also a sysctl for this, but racing | ||
131 | * with this one is OK, see comment in kernel/pid_namespace.c about it). | ||
132 | * We want the winner to have the "later" value, because if the | ||
133 | * "earlier" value prevails, then a pid may get reused immediately. | ||
134 | * | ||
135 | * Since pids rollover, it is not sufficient to just pick the bigger | ||
136 | * value. We have to consider where we started counting from. | ||
137 | * | ||
138 | * 'base' is the value of pid_ns->last_pid that we observed when | ||
139 | * we started looking for a pid. | ||
140 | * | ||
141 | * 'pid' is the pid that we eventually found. | ||
142 | */ | ||
143 | static void set_last_pid(struct pid_namespace *pid_ns, int base, int pid) | ||
144 | { | ||
145 | int prev; | ||
146 | int last_write = base; | ||
147 | do { | ||
148 | prev = last_write; | ||
149 | last_write = cmpxchg(&pid_ns->last_pid, prev, pid); | ||
150 | } while ((prev != last_write) && (pid_before(base, last_write, pid))); | ||
151 | } | ||
152 | |||
153 | static int alloc_pidmap(struct pid_namespace *pid_ns) | ||
154 | { | ||
155 | int i, offset, max_scan, pid, last = pid_ns->last_pid; | ||
156 | struct pidmap *map; | ||
157 | |||
158 | pid = last + 1; | ||
159 | if (pid >= pid_max) | ||
160 | pid = RESERVED_PIDS; | ||
161 | offset = pid & BITS_PER_PAGE_MASK; | ||
162 | map = &pid_ns->pidmap[pid/BITS_PER_PAGE]; | ||
163 | /* | ||
164 | * If last_pid points into the middle of the map->page we | ||
165 | * want to scan this bitmap block twice, the second time | ||
166 | * we start with offset == 0 (or RESERVED_PIDS). | ||
167 | */ | ||
168 | max_scan = DIV_ROUND_UP(pid_max, BITS_PER_PAGE) - !offset; | ||
169 | for (i = 0; i <= max_scan; ++i) { | ||
170 | if (unlikely(!map->page)) { | ||
171 | void *page = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
172 | /* | ||
173 | * Free the page if someone raced with us | ||
174 | * installing it: | ||
175 | */ | ||
176 | spin_lock_irq(&pidmap_lock); | ||
177 | if (!map->page) { | ||
178 | map->page = page; | ||
179 | page = NULL; | ||
180 | } | ||
181 | spin_unlock_irq(&pidmap_lock); | ||
182 | kfree(page); | ||
183 | if (unlikely(!map->page)) | ||
184 | return -ENOMEM; | ||
185 | } | ||
186 | if (likely(atomic_read(&map->nr_free))) { | ||
187 | for ( ; ; ) { | ||
188 | if (!test_and_set_bit(offset, map->page)) { | ||
189 | atomic_dec(&map->nr_free); | ||
190 | set_last_pid(pid_ns, last, pid); | ||
191 | return pid; | ||
192 | } | ||
193 | offset = find_next_offset(map, offset); | ||
194 | if (offset >= BITS_PER_PAGE) | ||
195 | break; | ||
196 | pid = mk_pid(pid_ns, map, offset); | ||
197 | if (pid >= pid_max) | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | if (map < &pid_ns->pidmap[(pid_max-1)/BITS_PER_PAGE]) { | ||
202 | ++map; | ||
203 | offset = 0; | ||
204 | } else { | ||
205 | map = &pid_ns->pidmap[0]; | ||
206 | offset = RESERVED_PIDS; | ||
207 | if (unlikely(last == offset)) | ||
208 | break; | ||
209 | } | ||
210 | pid = mk_pid(pid_ns, map, offset); | ||
211 | } | ||
212 | return -EAGAIN; | ||
213 | } | ||
214 | |||
215 | int next_pidmap(struct pid_namespace *pid_ns, unsigned int last) | ||
216 | { | ||
217 | int offset; | ||
218 | struct pidmap *map, *end; | ||
219 | |||
220 | if (last >= PID_MAX_LIMIT) | ||
221 | return -1; | ||
222 | |||
223 | offset = (last + 1) & BITS_PER_PAGE_MASK; | ||
224 | map = &pid_ns->pidmap[(last + 1)/BITS_PER_PAGE]; | ||
225 | end = &pid_ns->pidmap[PIDMAP_ENTRIES]; | ||
226 | for (; map < end; map++, offset = 0) { | ||
227 | if (unlikely(!map->page)) | ||
228 | continue; | ||
229 | offset = find_next_bit((map)->page, BITS_PER_PAGE, offset); | ||
230 | if (offset < BITS_PER_PAGE) | ||
231 | return mk_pid(pid_ns, map, offset); | ||
232 | } | ||
233 | return -1; | ||
234 | } | ||
235 | |||
236 | void put_pid(struct pid *pid) | 89 | void put_pid(struct pid *pid) |
237 | { | 90 | { |
238 | struct pid_namespace *ns; | 91 | struct pid_namespace *ns; |
@@ -265,8 +118,7 @@ void free_pid(struct pid *pid) | |||
265 | for (i = 0; i <= pid->level; i++) { | 118 | for (i = 0; i <= pid->level; i++) { |
266 | struct upid *upid = pid->numbers + i; | 119 | struct upid *upid = pid->numbers + i; |
267 | struct pid_namespace *ns = upid->ns; | 120 | struct pid_namespace *ns = upid->ns; |
268 | hlist_del_rcu(&upid->pid_chain); | 121 | switch (--ns->pid_allocated) { |
269 | switch(--ns->nr_hashed) { | ||
270 | case 2: | 122 | case 2: |
271 | case 1: | 123 | case 1: |
272 | /* When all that is left in the pid namespace | 124 | /* When all that is left in the pid namespace |
@@ -275,21 +127,20 @@ void free_pid(struct pid *pid) | |||
275 | */ | 127 | */ |
276 | wake_up_process(ns->child_reaper); | 128 | wake_up_process(ns->child_reaper); |
277 | break; | 129 | break; |
278 | case PIDNS_HASH_ADDING: | 130 | case PIDNS_ADDING: |
279 | /* Handle a fork failure of the first process */ | 131 | /* Handle a fork failure of the first process */ |
280 | WARN_ON(ns->child_reaper); | 132 | WARN_ON(ns->child_reaper); |
281 | ns->nr_hashed = 0; | 133 | ns->pid_allocated = 0; |
282 | /* fall through */ | 134 | /* fall through */ |
283 | case 0: | 135 | case 0: |
284 | schedule_work(&ns->proc_work); | 136 | schedule_work(&ns->proc_work); |
285 | break; | 137 | break; |
286 | } | 138 | } |
139 | |||
140 | idr_remove(&ns->idr, upid->nr); | ||
287 | } | 141 | } |
288 | spin_unlock_irqrestore(&pidmap_lock, flags); | 142 | spin_unlock_irqrestore(&pidmap_lock, flags); |
289 | 143 | ||
290 | for (i = 0; i <= pid->level; i++) | ||
291 | free_pidmap(pid->numbers + i); | ||
292 | |||
293 | call_rcu(&pid->rcu, delayed_put_pid); | 144 | call_rcu(&pid->rcu, delayed_put_pid); |
294 | } | 145 | } |
295 | 146 | ||
@@ -308,8 +159,29 @@ struct pid *alloc_pid(struct pid_namespace *ns) | |||
308 | 159 | ||
309 | tmp = ns; | 160 | tmp = ns; |
310 | pid->level = ns->level; | 161 | pid->level = ns->level; |
162 | |||
311 | for (i = ns->level; i >= 0; i--) { | 163 | for (i = ns->level; i >= 0; i--) { |
312 | nr = alloc_pidmap(tmp); | 164 | int pid_min = 1; |
165 | |||
166 | idr_preload(GFP_KERNEL); | ||
167 | spin_lock_irq(&pidmap_lock); | ||
168 | |||
169 | /* | ||
170 | * init really needs pid 1, but after reaching the maximum | ||
171 | * wrap back to RESERVED_PIDS | ||
172 | */ | ||
173 | if (idr_get_cursor(&tmp->idr) > RESERVED_PIDS) | ||
174 | pid_min = RESERVED_PIDS; | ||
175 | |||
176 | /* | ||
177 | * Store a null pointer so find_pid_ns does not find | ||
178 | * a partially initialized PID (see below). | ||
179 | */ | ||
180 | nr = idr_alloc_cyclic(&tmp->idr, NULL, pid_min, | ||
181 | pid_max, GFP_ATOMIC); | ||
182 | spin_unlock_irq(&pidmap_lock); | ||
183 | idr_preload_end(); | ||
184 | |||
313 | if (nr < 0) { | 185 | if (nr < 0) { |
314 | retval = nr; | 186 | retval = nr; |
315 | goto out_free; | 187 | goto out_free; |
@@ -334,12 +206,12 @@ struct pid *alloc_pid(struct pid_namespace *ns) | |||
334 | 206 | ||
335 | upid = pid->numbers + ns->level; | 207 | upid = pid->numbers + ns->level; |
336 | spin_lock_irq(&pidmap_lock); | 208 | spin_lock_irq(&pidmap_lock); |
337 | if (!(ns->nr_hashed & PIDNS_HASH_ADDING)) | 209 | if (!(ns->pid_allocated & PIDNS_ADDING)) |
338 | goto out_unlock; | 210 | goto out_unlock; |
339 | for ( ; upid >= pid->numbers; --upid) { | 211 | for ( ; upid >= pid->numbers; --upid) { |
340 | hlist_add_head_rcu(&upid->pid_chain, | 212 | /* Make the PID visible to find_pid_ns. */ |
341 | &pid_hash[pid_hashfn(upid->nr, upid->ns)]); | 213 | idr_replace(&upid->ns->idr, pid, upid->nr); |
342 | upid->ns->nr_hashed++; | 214 | upid->ns->pid_allocated++; |
343 | } | 215 | } |
344 | spin_unlock_irq(&pidmap_lock); | 216 | spin_unlock_irq(&pidmap_lock); |
345 | 217 | ||
@@ -350,8 +222,11 @@ out_unlock: | |||
350 | put_pid_ns(ns); | 222 | put_pid_ns(ns); |
351 | 223 | ||
352 | out_free: | 224 | out_free: |
225 | spin_lock_irq(&pidmap_lock); | ||
353 | while (++i <= ns->level) | 226 | while (++i <= ns->level) |
354 | free_pidmap(pid->numbers + i); | 227 | idr_remove(&ns->idr, (pid->numbers + i)->nr); |
228 | |||
229 | spin_unlock_irq(&pidmap_lock); | ||
355 | 230 | ||
356 | kmem_cache_free(ns->pid_cachep, pid); | 231 | kmem_cache_free(ns->pid_cachep, pid); |
357 | return ERR_PTR(retval); | 232 | return ERR_PTR(retval); |
@@ -360,21 +235,13 @@ out_free: | |||
360 | void disable_pid_allocation(struct pid_namespace *ns) | 235 | void disable_pid_allocation(struct pid_namespace *ns) |
361 | { | 236 | { |
362 | spin_lock_irq(&pidmap_lock); | 237 | spin_lock_irq(&pidmap_lock); |
363 | ns->nr_hashed &= ~PIDNS_HASH_ADDING; | 238 | ns->pid_allocated &= ~PIDNS_ADDING; |
364 | spin_unlock_irq(&pidmap_lock); | 239 | spin_unlock_irq(&pidmap_lock); |
365 | } | 240 | } |
366 | 241 | ||
367 | struct pid *find_pid_ns(int nr, struct pid_namespace *ns) | 242 | struct pid *find_pid_ns(int nr, struct pid_namespace *ns) |
368 | { | 243 | { |
369 | struct upid *pnr; | 244 | return idr_find(&ns->idr, nr); |
370 | |||
371 | hlist_for_each_entry_rcu(pnr, | ||
372 | &pid_hash[pid_hashfn(nr, ns)], pid_chain) | ||
373 | if (pnr->nr == nr && pnr->ns == ns) | ||
374 | return container_of(pnr, struct pid, | ||
375 | numbers[ns->level]); | ||
376 | |||
377 | return NULL; | ||
378 | } | 245 | } |
379 | EXPORT_SYMBOL_GPL(find_pid_ns); | 246 | EXPORT_SYMBOL_GPL(find_pid_ns); |
380 | 247 | ||
@@ -530,6 +397,7 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, | |||
530 | if (type != PIDTYPE_PID) { | 397 | if (type != PIDTYPE_PID) { |
531 | if (type == __PIDTYPE_TGID) | 398 | if (type == __PIDTYPE_TGID) |
532 | type = PIDTYPE_PID; | 399 | type = PIDTYPE_PID; |
400 | |||
533 | task = task->group_leader; | 401 | task = task->group_leader; |
534 | } | 402 | } |
535 | nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); | 403 | nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); |
@@ -553,35 +421,13 @@ EXPORT_SYMBOL_GPL(task_active_pid_ns); | |||
553 | */ | 421 | */ |
554 | struct pid *find_ge_pid(int nr, struct pid_namespace *ns) | 422 | struct pid *find_ge_pid(int nr, struct pid_namespace *ns) |
555 | { | 423 | { |
556 | struct pid *pid; | 424 | return idr_get_next(&ns->idr, &nr); |
557 | |||
558 | do { | ||
559 | pid = find_pid_ns(nr, ns); | ||
560 | if (pid) | ||
561 | break; | ||
562 | nr = next_pidmap(ns, nr); | ||
563 | } while (nr > 0); | ||
564 | |||
565 | return pid; | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * The pid hash table is scaled according to the amount of memory in the | ||
570 | * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or | ||
571 | * more. | ||
572 | */ | ||
573 | void __init pidhash_init(void) | ||
574 | { | ||
575 | pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18, | ||
576 | HASH_EARLY | HASH_SMALL | HASH_ZERO, | ||
577 | &pidhash_shift, NULL, | ||
578 | 0, 4096); | ||
579 | } | 425 | } |
580 | 426 | ||
581 | void __init pidmap_init(void) | 427 | void __init pid_idr_init(void) |
582 | { | 428 | { |
583 | /* Verify no one has done anything silly: */ | 429 | /* Verify no one has done anything silly: */ |
584 | BUILD_BUG_ON(PID_MAX_LIMIT >= PIDNS_HASH_ADDING); | 430 | BUILD_BUG_ON(PID_MAX_LIMIT >= PIDNS_ADDING); |
585 | 431 | ||
586 | /* bump default and minimum pid_max based on number of cpus */ | 432 | /* bump default and minimum pid_max based on number of cpus */ |
587 | pid_max = min(pid_max_max, max_t(int, pid_max, | 433 | pid_max = min(pid_max_max, max_t(int, pid_max, |
@@ -590,10 +436,7 @@ void __init pidmap_init(void) | |||
590 | PIDS_PER_CPU_MIN * num_possible_cpus()); | 436 | PIDS_PER_CPU_MIN * num_possible_cpus()); |
591 | pr_info("pid_max: default: %u minimum: %u\n", pid_max, pid_max_min); | 437 | pr_info("pid_max: default: %u minimum: %u\n", pid_max, pid_max_min); |
592 | 438 | ||
593 | init_pid_ns.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL); | 439 | idr_init(&init_pid_ns.idr); |
594 | /* Reserve PID 0. We never call free_pidmap(0) */ | ||
595 | set_bit(0, init_pid_ns.pidmap[0].page); | ||
596 | atomic_dec(&init_pid_ns.pidmap[0].nr_free); | ||
597 | 440 | ||
598 | init_pid_ns.pid_cachep = KMEM_CACHE(pid, | 441 | init_pid_ns.pid_cachep = KMEM_CACHE(pid, |
599 | SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); | 442 | SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 4918314893bc..0b53eef7d34b 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <linux/sched/task.h> | 22 | #include <linux/sched/task.h> |
23 | #include <linux/sched/signal.h> | 23 | #include <linux/sched/signal.h> |
24 | #include <linux/idr.h> | ||
24 | 25 | ||
25 | struct pid_cache { | 26 | struct pid_cache { |
26 | int nr_ids; | 27 | int nr_ids; |
@@ -98,7 +99,6 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns | |||
98 | struct pid_namespace *ns; | 99 | struct pid_namespace *ns; |
99 | unsigned int level = parent_pid_ns->level + 1; | 100 | unsigned int level = parent_pid_ns->level + 1; |
100 | struct ucounts *ucounts; | 101 | struct ucounts *ucounts; |
101 | int i; | ||
102 | int err; | 102 | int err; |
103 | 103 | ||
104 | err = -EINVAL; | 104 | err = -EINVAL; |
@@ -117,17 +117,15 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns | |||
117 | if (ns == NULL) | 117 | if (ns == NULL) |
118 | goto out_dec; | 118 | goto out_dec; |
119 | 119 | ||
120 | ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL); | 120 | idr_init(&ns->idr); |
121 | if (!ns->pidmap[0].page) | ||
122 | goto out_free; | ||
123 | 121 | ||
124 | ns->pid_cachep = create_pid_cachep(level + 1); | 122 | ns->pid_cachep = create_pid_cachep(level + 1); |
125 | if (ns->pid_cachep == NULL) | 123 | if (ns->pid_cachep == NULL) |
126 | goto out_free_map; | 124 | goto out_free_idr; |
127 | 125 | ||
128 | err = ns_alloc_inum(&ns->ns); | 126 | err = ns_alloc_inum(&ns->ns); |
129 | if (err) | 127 | if (err) |
130 | goto out_free_map; | 128 | goto out_free_idr; |
131 | ns->ns.ops = &pidns_operations; | 129 | ns->ns.ops = &pidns_operations; |
132 | 130 | ||
133 | kref_init(&ns->kref); | 131 | kref_init(&ns->kref); |
@@ -135,20 +133,13 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns | |||
135 | ns->parent = get_pid_ns(parent_pid_ns); | 133 | ns->parent = get_pid_ns(parent_pid_ns); |
136 | ns->user_ns = get_user_ns(user_ns); | 134 | ns->user_ns = get_user_ns(user_ns); |
137 | ns->ucounts = ucounts; | 135 | ns->ucounts = ucounts; |
138 | ns->nr_hashed = PIDNS_HASH_ADDING; | 136 | ns->pid_allocated = PIDNS_ADDING; |
139 | INIT_WORK(&ns->proc_work, proc_cleanup_work); | 137 | INIT_WORK(&ns->proc_work, proc_cleanup_work); |
140 | 138 | ||
141 | set_bit(0, ns->pidmap[0].page); | ||
142 | atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1); | ||
143 | |||
144 | for (i = 1; i < PIDMAP_ENTRIES; i++) | ||
145 | atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE); | ||
146 | |||
147 | return ns; | 139 | return ns; |
148 | 140 | ||
149 | out_free_map: | 141 | out_free_idr: |
150 | kfree(ns->pidmap[0].page); | 142 | idr_destroy(&ns->idr); |
151 | out_free: | ||
152 | kmem_cache_free(pid_ns_cachep, ns); | 143 | kmem_cache_free(pid_ns_cachep, ns); |
153 | out_dec: | 144 | out_dec: |
154 | dec_pid_namespaces(ucounts); | 145 | dec_pid_namespaces(ucounts); |
@@ -168,11 +159,9 @@ static void delayed_free_pidns(struct rcu_head *p) | |||
168 | 159 | ||
169 | static void destroy_pid_namespace(struct pid_namespace *ns) | 160 | static void destroy_pid_namespace(struct pid_namespace *ns) |
170 | { | 161 | { |
171 | int i; | ||
172 | |||
173 | ns_free_inum(&ns->ns); | 162 | ns_free_inum(&ns->ns); |
174 | for (i = 0; i < PIDMAP_ENTRIES; i++) | 163 | |
175 | kfree(ns->pidmap[i].page); | 164 | idr_destroy(&ns->idr); |
176 | call_rcu(&ns->rcu, delayed_free_pidns); | 165 | call_rcu(&ns->rcu, delayed_free_pidns); |
177 | } | 166 | } |
178 | 167 | ||
@@ -213,6 +202,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
213 | int rc; | 202 | int rc; |
214 | struct task_struct *task, *me = current; | 203 | struct task_struct *task, *me = current; |
215 | int init_pids = thread_group_leader(me) ? 1 : 2; | 204 | int init_pids = thread_group_leader(me) ? 1 : 2; |
205 | struct pid *pid; | ||
216 | 206 | ||
217 | /* Don't allow any more processes into the pid namespace */ | 207 | /* Don't allow any more processes into the pid namespace */ |
218 | disable_pid_allocation(pid_ns); | 208 | disable_pid_allocation(pid_ns); |
@@ -239,20 +229,16 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
239 | * maintain a tasklist for each pid namespace. | 229 | * maintain a tasklist for each pid namespace. |
240 | * | 230 | * |
241 | */ | 231 | */ |
232 | rcu_read_lock(); | ||
242 | read_lock(&tasklist_lock); | 233 | read_lock(&tasklist_lock); |
243 | nr = next_pidmap(pid_ns, 1); | 234 | nr = 2; |
244 | while (nr > 0) { | 235 | idr_for_each_entry_continue(&pid_ns->idr, pid, nr) { |
245 | rcu_read_lock(); | 236 | task = pid_task(pid, PIDTYPE_PID); |
246 | |||
247 | task = pid_task(find_vpid(nr), PIDTYPE_PID); | ||
248 | if (task && !__fatal_signal_pending(task)) | 237 | if (task && !__fatal_signal_pending(task)) |
249 | send_sig_info(SIGKILL, SEND_SIG_FORCED, task); | 238 | send_sig_info(SIGKILL, SEND_SIG_FORCED, task); |
250 | |||
251 | rcu_read_unlock(); | ||
252 | |||
253 | nr = next_pidmap(pid_ns, nr); | ||
254 | } | 239 | } |
255 | read_unlock(&tasklist_lock); | 240 | read_unlock(&tasklist_lock); |
241 | rcu_read_unlock(); | ||
256 | 242 | ||
257 | /* | 243 | /* |
258 | * Reap the EXIT_ZOMBIE children we had before we ignored SIGCHLD. | 244 | * Reap the EXIT_ZOMBIE children we had before we ignored SIGCHLD. |
@@ -268,7 +254,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
268 | * sys_wait4() above can't reap the EXIT_DEAD children but we do not | 254 | * sys_wait4() above can't reap the EXIT_DEAD children but we do not |
269 | * really care, we could reparent them to the global init. We could | 255 | * really care, we could reparent them to the global init. We could |
270 | * exit and reap ->child_reaper even if it is not the last thread in | 256 | * exit and reap ->child_reaper even if it is not the last thread in |
271 | * this pid_ns, free_pid(nr_hashed == 0) calls proc_cleanup_work(), | 257 | * this pid_ns, free_pid(pid_allocated == 0) calls proc_cleanup_work(), |
272 | * pid_ns can not go away until proc_kill_sb() drops the reference. | 258 | * pid_ns can not go away until proc_kill_sb() drops the reference. |
273 | * | 259 | * |
274 | * But this ns can also have other tasks injected by setns()+fork(). | 260 | * But this ns can also have other tasks injected by setns()+fork(). |
@@ -282,7 +268,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
282 | */ | 268 | */ |
283 | for (;;) { | 269 | for (;;) { |
284 | set_current_state(TASK_INTERRUPTIBLE); | 270 | set_current_state(TASK_INTERRUPTIBLE); |
285 | if (pid_ns->nr_hashed == init_pids) | 271 | if (pid_ns->pid_allocated == init_pids) |
286 | break; | 272 | break; |
287 | schedule(); | 273 | schedule(); |
288 | } | 274 | } |
@@ -301,6 +287,7 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write, | |||
301 | { | 287 | { |
302 | struct pid_namespace *pid_ns = task_active_pid_ns(current); | 288 | struct pid_namespace *pid_ns = task_active_pid_ns(current); |
303 | struct ctl_table tmp = *table; | 289 | struct ctl_table tmp = *table; |
290 | int ret, next; | ||
304 | 291 | ||
305 | if (write && !ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN)) | 292 | if (write && !ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN)) |
306 | return -EPERM; | 293 | return -EPERM; |
@@ -311,8 +298,14 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write, | |||
311 | * it should synchronize its usage with external means. | 298 | * it should synchronize its usage with external means. |
312 | */ | 299 | */ |
313 | 300 | ||
314 | tmp.data = &pid_ns->last_pid; | 301 | next = idr_get_cursor(&pid_ns->idr) - 1; |
315 | return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); | 302 | |
303 | tmp.data = &next; | ||
304 | ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); | ||
305 | if (!ret && write) | ||
306 | idr_set_cursor(&pid_ns->idr, next + 1); | ||
307 | |||
308 | return ret; | ||
316 | } | 309 | } |
317 | 310 | ||
318 | extern int pid_max; | 311 | extern int pid_max; |
diff --git a/kernel/reboot.c b/kernel/reboot.c index bd30a973fe94..e4ced883d8de 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c | |||
@@ -104,6 +104,33 @@ int unregister_reboot_notifier(struct notifier_block *nb) | |||
104 | } | 104 | } |
105 | EXPORT_SYMBOL(unregister_reboot_notifier); | 105 | EXPORT_SYMBOL(unregister_reboot_notifier); |
106 | 106 | ||
107 | static void devm_unregister_reboot_notifier(struct device *dev, void *res) | ||
108 | { | ||
109 | WARN_ON(unregister_reboot_notifier(*(struct notifier_block **)res)); | ||
110 | } | ||
111 | |||
112 | int devm_register_reboot_notifier(struct device *dev, struct notifier_block *nb) | ||
113 | { | ||
114 | struct notifier_block **rcnb; | ||
115 | int ret; | ||
116 | |||
117 | rcnb = devres_alloc(devm_unregister_reboot_notifier, | ||
118 | sizeof(*rcnb), GFP_KERNEL); | ||
119 | if (!rcnb) | ||
120 | return -ENOMEM; | ||
121 | |||
122 | ret = register_reboot_notifier(nb); | ||
123 | if (!ret) { | ||
124 | *rcnb = nb; | ||
125 | devres_add(dev, rcnb); | ||
126 | } else { | ||
127 | devres_free(rcnb); | ||
128 | } | ||
129 | |||
130 | return ret; | ||
131 | } | ||
132 | EXPORT_SYMBOL(devm_register_reboot_notifier); | ||
133 | |||
107 | /* | 134 | /* |
108 | * Notifier list for kernel code which wants to be called | 135 | * Notifier list for kernel code which wants to be called |
109 | * to restart the system. | 136 | * to restart the system. |
diff --git a/kernel/signal.c b/kernel/signal.c index babb36d3d039..9558664bd9ec 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -78,7 +78,7 @@ static int sig_task_ignored(struct task_struct *t, int sig, bool force) | |||
78 | handler = sig_handler(t, sig); | 78 | handler = sig_handler(t, sig); |
79 | 79 | ||
80 | if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && | 80 | if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && |
81 | handler == SIG_DFL && !force) | 81 | handler == SIG_DFL && !(force && sig_kernel_only(sig))) |
82 | return 1; | 82 | return 1; |
83 | 83 | ||
84 | return sig_handler_ignored(handler, sig); | 84 | return sig_handler_ignored(handler, sig); |
@@ -94,13 +94,15 @@ static int sig_ignored(struct task_struct *t, int sig, bool force) | |||
94 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) | 94 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) |
95 | return 0; | 95 | return 0; |
96 | 96 | ||
97 | if (!sig_task_ignored(t, sig, force)) | ||
98 | return 0; | ||
99 | |||
100 | /* | 97 | /* |
101 | * Tracers may want to know about even ignored signals. | 98 | * Tracers may want to know about even ignored signal unless it |
99 | * is SIGKILL which can't be reported anyway but can be ignored | ||
100 | * by SIGNAL_UNKILLABLE task. | ||
102 | */ | 101 | */ |
103 | return !t->ptrace; | 102 | if (t->ptrace && sig != SIGKILL) |
103 | return 0; | ||
104 | |||
105 | return sig_task_ignored(t, sig, force); | ||
104 | } | 106 | } |
105 | 107 | ||
106 | /* | 108 | /* |
@@ -929,9 +931,9 @@ static void complete_signal(int sig, struct task_struct *p, int group) | |||
929 | * then start taking the whole group down immediately. | 931 | * then start taking the whole group down immediately. |
930 | */ | 932 | */ |
931 | if (sig_fatal(p, sig) && | 933 | if (sig_fatal(p, sig) && |
932 | !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) && | 934 | !(signal->flags & SIGNAL_GROUP_EXIT) && |
933 | !sigismember(&t->real_blocked, sig) && | 935 | !sigismember(&t->real_blocked, sig) && |
934 | (sig == SIGKILL || !t->ptrace)) { | 936 | (sig == SIGKILL || !p->ptrace)) { |
935 | /* | 937 | /* |
936 | * This signal will be fatal to the whole group. | 938 | * This signal will be fatal to the whole group. |
937 | */ | 939 | */ |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4a13a389e99b..557d46728577 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/kexec.h> | 66 | #include <linux/kexec.h> |
67 | #include <linux/bpf.h> | 67 | #include <linux/bpf.h> |
68 | #include <linux/mount.h> | 68 | #include <linux/mount.h> |
69 | #include <linux/pipe_fs_i.h> | ||
69 | 70 | ||
70 | #include <linux/uaccess.h> | 71 | #include <linux/uaccess.h> |
71 | #include <asm/processor.h> | 72 | #include <asm/processor.h> |
@@ -1816,7 +1817,7 @@ static struct ctl_table fs_table[] = { | |||
1816 | { | 1817 | { |
1817 | .procname = "pipe-max-size", | 1818 | .procname = "pipe-max-size", |
1818 | .data = &pipe_max_size, | 1819 | .data = &pipe_max_size, |
1819 | .maxlen = sizeof(int), | 1820 | .maxlen = sizeof(pipe_max_size), |
1820 | .mode = 0644, | 1821 | .mode = 0644, |
1821 | .proc_handler = &pipe_proc_fn, | 1822 | .proc_handler = &pipe_proc_fn, |
1822 | .extra1 = &pipe_min_size, | 1823 | .extra1 = &pipe_min_size, |
@@ -2575,12 +2576,13 @@ static int do_proc_douintvec_minmax_conv(unsigned long *lvalp, | |||
2575 | if (write) { | 2576 | if (write) { |
2576 | unsigned int val = *lvalp; | 2577 | unsigned int val = *lvalp; |
2577 | 2578 | ||
2579 | if (*lvalp > UINT_MAX) | ||
2580 | return -EINVAL; | ||
2581 | |||
2578 | if ((param->min && *param->min > val) || | 2582 | if ((param->min && *param->min > val) || |
2579 | (param->max && *param->max < val)) | 2583 | (param->max && *param->max < val)) |
2580 | return -ERANGE; | 2584 | return -ERANGE; |
2581 | 2585 | ||
2582 | if (*lvalp > UINT_MAX) | ||
2583 | return -EINVAL; | ||
2584 | *valp = val; | 2586 | *valp = val; |
2585 | } else { | 2587 | } else { |
2586 | unsigned int val = *valp; | 2588 | unsigned int val = *valp; |
@@ -2620,6 +2622,48 @@ int proc_douintvec_minmax(struct ctl_table *table, int write, | |||
2620 | do_proc_douintvec_minmax_conv, ¶m); | 2622 | do_proc_douintvec_minmax_conv, ¶m); |
2621 | } | 2623 | } |
2622 | 2624 | ||
2625 | struct do_proc_dopipe_max_size_conv_param { | ||
2626 | unsigned int *min; | ||
2627 | }; | ||
2628 | |||
2629 | static int do_proc_dopipe_max_size_conv(unsigned long *lvalp, | ||
2630 | unsigned int *valp, | ||
2631 | int write, void *data) | ||
2632 | { | ||
2633 | struct do_proc_dopipe_max_size_conv_param *param = data; | ||
2634 | |||
2635 | if (write) { | ||
2636 | unsigned int val; | ||
2637 | |||
2638 | if (*lvalp > UINT_MAX) | ||
2639 | return -EINVAL; | ||
2640 | |||
2641 | val = round_pipe_size(*lvalp); | ||
2642 | if (val == 0) | ||
2643 | return -EINVAL; | ||
2644 | |||
2645 | if (param->min && *param->min > val) | ||
2646 | return -ERANGE; | ||
2647 | |||
2648 | *valp = val; | ||
2649 | } else { | ||
2650 | unsigned int val = *valp; | ||
2651 | *lvalp = (unsigned long) val; | ||
2652 | } | ||
2653 | |||
2654 | return 0; | ||
2655 | } | ||
2656 | |||
2657 | int proc_dopipe_max_size(struct ctl_table *table, int write, | ||
2658 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2659 | { | ||
2660 | struct do_proc_dopipe_max_size_conv_param param = { | ||
2661 | .min = (unsigned int *) table->extra1, | ||
2662 | }; | ||
2663 | return do_proc_douintvec(table, write, buffer, lenp, ppos, | ||
2664 | do_proc_dopipe_max_size_conv, ¶m); | ||
2665 | } | ||
2666 | |||
2623 | static void validate_coredump_safety(void) | 2667 | static void validate_coredump_safety(void) |
2624 | { | 2668 | { |
2625 | #ifdef CONFIG_COREDUMP | 2669 | #ifdef CONFIG_COREDUMP |
@@ -3083,14 +3127,12 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, | |||
3083 | else | 3127 | else |
3084 | bitmap_copy(bitmap, tmp_bitmap, bitmap_len); | 3128 | bitmap_copy(bitmap, tmp_bitmap, bitmap_len); |
3085 | } | 3129 | } |
3086 | kfree(tmp_bitmap); | ||
3087 | *lenp -= left; | 3130 | *lenp -= left; |
3088 | *ppos += *lenp; | 3131 | *ppos += *lenp; |
3089 | return 0; | ||
3090 | } else { | ||
3091 | kfree(tmp_bitmap); | ||
3092 | return err; | ||
3093 | } | 3132 | } |
3133 | |||
3134 | kfree(tmp_bitmap); | ||
3135 | return err; | ||
3094 | } | 3136 | } |
3095 | 3137 | ||
3096 | #else /* CONFIG_PROC_SYSCTL */ | 3138 | #else /* CONFIG_PROC_SYSCTL */ |
@@ -3125,6 +3167,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write, | |||
3125 | return -ENOSYS; | 3167 | return -ENOSYS; |
3126 | } | 3168 | } |
3127 | 3169 | ||
3170 | int proc_dopipe_max_size(struct ctl_table *table, int write, | ||
3171 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
3172 | { | ||
3173 | return -ENOSYS; | ||
3174 | } | ||
3175 | |||
3128 | int proc_dointvec_jiffies(struct ctl_table *table, int write, | 3176 | int proc_dointvec_jiffies(struct ctl_table *table, int write, |
3129 | void __user *buffer, size_t *lenp, loff_t *ppos) | 3177 | void __user *buffer, size_t *lenp, loff_t *ppos) |
3130 | { | 3178 | { |
@@ -3168,6 +3216,7 @@ EXPORT_SYMBOL(proc_douintvec); | |||
3168 | EXPORT_SYMBOL(proc_dointvec_jiffies); | 3216 | EXPORT_SYMBOL(proc_dointvec_jiffies); |
3169 | EXPORT_SYMBOL(proc_dointvec_minmax); | 3217 | EXPORT_SYMBOL(proc_dointvec_minmax); |
3170 | EXPORT_SYMBOL_GPL(proc_douintvec_minmax); | 3218 | EXPORT_SYMBOL_GPL(proc_douintvec_minmax); |
3219 | EXPORT_SYMBOL_GPL(proc_dopipe_max_size); | ||
3171 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); | 3220 | EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); |
3172 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); | 3221 | EXPORT_SYMBOL(proc_dointvec_ms_jiffies); |
3173 | EXPORT_SYMBOL(proc_dostring); | 3222 | EXPORT_SYMBOL(proc_dostring); |
diff --git a/kernel/umh.c b/kernel/umh.c index 6ff9905250ff..18e5fa4b0e71 100644 --- a/kernel/umh.c +++ b/kernel/umh.c | |||
@@ -537,14 +537,14 @@ static int proc_cap_handler(struct ctl_table *table, int write, | |||
537 | /* | 537 | /* |
538 | * Drop everything not in the new_cap (but don't add things) | 538 | * Drop everything not in the new_cap (but don't add things) |
539 | */ | 539 | */ |
540 | spin_lock(&umh_sysctl_lock); | ||
541 | if (write) { | 540 | if (write) { |
541 | spin_lock(&umh_sysctl_lock); | ||
542 | if (table->data == CAP_BSET) | 542 | if (table->data == CAP_BSET) |
543 | usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); | 543 | usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); |
544 | if (table->data == CAP_PI) | 544 | if (table->data == CAP_PI) |
545 | usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); | 545 | usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); |
546 | spin_unlock(&umh_sysctl_lock); | ||
546 | } | 547 | } |
547 | spin_unlock(&umh_sysctl_lock); | ||
548 | 548 | ||
549 | return 0; | 549 | return 0; |
550 | } | 550 | } |
diff --git a/lib/Kconfig b/lib/Kconfig index a2b6745324ab..368972f0db78 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -584,7 +584,7 @@ config PRIME_NUMBERS | |||
584 | tristate | 584 | tristate |
585 | 585 | ||
586 | config STRING_SELFTEST | 586 | config STRING_SELFTEST |
587 | bool "Test string functions" | 587 | tristate "Test string functions" |
588 | 588 | ||
589 | endmenu | 589 | endmenu |
590 | 590 | ||
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8ffd891857ab..947d3e2ed5c2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -756,6 +756,16 @@ config KCOV | |||
756 | 756 | ||
757 | For more details, see Documentation/dev-tools/kcov.rst. | 757 | For more details, see Documentation/dev-tools/kcov.rst. |
758 | 758 | ||
759 | config KCOV_ENABLE_COMPARISONS | ||
760 | bool "Enable comparison operands collection by KCOV" | ||
761 | depends on KCOV | ||
762 | default n | ||
763 | help | ||
764 | KCOV also exposes operands of every comparison in the instrumented | ||
765 | code along with operand sizes and PCs of the comparison instructions. | ||
766 | These operands can be used by fuzzing engines to improve the quality | ||
767 | of fuzzing coverage. | ||
768 | |||
759 | config KCOV_INSTRUMENT_ALL | 769 | config KCOV_INSTRUMENT_ALL |
760 | bool "Instrument all code by default" | 770 | bool "Instrument all code by default" |
761 | depends on KCOV | 771 | depends on KCOV |
@@ -1850,6 +1860,15 @@ config TEST_BPF | |||
1850 | 1860 | ||
1851 | If unsure, say N. | 1861 | If unsure, say N. |
1852 | 1862 | ||
1863 | config TEST_FIND_BIT | ||
1864 | tristate "Test find_bit functions" | ||
1865 | default n | ||
1866 | help | ||
1867 | This builds the "test_find_bit" module that measure find_*_bit() | ||
1868 | functions performance. | ||
1869 | |||
1870 | If unsure, say N. | ||
1871 | |||
1853 | config TEST_FIRMWARE | 1872 | config TEST_FIRMWARE |
1854 | tristate "Test firmware loading via userspace interface" | 1873 | tristate "Test firmware loading via userspace interface" |
1855 | default n | 1874 | default n |
diff --git a/lib/Makefile b/lib/Makefile index 136a0b254564..d11c48ec8ffd 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -40,12 +40,14 @@ obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \ | |||
40 | bsearch.o find_bit.o llist.o memweight.o kfifo.o \ | 40 | bsearch.o find_bit.o llist.o memweight.o kfifo.o \ |
41 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ | 41 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ |
42 | once.o refcount.o usercopy.o errseq.o | 42 | once.o refcount.o usercopy.o errseq.o |
43 | obj-$(CONFIG_STRING_SELFTEST) += test_string.o | ||
43 | obj-y += string_helpers.o | 44 | obj-y += string_helpers.o |
44 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o | 45 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o |
45 | obj-y += hexdump.o | 46 | obj-y += hexdump.o |
46 | obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o | 47 | obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o |
47 | obj-y += kstrtox.o | 48 | obj-y += kstrtox.o |
48 | obj-$(CONFIG_TEST_BPF) += test_bpf.o | 49 | obj-$(CONFIG_TEST_BPF) += test_bpf.o |
50 | obj-$(CONFIG_TEST_FIND_BIT) += test_find_bit.o | ||
49 | obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o | 51 | obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o |
50 | obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o | 52 | obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o |
51 | obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o | 53 | obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o |
@@ -186,7 +186,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | |||
186 | return BUG_TRAP_TYPE_WARN; | 186 | return BUG_TRAP_TYPE_WARN; |
187 | } | 187 | } |
188 | 188 | ||
189 | printk(KERN_DEFAULT "------------[ cut here ]------------\n"); | 189 | printk(KERN_DEFAULT CUT_HERE); |
190 | 190 | ||
191 | if (file) | 191 | if (file) |
192 | pr_crit("kernel BUG at %s:%u!\n", file, line); | 192 | pr_crit("kernel BUG at %s:%u!\n", file, line); |
@@ -196,3 +196,26 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | |||
196 | 196 | ||
197 | return BUG_TRAP_TYPE_BUG; | 197 | return BUG_TRAP_TYPE_BUG; |
198 | } | 198 | } |
199 | |||
200 | static void clear_once_table(struct bug_entry *start, struct bug_entry *end) | ||
201 | { | ||
202 | struct bug_entry *bug; | ||
203 | |||
204 | for (bug = start; bug < end; bug++) | ||
205 | bug->flags &= ~BUGFLAG_DONE; | ||
206 | } | ||
207 | |||
208 | void generic_bug_clear_once(void) | ||
209 | { | ||
210 | #ifdef CONFIG_MODULES | ||
211 | struct module *mod; | ||
212 | |||
213 | rcu_read_lock_sched(); | ||
214 | list_for_each_entry_rcu(mod, &module_bug_list, bug_list) | ||
215 | clear_once_table(mod->bug_table, | ||
216 | mod->bug_table + mod->num_bugs); | ||
217 | rcu_read_unlock_sched(); | ||
218 | #endif | ||
219 | |||
220 | clear_once_table(__start___bug_table, __stop___bug_table); | ||
221 | } | ||
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index ea4cc3dde4f1..1b34d210452c 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -1495,14 +1495,22 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size, | |||
1495 | if (!entry) | 1495 | if (!entry) |
1496 | return; | 1496 | return; |
1497 | 1497 | ||
1498 | /* handle vmalloc and linear addresses */ | ||
1499 | if (!is_vmalloc_addr(virt) && !virt_to_page(virt)) | ||
1500 | return; | ||
1501 | |||
1498 | entry->type = dma_debug_coherent; | 1502 | entry->type = dma_debug_coherent; |
1499 | entry->dev = dev; | 1503 | entry->dev = dev; |
1500 | entry->pfn = page_to_pfn(virt_to_page(virt)); | ||
1501 | entry->offset = offset_in_page(virt); | 1504 | entry->offset = offset_in_page(virt); |
1502 | entry->size = size; | 1505 | entry->size = size; |
1503 | entry->dev_addr = dma_addr; | 1506 | entry->dev_addr = dma_addr; |
1504 | entry->direction = DMA_BIDIRECTIONAL; | 1507 | entry->direction = DMA_BIDIRECTIONAL; |
1505 | 1508 | ||
1509 | if (is_vmalloc_addr(virt)) | ||
1510 | entry->pfn = vmalloc_to_pfn(virt); | ||
1511 | else | ||
1512 | entry->pfn = page_to_pfn(virt_to_page(virt)); | ||
1513 | |||
1506 | add_dma_entry(entry); | 1514 | add_dma_entry(entry); |
1507 | } | 1515 | } |
1508 | EXPORT_SYMBOL(debug_dma_alloc_coherent); | 1516 | EXPORT_SYMBOL(debug_dma_alloc_coherent); |
@@ -1513,13 +1521,21 @@ void debug_dma_free_coherent(struct device *dev, size_t size, | |||
1513 | struct dma_debug_entry ref = { | 1521 | struct dma_debug_entry ref = { |
1514 | .type = dma_debug_coherent, | 1522 | .type = dma_debug_coherent, |
1515 | .dev = dev, | 1523 | .dev = dev, |
1516 | .pfn = page_to_pfn(virt_to_page(virt)), | ||
1517 | .offset = offset_in_page(virt), | 1524 | .offset = offset_in_page(virt), |
1518 | .dev_addr = addr, | 1525 | .dev_addr = addr, |
1519 | .size = size, | 1526 | .size = size, |
1520 | .direction = DMA_BIDIRECTIONAL, | 1527 | .direction = DMA_BIDIRECTIONAL, |
1521 | }; | 1528 | }; |
1522 | 1529 | ||
1530 | /* handle vmalloc and linear addresses */ | ||
1531 | if (!is_vmalloc_addr(virt) && !virt_to_page(virt)) | ||
1532 | return; | ||
1533 | |||
1534 | if (is_vmalloc_addr(virt)) | ||
1535 | ref.pfn = vmalloc_to_pfn(virt); | ||
1536 | else | ||
1537 | ref.pfn = page_to_pfn(virt_to_page(virt)); | ||
1538 | |||
1523 | if (unlikely(dma_debug_disabled())) | 1539 | if (unlikely(dma_debug_disabled())) |
1524 | return; | 1540 | return; |
1525 | 1541 | ||
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index da796e2dc4f5..c7c96bc7654a 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -360,6 +360,10 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
360 | if (parse_lineno(last, &query->last_lineno) < 0) | 360 | if (parse_lineno(last, &query->last_lineno) < 0) |
361 | return -EINVAL; | 361 | return -EINVAL; |
362 | 362 | ||
363 | /* special case for last lineno not specified */ | ||
364 | if (query->last_lineno == 0) | ||
365 | query->last_lineno = UINT_MAX; | ||
366 | |||
363 | if (query->last_lineno < query->first_lineno) { | 367 | if (query->last_lineno < query->first_lineno) { |
364 | pr_err("last-line:%d < 1st-line:%d\n", | 368 | pr_err("last-line:%d < 1st-line:%d\n", |
365 | query->last_lineno, | 369 | query->last_lineno, |
diff --git a/lib/genalloc.c b/lib/genalloc.c index 144fe6b1a03e..ca06adc4f445 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
@@ -194,7 +194,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy | |||
194 | chunk->phys_addr = phys; | 194 | chunk->phys_addr = phys; |
195 | chunk->start_addr = virt; | 195 | chunk->start_addr = virt; |
196 | chunk->end_addr = virt + size - 1; | 196 | chunk->end_addr = virt + size - 1; |
197 | atomic_set(&chunk->avail, size); | 197 | atomic_long_set(&chunk->avail, size); |
198 | 198 | ||
199 | spin_lock(&pool->lock); | 199 | spin_lock(&pool->lock); |
200 | list_add_rcu(&chunk->next_chunk, &pool->chunks); | 200 | list_add_rcu(&chunk->next_chunk, &pool->chunks); |
@@ -304,7 +304,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size, | |||
304 | nbits = (size + (1UL << order) - 1) >> order; | 304 | nbits = (size + (1UL << order) - 1) >> order; |
305 | rcu_read_lock(); | 305 | rcu_read_lock(); |
306 | list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { | 306 | list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { |
307 | if (size > atomic_read(&chunk->avail)) | 307 | if (size > atomic_long_read(&chunk->avail)) |
308 | continue; | 308 | continue; |
309 | 309 | ||
310 | start_bit = 0; | 310 | start_bit = 0; |
@@ -324,7 +324,7 @@ retry: | |||
324 | 324 | ||
325 | addr = chunk->start_addr + ((unsigned long)start_bit << order); | 325 | addr = chunk->start_addr + ((unsigned long)start_bit << order); |
326 | size = nbits << order; | 326 | size = nbits << order; |
327 | atomic_sub(size, &chunk->avail); | 327 | atomic_long_sub(size, &chunk->avail); |
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | rcu_read_unlock(); | 330 | rcu_read_unlock(); |
@@ -390,7 +390,7 @@ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size) | |||
390 | remain = bitmap_clear_ll(chunk->bits, start_bit, nbits); | 390 | remain = bitmap_clear_ll(chunk->bits, start_bit, nbits); |
391 | BUG_ON(remain); | 391 | BUG_ON(remain); |
392 | size = nbits << order; | 392 | size = nbits << order; |
393 | atomic_add(size, &chunk->avail); | 393 | atomic_long_add(size, &chunk->avail); |
394 | rcu_read_unlock(); | 394 | rcu_read_unlock(); |
395 | return; | 395 | return; |
396 | } | 396 | } |
@@ -464,7 +464,7 @@ size_t gen_pool_avail(struct gen_pool *pool) | |||
464 | 464 | ||
465 | rcu_read_lock(); | 465 | rcu_read_lock(); |
466 | list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) | 466 | list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) |
467 | avail += atomic_read(&chunk->avail); | 467 | avail += atomic_long_read(&chunk->avail); |
468 | rcu_read_unlock(); | 468 | rcu_read_unlock(); |
469 | return avail; | 469 | return avail; |
470 | } | 470 | } |
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c index db0b5aa071fc..e2d329099bf7 100644 --- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c | |||
@@ -8,12 +8,13 @@ | |||
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/export.h> | 10 | #include <linux/export.h> |
11 | #include <linux/bitops.h> | ||
11 | 12 | ||
12 | /** | 13 | /** |
13 | * int_sqrt - rough approximation to sqrt | 14 | * int_sqrt - computes the integer square root |
14 | * @x: integer of which to calculate the sqrt | 15 | * @x: integer of which to calculate the sqrt |
15 | * | 16 | * |
16 | * A very rough approximation to the sqrt() function. | 17 | * Computes: floor(sqrt(x)) |
17 | */ | 18 | */ |
18 | unsigned long int_sqrt(unsigned long x) | 19 | unsigned long int_sqrt(unsigned long x) |
19 | { | 20 | { |
@@ -22,7 +23,7 @@ unsigned long int_sqrt(unsigned long x) | |||
22 | if (x <= 1) | 23 | if (x <= 1) |
23 | return x; | 24 | return x; |
24 | 25 | ||
25 | m = 1UL << (BITS_PER_LONG - 2); | 26 | m = 1UL << (__fls(x) & ~1UL); |
26 | while (m != 0) { | 27 | while (m != 0) { |
27 | b = y + m; | 28 | b = y + m; |
28 | y >>= 1; | 29 | y >>= 1; |
diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c index 0e343fd29570..835242e74aaa 100644 --- a/lib/interval_tree_test.c +++ b/lib/interval_tree_test.c | |||
@@ -11,10 +11,10 @@ | |||
11 | MODULE_PARM_DESC(name, msg); | 11 | MODULE_PARM_DESC(name, msg); |
12 | 12 | ||
13 | __param(int, nnodes, 100, "Number of nodes in the interval tree"); | 13 | __param(int, nnodes, 100, "Number of nodes in the interval tree"); |
14 | __param(int, perf_loops, 100000, "Number of iterations modifying the tree"); | 14 | __param(int, perf_loops, 1000, "Number of iterations modifying the tree"); |
15 | 15 | ||
16 | __param(int, nsearches, 100, "Number of searches to the interval tree"); | 16 | __param(int, nsearches, 100, "Number of searches to the interval tree"); |
17 | __param(int, search_loops, 10000, "Number of iterations searching the tree"); | 17 | __param(int, search_loops, 1000, "Number of iterations searching the tree"); |
18 | __param(bool, search_all, false, "Searches will iterate all nodes in the tree"); | 18 | __param(bool, search_all, false, "Searches will iterate all nodes in the tree"); |
19 | 19 | ||
20 | __param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint"); | 20 | __param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint"); |
diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c index 46e4c749e4eb..61a6b5aab07e 100644 --- a/lib/nmi_backtrace.c +++ b/lib/nmi_backtrace.c | |||
@@ -93,8 +93,8 @@ bool nmi_cpu_backtrace(struct pt_regs *regs) | |||
93 | if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { | 93 | if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { |
94 | arch_spin_lock(&lock); | 94 | arch_spin_lock(&lock); |
95 | if (regs && cpu_in_idle(instruction_pointer(regs))) { | 95 | if (regs && cpu_in_idle(instruction_pointer(regs))) { |
96 | pr_warn("NMI backtrace for cpu %d skipped: idling at pc %#lx\n", | 96 | pr_warn("NMI backtrace for cpu %d skipped: idling at %pS\n", |
97 | cpu, instruction_pointer(regs)); | 97 | cpu, (void *)instruction_pointer(regs)); |
98 | } else { | 98 | } else { |
99 | pr_warn("NMI backtrace for cpu %d\n", cpu); | 99 | pr_warn("NMI backtrace for cpu %d\n", cpu); |
100 | if (regs) | 100 | if (regs) |
diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 191a238e5a9d..7d36c1e27ff6 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c | |||
@@ -11,7 +11,7 @@ | |||
11 | MODULE_PARM_DESC(name, msg); | 11 | MODULE_PARM_DESC(name, msg); |
12 | 12 | ||
13 | __param(int, nnodes, 100, "Number of nodes in the rb-tree"); | 13 | __param(int, nnodes, 100, "Number of nodes in the rb-tree"); |
14 | __param(int, perf_loops, 100000, "Number of iterations modifying the rb-tree"); | 14 | __param(int, perf_loops, 1000, "Number of iterations modifying the rb-tree"); |
15 | __param(int, check_loops, 100, "Number of iterations modifying and verifying the rb-tree"); | 15 | __param(int, check_loops, 100, "Number of iterations modifying and verifying the rb-tree"); |
16 | 16 | ||
17 | struct test_node { | 17 | struct test_node { |
diff --git a/lib/string.c b/lib/string.c index 5e8d410a93df..64a9e33f1daa 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -1052,144 +1052,3 @@ void fortify_panic(const char *name) | |||
1052 | BUG(); | 1052 | BUG(); |
1053 | } | 1053 | } |
1054 | EXPORT_SYMBOL(fortify_panic); | 1054 | EXPORT_SYMBOL(fortify_panic); |
1055 | |||
1056 | #ifdef CONFIG_STRING_SELFTEST | ||
1057 | #include <linux/slab.h> | ||
1058 | #include <linux/module.h> | ||
1059 | |||
1060 | static __init int memset16_selftest(void) | ||
1061 | { | ||
1062 | unsigned i, j, k; | ||
1063 | u16 v, *p; | ||
1064 | |||
1065 | p = kmalloc(256 * 2 * 2, GFP_KERNEL); | ||
1066 | if (!p) | ||
1067 | return -1; | ||
1068 | |||
1069 | for (i = 0; i < 256; i++) { | ||
1070 | for (j = 0; j < 256; j++) { | ||
1071 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
1072 | memset16(p + i, 0xb1b2, j); | ||
1073 | for (k = 0; k < 512; k++) { | ||
1074 | v = p[k]; | ||
1075 | if (k < i) { | ||
1076 | if (v != 0xa1a1) | ||
1077 | goto fail; | ||
1078 | } else if (k < i + j) { | ||
1079 | if (v != 0xb1b2) | ||
1080 | goto fail; | ||
1081 | } else { | ||
1082 | if (v != 0xa1a1) | ||
1083 | goto fail; | ||
1084 | } | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | fail: | ||
1090 | kfree(p); | ||
1091 | if (i < 256) | ||
1092 | return (i << 24) | (j << 16) | k; | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static __init int memset32_selftest(void) | ||
1097 | { | ||
1098 | unsigned i, j, k; | ||
1099 | u32 v, *p; | ||
1100 | |||
1101 | p = kmalloc(256 * 2 * 4, GFP_KERNEL); | ||
1102 | if (!p) | ||
1103 | return -1; | ||
1104 | |||
1105 | for (i = 0; i < 256; i++) { | ||
1106 | for (j = 0; j < 256; j++) { | ||
1107 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
1108 | memset32(p + i, 0xb1b2b3b4, j); | ||
1109 | for (k = 0; k < 512; k++) { | ||
1110 | v = p[k]; | ||
1111 | if (k < i) { | ||
1112 | if (v != 0xa1a1a1a1) | ||
1113 | goto fail; | ||
1114 | } else if (k < i + j) { | ||
1115 | if (v != 0xb1b2b3b4) | ||
1116 | goto fail; | ||
1117 | } else { | ||
1118 | if (v != 0xa1a1a1a1) | ||
1119 | goto fail; | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | fail: | ||
1126 | kfree(p); | ||
1127 | if (i < 256) | ||
1128 | return (i << 24) | (j << 16) | k; | ||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | static __init int memset64_selftest(void) | ||
1133 | { | ||
1134 | unsigned i, j, k; | ||
1135 | u64 v, *p; | ||
1136 | |||
1137 | p = kmalloc(256 * 2 * 8, GFP_KERNEL); | ||
1138 | if (!p) | ||
1139 | return -1; | ||
1140 | |||
1141 | for (i = 0; i < 256; i++) { | ||
1142 | for (j = 0; j < 256; j++) { | ||
1143 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
1144 | memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j); | ||
1145 | for (k = 0; k < 512; k++) { | ||
1146 | v = p[k]; | ||
1147 | if (k < i) { | ||
1148 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | ||
1149 | goto fail; | ||
1150 | } else if (k < i + j) { | ||
1151 | if (v != 0xb1b2b3b4b5b6b7b8ULL) | ||
1152 | goto fail; | ||
1153 | } else { | ||
1154 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | ||
1155 | goto fail; | ||
1156 | } | ||
1157 | } | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | fail: | ||
1162 | kfree(p); | ||
1163 | if (i < 256) | ||
1164 | return (i << 24) | (j << 16) | k; | ||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | static __init int string_selftest_init(void) | ||
1169 | { | ||
1170 | int test, subtest; | ||
1171 | |||
1172 | test = 1; | ||
1173 | subtest = memset16_selftest(); | ||
1174 | if (subtest) | ||
1175 | goto fail; | ||
1176 | |||
1177 | test = 2; | ||
1178 | subtest = memset32_selftest(); | ||
1179 | if (subtest) | ||
1180 | goto fail; | ||
1181 | |||
1182 | test = 3; | ||
1183 | subtest = memset64_selftest(); | ||
1184 | if (subtest) | ||
1185 | goto fail; | ||
1186 | |||
1187 | pr_info("String selftests succeeded\n"); | ||
1188 | return 0; | ||
1189 | fail: | ||
1190 | pr_crit("String selftest failure %d.%08x\n", test, subtest); | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | module_init(string_selftest_init); | ||
1195 | #endif /* CONFIG_STRING_SELFTEST */ | ||
diff --git a/lib/test_find_bit.c b/lib/test_find_bit.c new file mode 100644 index 000000000000..f4394a36f9aa --- /dev/null +++ b/lib/test_find_bit.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Test for find_*_bit functions. | ||
3 | * | ||
4 | * Copyright (c) 2017 Cavium. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of version 2 of the GNU General Public | ||
8 | * License as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * find_bit functions are widely used in kernel, so the successful boot | ||
18 | * is good enough test for correctness. | ||
19 | * | ||
20 | * This test is focused on performance of traversing bitmaps. Two typical | ||
21 | * scenarios are reproduced: | ||
22 | * - randomly filled bitmap with approximately equal number of set and | ||
23 | * cleared bits; | ||
24 | * - sparse bitmap with few set bits at random positions. | ||
25 | */ | ||
26 | |||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/printk.h> | ||
32 | #include <linux/random.h> | ||
33 | |||
34 | #define BITMAP_LEN (4096UL * 8 * 10) | ||
35 | #define SPARSE 500 | ||
36 | |||
37 | static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata; | ||
38 | |||
39 | /* | ||
40 | * This is Schlemiel the Painter's algorithm. It should be called after | ||
41 | * all other tests for the same bitmap because it sets all bits of bitmap to 1. | ||
42 | */ | ||
43 | static int __init test_find_first_bit(void *bitmap, unsigned long len) | ||
44 | { | ||
45 | unsigned long i, cnt; | ||
46 | cycles_t cycles; | ||
47 | |||
48 | cycles = get_cycles(); | ||
49 | for (cnt = i = 0; i < len; cnt++) { | ||
50 | i = find_first_bit(bitmap, len); | ||
51 | __clear_bit(i, bitmap); | ||
52 | } | ||
53 | cycles = get_cycles() - cycles; | ||
54 | pr_err("find_first_bit:\t\t%llu cycles,\t%ld iterations\n", | ||
55 | (u64)cycles, cnt); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int __init test_find_next_bit(const void *bitmap, unsigned long len) | ||
61 | { | ||
62 | unsigned long i, cnt; | ||
63 | cycles_t cycles; | ||
64 | |||
65 | cycles = get_cycles(); | ||
66 | for (cnt = i = 0; i < BITMAP_LEN; cnt++) | ||
67 | i = find_next_bit(bitmap, BITMAP_LEN, i) + 1; | ||
68 | cycles = get_cycles() - cycles; | ||
69 | pr_err("find_next_bit:\t\t%llu cycles,\t%ld iterations\n", | ||
70 | (u64)cycles, cnt); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len) | ||
76 | { | ||
77 | unsigned long i, cnt; | ||
78 | cycles_t cycles; | ||
79 | |||
80 | cycles = get_cycles(); | ||
81 | for (cnt = i = 0; i < BITMAP_LEN; cnt++) | ||
82 | i = find_next_zero_bit(bitmap, len, i) + 1; | ||
83 | cycles = get_cycles() - cycles; | ||
84 | pr_err("find_next_zero_bit:\t%llu cycles,\t%ld iterations\n", | ||
85 | (u64)cycles, cnt); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int __init test_find_last_bit(const void *bitmap, unsigned long len) | ||
91 | { | ||
92 | unsigned long l, cnt = 0; | ||
93 | cycles_t cycles; | ||
94 | |||
95 | cycles = get_cycles(); | ||
96 | do { | ||
97 | cnt++; | ||
98 | l = find_last_bit(bitmap, len); | ||
99 | if (l >= len) | ||
100 | break; | ||
101 | len = l; | ||
102 | } while (len); | ||
103 | cycles = get_cycles() - cycles; | ||
104 | pr_err("find_last_bit:\t\t%llu cycles,\t%ld iterations\n", | ||
105 | (u64)cycles, cnt); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int __init find_bit_test(void) | ||
111 | { | ||
112 | unsigned long nbits = BITMAP_LEN / SPARSE; | ||
113 | |||
114 | pr_err("\nStart testing find_bit() with random-filled bitmap\n"); | ||
115 | |||
116 | get_random_bytes(bitmap, sizeof(bitmap)); | ||
117 | |||
118 | test_find_next_bit(bitmap, BITMAP_LEN); | ||
119 | test_find_next_zero_bit(bitmap, BITMAP_LEN); | ||
120 | test_find_last_bit(bitmap, BITMAP_LEN); | ||
121 | test_find_first_bit(bitmap, BITMAP_LEN); | ||
122 | |||
123 | pr_err("\nStart testing find_bit() with sparse bitmap\n"); | ||
124 | |||
125 | bitmap_zero(bitmap, BITMAP_LEN); | ||
126 | |||
127 | while (nbits--) | ||
128 | __set_bit(prandom_u32() % BITMAP_LEN, bitmap); | ||
129 | |||
130 | test_find_next_bit(bitmap, BITMAP_LEN); | ||
131 | test_find_next_zero_bit(bitmap, BITMAP_LEN); | ||
132 | test_find_last_bit(bitmap, BITMAP_LEN); | ||
133 | test_find_first_bit(bitmap, BITMAP_LEN); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | module_init(find_bit_test); | ||
138 | |||
139 | static void __exit test_find_bit_cleanup(void) | ||
140 | { | ||
141 | } | ||
142 | module_exit(test_find_bit_cleanup); | ||
143 | |||
144 | MODULE_LICENSE("GPL"); | ||
diff --git a/lib/test_kasan.c b/lib/test_kasan.c index a25c9763fce1..ef1a3ac1397e 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c | |||
@@ -353,10 +353,9 @@ static noinline void __init memcg_accounted_kmem_cache(void) | |||
353 | */ | 353 | */ |
354 | for (i = 0; i < 5; i++) { | 354 | for (i = 0; i < 5; i++) { |
355 | p = kmem_cache_alloc(cache, GFP_KERNEL); | 355 | p = kmem_cache_alloc(cache, GFP_KERNEL); |
356 | if (!p) { | 356 | if (!p) |
357 | pr_err("Allocation failed\n"); | ||
358 | goto free_cache; | 357 | goto free_cache; |
359 | } | 358 | |
360 | kmem_cache_free(cache, p); | 359 | kmem_cache_free(cache, p); |
361 | msleep(100); | 360 | msleep(100); |
362 | } | 361 | } |
diff --git a/lib/test_kmod.c b/lib/test_kmod.c index fba78d25e825..337f408b4de6 100644 --- a/lib/test_kmod.c +++ b/lib/test_kmod.c | |||
@@ -783,10 +783,8 @@ static int kmod_config_sync_info(struct kmod_test_device *test_dev) | |||
783 | free_test_dev_info(test_dev); | 783 | free_test_dev_info(test_dev); |
784 | test_dev->info = vzalloc(config->num_threads * | 784 | test_dev->info = vzalloc(config->num_threads * |
785 | sizeof(struct kmod_test_device_info)); | 785 | sizeof(struct kmod_test_device_info)); |
786 | if (!test_dev->info) { | 786 | if (!test_dev->info) |
787 | dev_err(test_dev->dev, "Cannot alloc test_dev info\n"); | ||
788 | return -ENOMEM; | 787 | return -ENOMEM; |
789 | } | ||
790 | 788 | ||
791 | return 0; | 789 | return 0; |
792 | } | 790 | } |
@@ -1089,10 +1087,8 @@ static struct kmod_test_device *alloc_test_dev_kmod(int idx) | |||
1089 | struct miscdevice *misc_dev; | 1087 | struct miscdevice *misc_dev; |
1090 | 1088 | ||
1091 | test_dev = vzalloc(sizeof(struct kmod_test_device)); | 1089 | test_dev = vzalloc(sizeof(struct kmod_test_device)); |
1092 | if (!test_dev) { | 1090 | if (!test_dev) |
1093 | pr_err("Cannot alloc test_dev\n"); | ||
1094 | goto err_out; | 1091 | goto err_out; |
1095 | } | ||
1096 | 1092 | ||
1097 | mutex_init(&test_dev->config_mutex); | 1093 | mutex_init(&test_dev->config_mutex); |
1098 | mutex_init(&test_dev->trigger_mutex); | 1094 | mutex_init(&test_dev->trigger_mutex); |
diff --git a/lib/test_list_sort.c b/lib/test_list_sort.c index 28e817387b04..5474f3f3e41d 100644 --- a/lib/test_list_sort.c +++ b/lib/test_list_sort.c | |||
@@ -76,17 +76,14 @@ static int __init list_sort_test(void) | |||
76 | pr_debug("start testing list_sort()\n"); | 76 | pr_debug("start testing list_sort()\n"); |
77 | 77 | ||
78 | elts = kcalloc(TEST_LIST_LEN, sizeof(*elts), GFP_KERNEL); | 78 | elts = kcalloc(TEST_LIST_LEN, sizeof(*elts), GFP_KERNEL); |
79 | if (!elts) { | 79 | if (!elts) |
80 | pr_err("error: cannot allocate memory\n"); | ||
81 | return err; | 80 | return err; |
82 | } | ||
83 | 81 | ||
84 | for (i = 0; i < TEST_LIST_LEN; i++) { | 82 | for (i = 0; i < TEST_LIST_LEN; i++) { |
85 | el = kmalloc(sizeof(*el), GFP_KERNEL); | 83 | el = kmalloc(sizeof(*el), GFP_KERNEL); |
86 | if (!el) { | 84 | if (!el) |
87 | pr_err("error: cannot allocate memory\n"); | ||
88 | goto exit; | 85 | goto exit; |
89 | } | 86 | |
90 | /* force some equivalencies */ | 87 | /* force some equivalencies */ |
91 | el->value = prandom_u32() % (TEST_LIST_LEN / 3); | 88 | el->value = prandom_u32() % (TEST_LIST_LEN / 3); |
92 | el->serial = i; | 89 | el->serial = i; |
diff --git a/lib/test_string.c b/lib/test_string.c new file mode 100644 index 000000000000..0fcdb82dca86 --- /dev/null +++ b/lib/test_string.c | |||
@@ -0,0 +1,141 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/printk.h> | ||
3 | #include <linux/slab.h> | ||
4 | #include <linux/string.h> | ||
5 | |||
6 | static __init int memset16_selftest(void) | ||
7 | { | ||
8 | unsigned i, j, k; | ||
9 | u16 v, *p; | ||
10 | |||
11 | p = kmalloc(256 * 2 * 2, GFP_KERNEL); | ||
12 | if (!p) | ||
13 | return -1; | ||
14 | |||
15 | for (i = 0; i < 256; i++) { | ||
16 | for (j = 0; j < 256; j++) { | ||
17 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
18 | memset16(p + i, 0xb1b2, j); | ||
19 | for (k = 0; k < 512; k++) { | ||
20 | v = p[k]; | ||
21 | if (k < i) { | ||
22 | if (v != 0xa1a1) | ||
23 | goto fail; | ||
24 | } else if (k < i + j) { | ||
25 | if (v != 0xb1b2) | ||
26 | goto fail; | ||
27 | } else { | ||
28 | if (v != 0xa1a1) | ||
29 | goto fail; | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | |||
35 | fail: | ||
36 | kfree(p); | ||
37 | if (i < 256) | ||
38 | return (i << 24) | (j << 16) | k; | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static __init int memset32_selftest(void) | ||
43 | { | ||
44 | unsigned i, j, k; | ||
45 | u32 v, *p; | ||
46 | |||
47 | p = kmalloc(256 * 2 * 4, GFP_KERNEL); | ||
48 | if (!p) | ||
49 | return -1; | ||
50 | |||
51 | for (i = 0; i < 256; i++) { | ||
52 | for (j = 0; j < 256; j++) { | ||
53 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
54 | memset32(p + i, 0xb1b2b3b4, j); | ||
55 | for (k = 0; k < 512; k++) { | ||
56 | v = p[k]; | ||
57 | if (k < i) { | ||
58 | if (v != 0xa1a1a1a1) | ||
59 | goto fail; | ||
60 | } else if (k < i + j) { | ||
61 | if (v != 0xb1b2b3b4) | ||
62 | goto fail; | ||
63 | } else { | ||
64 | if (v != 0xa1a1a1a1) | ||
65 | goto fail; | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | fail: | ||
72 | kfree(p); | ||
73 | if (i < 256) | ||
74 | return (i << 24) | (j << 16) | k; | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static __init int memset64_selftest(void) | ||
79 | { | ||
80 | unsigned i, j, k; | ||
81 | u64 v, *p; | ||
82 | |||
83 | p = kmalloc(256 * 2 * 8, GFP_KERNEL); | ||
84 | if (!p) | ||
85 | return -1; | ||
86 | |||
87 | for (i = 0; i < 256; i++) { | ||
88 | for (j = 0; j < 256; j++) { | ||
89 | memset(p, 0xa1, 256 * 2 * sizeof(v)); | ||
90 | memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j); | ||
91 | for (k = 0; k < 512; k++) { | ||
92 | v = p[k]; | ||
93 | if (k < i) { | ||
94 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | ||
95 | goto fail; | ||
96 | } else if (k < i + j) { | ||
97 | if (v != 0xb1b2b3b4b5b6b7b8ULL) | ||
98 | goto fail; | ||
99 | } else { | ||
100 | if (v != 0xa1a1a1a1a1a1a1a1ULL) | ||
101 | goto fail; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | fail: | ||
108 | kfree(p); | ||
109 | if (i < 256) | ||
110 | return (i << 24) | (j << 16) | k; | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static __init int string_selftest_init(void) | ||
115 | { | ||
116 | int test, subtest; | ||
117 | |||
118 | test = 1; | ||
119 | subtest = memset16_selftest(); | ||
120 | if (subtest) | ||
121 | goto fail; | ||
122 | |||
123 | test = 2; | ||
124 | subtest = memset32_selftest(); | ||
125 | if (subtest) | ||
126 | goto fail; | ||
127 | |||
128 | test = 3; | ||
129 | subtest = memset64_selftest(); | ||
130 | if (subtest) | ||
131 | goto fail; | ||
132 | |||
133 | pr_info("String selftests succeeded\n"); | ||
134 | return 0; | ||
135 | fail: | ||
136 | pr_crit("String selftest failure %d.%08x\n", test, subtest); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | module_init(string_selftest_init); | ||
141 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/mm/Kconfig b/mm/Kconfig index 9c4bdddd80c2..03ff7703d322 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -756,3 +756,12 @@ config PERCPU_STATS | |||
756 | This feature collects and exposes statistics via debugfs. The | 756 | This feature collects and exposes statistics via debugfs. The |
757 | information includes global and per chunk statistics, which can | 757 | information includes global and per chunk statistics, which can |
758 | be used to help understand percpu memory usage. | 758 | be used to help understand percpu memory usage. |
759 | |||
760 | config GUP_BENCHMARK | ||
761 | bool "Enable infrastructure for get_user_pages_fast() benchmarking" | ||
762 | default n | ||
763 | help | ||
764 | Provides /sys/kernel/debug/gup_benchmark that helps with testing | ||
765 | performance of get_user_pages_fast(). | ||
766 | |||
767 | See tools/testing/selftests/vm/gup_benchmark.c | ||
diff --git a/mm/Makefile b/mm/Makefile index e7ebd176fb93..e669f02c5a54 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -80,6 +80,7 @@ obj-$(CONFIG_PAGE_COUNTER) += page_counter.o | |||
80 | obj-$(CONFIG_MEMCG) += memcontrol.o vmpressure.o | 80 | obj-$(CONFIG_MEMCG) += memcontrol.o vmpressure.o |
81 | obj-$(CONFIG_MEMCG_SWAP) += swap_cgroup.o | 81 | obj-$(CONFIG_MEMCG_SWAP) += swap_cgroup.o |
82 | obj-$(CONFIG_CGROUP_HUGETLB) += hugetlb_cgroup.o | 82 | obj-$(CONFIG_CGROUP_HUGETLB) += hugetlb_cgroup.o |
83 | obj-$(CONFIG_GUP_BENCHMARK) += gup_benchmark.o | ||
83 | obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o | 84 | obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o |
84 | obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o | 85 | obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o |
85 | obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o | 86 | obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o |
diff --git a/mm/compaction.c b/mm/compaction.c index 85395dc6eb13..10cd757f1006 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -219,6 +219,24 @@ static void reset_cached_positions(struct zone *zone) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /* | 221 | /* |
222 | * Compound pages of >= pageblock_order should consistenly be skipped until | ||
223 | * released. It is always pointless to compact pages of such order (if they are | ||
224 | * migratable), and the pageblocks they occupy cannot contain any free pages. | ||
225 | */ | ||
226 | static bool pageblock_skip_persistent(struct page *page) | ||
227 | { | ||
228 | if (!PageCompound(page)) | ||
229 | return false; | ||
230 | |||
231 | page = compound_head(page); | ||
232 | |||
233 | if (compound_order(page) >= pageblock_order) | ||
234 | return true; | ||
235 | |||
236 | return false; | ||
237 | } | ||
238 | |||
239 | /* | ||
222 | * This function is called to clear all cached information on pageblocks that | 240 | * This function is called to clear all cached information on pageblocks that |
223 | * should be skipped for page isolation when the migrate and free page scanner | 241 | * should be skipped for page isolation when the migrate and free page scanner |
224 | * meet. | 242 | * meet. |
@@ -242,6 +260,8 @@ static void __reset_isolation_suitable(struct zone *zone) | |||
242 | continue; | 260 | continue; |
243 | if (zone != page_zone(page)) | 261 | if (zone != page_zone(page)) |
244 | continue; | 262 | continue; |
263 | if (pageblock_skip_persistent(page)) | ||
264 | continue; | ||
245 | 265 | ||
246 | clear_pageblock_skip(page); | 266 | clear_pageblock_skip(page); |
247 | } | 267 | } |
@@ -275,7 +295,7 @@ static void update_pageblock_skip(struct compact_control *cc, | |||
275 | struct zone *zone = cc->zone; | 295 | struct zone *zone = cc->zone; |
276 | unsigned long pfn; | 296 | unsigned long pfn; |
277 | 297 | ||
278 | if (cc->ignore_skip_hint) | 298 | if (cc->no_set_skip_hint) |
279 | return; | 299 | return; |
280 | 300 | ||
281 | if (!page) | 301 | if (!page) |
@@ -307,7 +327,12 @@ static inline bool isolation_suitable(struct compact_control *cc, | |||
307 | return true; | 327 | return true; |
308 | } | 328 | } |
309 | 329 | ||
310 | static void update_pageblock_skip(struct compact_control *cc, | 330 | static inline bool pageblock_skip_persistent(struct page *page) |
331 | { | ||
332 | return false; | ||
333 | } | ||
334 | |||
335 | static inline void update_pageblock_skip(struct compact_control *cc, | ||
311 | struct page *page, unsigned long nr_isolated, | 336 | struct page *page, unsigned long nr_isolated, |
312 | bool migrate_scanner) | 337 | bool migrate_scanner) |
313 | { | 338 | { |
@@ -449,13 +474,12 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, | |||
449 | * and the only danger is skipping too much. | 474 | * and the only danger is skipping too much. |
450 | */ | 475 | */ |
451 | if (PageCompound(page)) { | 476 | if (PageCompound(page)) { |
452 | unsigned int comp_order = compound_order(page); | 477 | const unsigned int order = compound_order(page); |
453 | 478 | ||
454 | if (likely(comp_order < MAX_ORDER)) { | 479 | if (likely(order < MAX_ORDER)) { |
455 | blockpfn += (1UL << comp_order) - 1; | 480 | blockpfn += (1UL << order) - 1; |
456 | cursor += (1UL << comp_order) - 1; | 481 | cursor += (1UL << order) - 1; |
457 | } | 482 | } |
458 | |||
459 | goto isolate_fail; | 483 | goto isolate_fail; |
460 | } | 484 | } |
461 | 485 | ||
@@ -772,11 +796,10 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn, | |||
772 | * danger is skipping too much. | 796 | * danger is skipping too much. |
773 | */ | 797 | */ |
774 | if (PageCompound(page)) { | 798 | if (PageCompound(page)) { |
775 | unsigned int comp_order = compound_order(page); | 799 | const unsigned int order = compound_order(page); |
776 | |||
777 | if (likely(comp_order < MAX_ORDER)) | ||
778 | low_pfn += (1UL << comp_order) - 1; | ||
779 | 800 | ||
801 | if (likely(order < MAX_ORDER)) | ||
802 | low_pfn += (1UL << order) - 1; | ||
780 | goto isolate_fail; | 803 | goto isolate_fail; |
781 | } | 804 | } |
782 | 805 | ||
@@ -1928,9 +1951,8 @@ static void kcompactd_do_work(pg_data_t *pgdat) | |||
1928 | .total_free_scanned = 0, | 1951 | .total_free_scanned = 0, |
1929 | .classzone_idx = pgdat->kcompactd_classzone_idx, | 1952 | .classzone_idx = pgdat->kcompactd_classzone_idx, |
1930 | .mode = MIGRATE_SYNC_LIGHT, | 1953 | .mode = MIGRATE_SYNC_LIGHT, |
1931 | .ignore_skip_hint = true, | 1954 | .ignore_skip_hint = false, |
1932 | .gfp_mask = GFP_KERNEL, | 1955 | .gfp_mask = GFP_KERNEL, |
1933 | |||
1934 | }; | 1956 | }; |
1935 | trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order, | 1957 | trace_mm_compaction_kcompactd_wake(pgdat->node_id, cc.order, |
1936 | cc.classzone_idx); | 1958 | cc.classzone_idx); |
diff --git a/mm/gup_benchmark.c b/mm/gup_benchmark.c new file mode 100644 index 000000000000..5c8e2abeaa15 --- /dev/null +++ b/mm/gup_benchmark.c | |||
@@ -0,0 +1,100 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/mm.h> | ||
3 | #include <linux/slab.h> | ||
4 | #include <linux/uaccess.h> | ||
5 | #include <linux/ktime.h> | ||
6 | #include <linux/debugfs.h> | ||
7 | |||
8 | #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark) | ||
9 | |||
10 | struct gup_benchmark { | ||
11 | __u64 delta_usec; | ||
12 | __u64 addr; | ||
13 | __u64 size; | ||
14 | __u32 nr_pages_per_call; | ||
15 | __u32 flags; | ||
16 | }; | ||
17 | |||
18 | static int __gup_benchmark_ioctl(unsigned int cmd, | ||
19 | struct gup_benchmark *gup) | ||
20 | { | ||
21 | ktime_t start_time, end_time; | ||
22 | unsigned long i, nr, nr_pages, addr, next; | ||
23 | struct page **pages; | ||
24 | |||
25 | nr_pages = gup->size / PAGE_SIZE; | ||
26 | pages = kvmalloc(sizeof(void *) * nr_pages, GFP_KERNEL); | ||
27 | if (!pages) | ||
28 | return -ENOMEM; | ||
29 | |||
30 | i = 0; | ||
31 | nr = gup->nr_pages_per_call; | ||
32 | start_time = ktime_get(); | ||
33 | for (addr = gup->addr; addr < gup->addr + gup->size; addr = next) { | ||
34 | if (nr != gup->nr_pages_per_call) | ||
35 | break; | ||
36 | |||
37 | next = addr + nr * PAGE_SIZE; | ||
38 | if (next > gup->addr + gup->size) { | ||
39 | next = gup->addr + gup->size; | ||
40 | nr = (next - addr) / PAGE_SIZE; | ||
41 | } | ||
42 | |||
43 | nr = get_user_pages_fast(addr, nr, gup->flags & 1, pages + i); | ||
44 | i += nr; | ||
45 | } | ||
46 | end_time = ktime_get(); | ||
47 | |||
48 | gup->delta_usec = ktime_us_delta(end_time, start_time); | ||
49 | gup->size = addr - gup->addr; | ||
50 | |||
51 | for (i = 0; i < nr_pages; i++) { | ||
52 | if (!pages[i]) | ||
53 | break; | ||
54 | put_page(pages[i]); | ||
55 | } | ||
56 | |||
57 | kvfree(pages); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static long gup_benchmark_ioctl(struct file *filep, unsigned int cmd, | ||
62 | unsigned long arg) | ||
63 | { | ||
64 | struct gup_benchmark gup; | ||
65 | int ret; | ||
66 | |||
67 | if (cmd != GUP_FAST_BENCHMARK) | ||
68 | return -EINVAL; | ||
69 | |||
70 | if (copy_from_user(&gup, (void __user *)arg, sizeof(gup))) | ||
71 | return -EFAULT; | ||
72 | |||
73 | ret = __gup_benchmark_ioctl(cmd, &gup); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | if (copy_to_user((void __user *)arg, &gup, sizeof(gup))) | ||
78 | return -EFAULT; | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static const struct file_operations gup_benchmark_fops = { | ||
84 | .open = nonseekable_open, | ||
85 | .unlocked_ioctl = gup_benchmark_ioctl, | ||
86 | }; | ||
87 | |||
88 | static int gup_benchmark_init(void) | ||
89 | { | ||
90 | void *ret; | ||
91 | |||
92 | ret = debugfs_create_file_unsafe("gup_benchmark", 0600, NULL, NULL, | ||
93 | &gup_benchmark_fops); | ||
94 | if (!ret) | ||
95 | pr_warn("Failed to create gup_benchmark in debugfs"); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | late_initcall(gup_benchmark_init); | ||
diff --git a/mm/internal.h b/mm/internal.h index 1df011f62480..e6bd35182dae 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -198,6 +198,7 @@ struct compact_control { | |||
198 | const int classzone_idx; /* zone index of a direct compactor */ | 198 | const int classzone_idx; /* zone index of a direct compactor */ |
199 | enum migrate_mode mode; /* Async or sync migration mode */ | 199 | enum migrate_mode mode; /* Async or sync migration mode */ |
200 | bool ignore_skip_hint; /* Scan blocks even if marked skip */ | 200 | bool ignore_skip_hint; /* Scan blocks even if marked skip */ |
201 | bool no_set_skip_hint; /* Don't mark blocks for skipping */ | ||
201 | bool ignore_block_suitable; /* Scan blocks considered unsuitable */ | 202 | bool ignore_block_suitable; /* Scan blocks considered unsuitable */ |
202 | bool direct_compaction; /* False from kcompactd or /proc/... */ | 203 | bool direct_compaction; /* False from kcompactd or /proc/... */ |
203 | bool whole_zone; /* Whole zone should/has been scanned */ | 204 | bool whole_zone; /* Whole zone should/has been scanned */ |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 55ded92f9809..d4096f4a5c1f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -7619,6 +7619,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
7619 | .zone = page_zone(pfn_to_page(start)), | 7619 | .zone = page_zone(pfn_to_page(start)), |
7620 | .mode = MIGRATE_SYNC, | 7620 | .mode = MIGRATE_SYNC, |
7621 | .ignore_skip_hint = true, | 7621 | .ignore_skip_hint = true, |
7622 | .no_set_skip_hint = true, | ||
7622 | .gfp_mask = current_gfp_context(gfp_mask), | 7623 | .gfp_mask = current_gfp_context(gfp_mask), |
7623 | }; | 7624 | }; |
7624 | INIT_LIST_HEAD(&cc.migratepages); | 7625 | INIT_LIST_HEAD(&cc.migratepages); |
diff --git a/mm/shmem.c b/mm/shmem.c index 1f97d77551c3..4aa9307feab0 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -3202,7 +3202,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
3202 | int len; | 3202 | int len; |
3203 | struct inode *inode; | 3203 | struct inode *inode; |
3204 | struct page *page; | 3204 | struct page *page; |
3205 | struct shmem_inode_info *info; | ||
3206 | 3205 | ||
3207 | len = strlen(symname) + 1; | 3206 | len = strlen(symname) + 1; |
3208 | if (len > PAGE_SIZE) | 3207 | if (len > PAGE_SIZE) |
@@ -3222,7 +3221,6 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
3222 | error = 0; | 3221 | error = 0; |
3223 | } | 3222 | } |
3224 | 3223 | ||
3225 | info = SHMEM_I(inode); | ||
3226 | inode->i_size = len-1; | 3224 | inode->i_size = len-1; |
3227 | if (len <= SHORT_SYMLINK_LEN) { | 3225 | if (len <= SHORT_SYMLINK_LEN) { |
3228 | inode->i_link = kmemdup(symname, len, GFP_KERNEL); | 3226 | inode->i_link = kmemdup(symname, len, GFP_KERNEL); |
diff --git a/mm/z3fold.c b/mm/z3fold.c index b2ba2ba585f3..39e19125d6a0 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c | |||
@@ -404,8 +404,7 @@ static void do_compact_page(struct z3fold_header *zhdr, bool locked) | |||
404 | WARN_ON(z3fold_page_trylock(zhdr)); | 404 | WARN_ON(z3fold_page_trylock(zhdr)); |
405 | else | 405 | else |
406 | z3fold_page_lock(zhdr); | 406 | z3fold_page_lock(zhdr); |
407 | if (test_bit(PAGE_STALE, &page->private) || | 407 | if (WARN_ON(!test_and_clear_bit(NEEDS_COMPACTING, &page->private))) { |
408 | !test_and_clear_bit(NEEDS_COMPACTING, &page->private)) { | ||
409 | z3fold_page_unlock(zhdr); | 408 | z3fold_page_unlock(zhdr); |
410 | return; | 409 | return; |
411 | } | 410 | } |
@@ -413,6 +412,11 @@ static void do_compact_page(struct z3fold_header *zhdr, bool locked) | |||
413 | list_del_init(&zhdr->buddy); | 412 | list_del_init(&zhdr->buddy); |
414 | spin_unlock(&pool->lock); | 413 | spin_unlock(&pool->lock); |
415 | 414 | ||
415 | if (kref_put(&zhdr->refcount, release_z3fold_page_locked)) { | ||
416 | atomic64_dec(&pool->pages_nr); | ||
417 | return; | ||
418 | } | ||
419 | |||
416 | z3fold_compact_page(zhdr); | 420 | z3fold_compact_page(zhdr); |
417 | unbuddied = get_cpu_ptr(pool->unbuddied); | 421 | unbuddied = get_cpu_ptr(pool->unbuddied); |
418 | fchunks = num_free_chunks(zhdr); | 422 | fchunks = num_free_chunks(zhdr); |
@@ -753,9 +757,11 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) | |||
753 | list_del_init(&zhdr->buddy); | 757 | list_del_init(&zhdr->buddy); |
754 | spin_unlock(&pool->lock); | 758 | spin_unlock(&pool->lock); |
755 | zhdr->cpu = -1; | 759 | zhdr->cpu = -1; |
760 | kref_get(&zhdr->refcount); | ||
756 | do_compact_page(zhdr, true); | 761 | do_compact_page(zhdr, true); |
757 | return; | 762 | return; |
758 | } | 763 | } |
764 | kref_get(&zhdr->refcount); | ||
759 | queue_work_on(zhdr->cpu, pool->compact_wq, &zhdr->work); | 765 | queue_work_on(zhdr->cpu, pool->compact_wq, &zhdr->work); |
760 | z3fold_page_unlock(zhdr); | 766 | z3fold_page_unlock(zhdr); |
761 | } | 767 | } |
diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov new file mode 100644 index 000000000000..5cc72037e423 --- /dev/null +++ b/scripts/Makefile.kcov | |||
@@ -0,0 +1,7 @@ | |||
1 | ifdef CONFIG_KCOV | ||
2 | CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) | ||
3 | ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y) | ||
4 | CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,) | ||
5 | endif | ||
6 | |||
7 | endif | ||
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8b80bac055e4..95cda3ecc66b 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -454,6 +454,7 @@ our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; | |||
454 | our $logFunctions = qr{(?x: | 454 | our $logFunctions = qr{(?x: |
455 | printk(?:_ratelimited|_once|_deferred_once|_deferred|)| | 455 | printk(?:_ratelimited|_once|_deferred_once|_deferred|)| |
456 | (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| | 456 | (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| |
457 | TP_printk| | ||
457 | WARN(?:_RATELIMIT|_ONCE|)| | 458 | WARN(?:_RATELIMIT|_ONCE|)| |
458 | panic| | 459 | panic| |
459 | MODULE_[A-Z_]+| | 460 | MODULE_[A-Z_]+| |
@@ -2900,8 +2901,9 @@ sub process { | |||
2900 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { | 2901 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { |
2901 | $msg_type = ""; | 2902 | $msg_type = ""; |
2902 | 2903 | ||
2903 | # EFI_GUID is another special case | 2904 | # More special cases |
2904 | } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { | 2905 | } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || |
2906 | $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { | ||
2905 | $msg_type = ""; | 2907 | $msg_type = ""; |
2906 | 2908 | ||
2907 | # Otherwise set the alternate message types | 2909 | # Otherwise set the alternate message types |
@@ -3103,6 +3105,7 @@ sub process { | |||
3103 | $line =~ /^\+[a-z_]*init/ || | 3105 | $line =~ /^\+[a-z_]*init/ || |
3104 | $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || | 3106 | $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || |
3105 | $line =~ /^\+\s*DECLARE/ || | 3107 | $line =~ /^\+\s*DECLARE/ || |
3108 | $line =~ /^\+\s*builtin_[\w_]*driver/ || | ||
3106 | $line =~ /^\+\s*__setup/)) { | 3109 | $line =~ /^\+\s*__setup/)) { |
3107 | if (CHK("LINE_SPACING", | 3110 | if (CHK("LINE_SPACING", |
3108 | "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && | 3111 | "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && |
@@ -3182,6 +3185,12 @@ sub process { | |||
3182 | # check we are in a valid C source file if not then ignore this hunk | 3185 | # check we are in a valid C source file if not then ignore this hunk |
3183 | next if ($realfile !~ /\.(h|c)$/); | 3186 | next if ($realfile !~ /\.(h|c)$/); |
3184 | 3187 | ||
3188 | # check for unusual line ending [ or ( | ||
3189 | if ($line =~ /^\+.*([\[\(])\s*$/) { | ||
3190 | CHK("OPEN_ENDED_LINE", | ||
3191 | "Lines should not end with a '$1'\n" . $herecurr); | ||
3192 | } | ||
3193 | |||
3185 | # check if this appears to be the start function declaration, save the name | 3194 | # check if this appears to be the start function declaration, save the name |
3186 | if ($sline =~ /^\+\{\s*$/ && | 3195 | if ($sline =~ /^\+\{\s*$/ && |
3187 | $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { | 3196 | $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { |
@@ -3829,28 +3838,10 @@ sub process { | |||
3829 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); | 3838 | "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); |
3830 | } | 3839 | } |
3831 | 3840 | ||
3832 | # printk should use KERN_* levels. Note that follow on printk's on the | 3841 | # printk should use KERN_* levels |
3833 | # same line do not need a level, so we use the current block context | 3842 | if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { |
3834 | # to try and find and validate the current printk. In summary the current | 3843 | WARN("PRINTK_WITHOUT_KERN_LEVEL", |
3835 | # printk includes all preceding printk's which have no newline on the end. | 3844 | "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); |
3836 | # we assume the first bad printk is the one to report. | ||
3837 | if ($line =~ /\bprintk\((?!KERN_)\s*"/) { | ||
3838 | my $ok = 0; | ||
3839 | for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { | ||
3840 | #print "CHECK<$lines[$ln - 1]\n"; | ||
3841 | # we have a preceding printk if it ends | ||
3842 | # with "\n" ignore it, else it is to blame | ||
3843 | if ($lines[$ln - 1] =~ m{\bprintk\(}) { | ||
3844 | if ($rawlines[$ln - 1] !~ m{\\n"}) { | ||
3845 | $ok = 1; | ||
3846 | } | ||
3847 | last; | ||
3848 | } | ||
3849 | } | ||
3850 | if ($ok == 0) { | ||
3851 | WARN("PRINTK_WITHOUT_KERN_LEVEL", | ||
3852 | "printk() should include KERN_ facility level\n" . $herecurr); | ||
3853 | } | ||
3854 | } | 3845 | } |
3855 | 3846 | ||
3856 | if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { | 3847 | if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { |
@@ -5957,7 +5948,7 @@ sub process { | |||
5957 | 5948 | ||
5958 | # check for function declarations that have arguments without identifier names | 5949 | # check for function declarations that have arguments without identifier names |
5959 | if (defined $stat && | 5950 | if (defined $stat && |
5960 | $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && | 5951 | $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && |
5961 | $1 ne "void") { | 5952 | $1 ne "void") { |
5962 | my $args = trim($1); | 5953 | my $args = trim($1); |
5963 | while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { | 5954 | while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { |
@@ -6109,7 +6100,7 @@ sub process { | |||
6109 | next if ($fline =~ /^.[\s$;]*$/); | 6100 | next if ($fline =~ /^.[\s$;]*$/); |
6110 | $has_statement = 1; | 6101 | $has_statement = 1; |
6111 | $count++; | 6102 | $count++; |
6112 | $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); | 6103 | $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); |
6113 | } | 6104 | } |
6114 | if (!$has_break && $has_statement) { | 6105 | if (!$has_break && $has_statement) { |
6115 | WARN("MISSING_BREAK", | 6106 | WARN("MISSING_BREAK", |
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index bc443201d3ef..99c96e86eccb 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
@@ -57,6 +57,7 @@ my $sections = 0; | |||
57 | my $file_emails = 0; | 57 | my $file_emails = 0; |
58 | my $from_filename = 0; | 58 | my $from_filename = 0; |
59 | my $pattern_depth = 0; | 59 | my $pattern_depth = 0; |
60 | my $self_test = undef; | ||
60 | my $version = 0; | 61 | my $version = 0; |
61 | my $help = 0; | 62 | my $help = 0; |
62 | my $find_maintainer_files = 0; | 63 | my $find_maintainer_files = 0; |
@@ -138,6 +139,7 @@ my %VCS_cmds_git = ( | |||
138 | "subject_pattern" => "^GitSubject: (.*)", | 139 | "subject_pattern" => "^GitSubject: (.*)", |
139 | "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$", | 140 | "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$", |
140 | "file_exists_cmd" => "git ls-files \$file", | 141 | "file_exists_cmd" => "git ls-files \$file", |
142 | "list_files_cmd" => "git ls-files \$file", | ||
141 | ); | 143 | ); |
142 | 144 | ||
143 | my %VCS_cmds_hg = ( | 145 | my %VCS_cmds_hg = ( |
@@ -167,6 +169,7 @@ my %VCS_cmds_hg = ( | |||
167 | "subject_pattern" => "^HgSubject: (.*)", | 169 | "subject_pattern" => "^HgSubject: (.*)", |
168 | "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$", | 170 | "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$", |
169 | "file_exists_cmd" => "hg files \$file", | 171 | "file_exists_cmd" => "hg files \$file", |
172 | "list_files_cmd" => "hg manifest -R \$file", | ||
170 | ); | 173 | ); |
171 | 174 | ||
172 | my $conf = which_conf(".get_maintainer.conf"); | 175 | my $conf = which_conf(".get_maintainer.conf"); |
@@ -216,6 +219,14 @@ if (-f $ignore_file) { | |||
216 | close($ignore); | 219 | close($ignore); |
217 | } | 220 | } |
218 | 221 | ||
222 | if ($#ARGV > 0) { | ||
223 | foreach (@ARGV) { | ||
224 | if ($_ =~ /^-{1,2}self-test(?:=|$)/) { | ||
225 | die "$P: using --self-test does not allow any other option or argument\n"; | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
219 | if (!GetOptions( | 230 | if (!GetOptions( |
220 | 'email!' => \$email, | 231 | 'email!' => \$email, |
221 | 'git!' => \$email_git, | 232 | 'git!' => \$email_git, |
@@ -252,6 +263,7 @@ if (!GetOptions( | |||
252 | 'fe|file-emails!' => \$file_emails, | 263 | 'fe|file-emails!' => \$file_emails, |
253 | 'f|file' => \$from_filename, | 264 | 'f|file' => \$from_filename, |
254 | 'find-maintainer-files' => \$find_maintainer_files, | 265 | 'find-maintainer-files' => \$find_maintainer_files, |
266 | 'self-test:s' => \$self_test, | ||
255 | 'v|version' => \$version, | 267 | 'v|version' => \$version, |
256 | 'h|help|usage' => \$help, | 268 | 'h|help|usage' => \$help, |
257 | )) { | 269 | )) { |
@@ -268,6 +280,12 @@ if ($version != 0) { | |||
268 | exit 0; | 280 | exit 0; |
269 | } | 281 | } |
270 | 282 | ||
283 | if (defined $self_test) { | ||
284 | read_all_maintainer_files(); | ||
285 | self_test(); | ||
286 | exit 0; | ||
287 | } | ||
288 | |||
271 | if (-t STDIN && !@ARGV) { | 289 | if (-t STDIN && !@ARGV) { |
272 | # We're talking to a terminal, but have no command line arguments. | 290 | # We're talking to a terminal, but have no command line arguments. |
273 | die "$P: missing patchfile or -f file - use --help if necessary\n"; | 291 | die "$P: missing patchfile or -f file - use --help if necessary\n"; |
@@ -311,14 +329,17 @@ if (!top_of_kernel_tree($lk_path)) { | |||
311 | my @typevalue = (); | 329 | my @typevalue = (); |
312 | my %keyword_hash; | 330 | my %keyword_hash; |
313 | my @mfiles = (); | 331 | my @mfiles = (); |
332 | my @self_test_info = (); | ||
314 | 333 | ||
315 | sub read_maintainer_file { | 334 | sub read_maintainer_file { |
316 | my ($file) = @_; | 335 | my ($file) = @_; |
317 | 336 | ||
318 | open (my $maint, '<', "$file") | 337 | open (my $maint, '<', "$file") |
319 | or die "$P: Can't open MAINTAINERS file '$file': $!\n"; | 338 | or die "$P: Can't open MAINTAINERS file '$file': $!\n"; |
339 | my $i = 1; | ||
320 | while (<$maint>) { | 340 | while (<$maint>) { |
321 | my $line = $_; | 341 | my $line = $_; |
342 | chomp $line; | ||
322 | 343 | ||
323 | if ($line =~ m/^([A-Z]):\s*(.*)/) { | 344 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
324 | my $type = $1; | 345 | my $type = $1; |
@@ -338,9 +359,12 @@ sub read_maintainer_file { | |||
338 | } | 359 | } |
339 | push(@typevalue, "$type:$value"); | 360 | push(@typevalue, "$type:$value"); |
340 | } elsif (!(/^\s*$/ || /^\s*\#/)) { | 361 | } elsif (!(/^\s*$/ || /^\s*\#/)) { |
341 | $line =~ s/\n$//g; | ||
342 | push(@typevalue, $line); | 362 | push(@typevalue, $line); |
343 | } | 363 | } |
364 | if (defined $self_test) { | ||
365 | push(@self_test_info, {file=>$file, linenr=>$i, line=>$line}); | ||
366 | } | ||
367 | $i++; | ||
344 | } | 368 | } |
345 | close($maint); | 369 | close($maint); |
346 | } | 370 | } |
@@ -357,26 +381,30 @@ sub find_ignore_git { | |||
357 | return grep { $_ !~ /^\.git$/; } @_; | 381 | return grep { $_ !~ /^\.git$/; } @_; |
358 | } | 382 | } |
359 | 383 | ||
360 | if (-d "${lk_path}MAINTAINERS") { | 384 | read_all_maintainer_files(); |
361 | opendir(DIR, "${lk_path}MAINTAINERS") or die $!; | 385 | |
362 | my @files = readdir(DIR); | 386 | sub read_all_maintainer_files { |
363 | closedir(DIR); | 387 | if (-d "${lk_path}MAINTAINERS") { |
364 | foreach my $file (@files) { | 388 | opendir(DIR, "${lk_path}MAINTAINERS") or die $!; |
365 | push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); | 389 | my @files = readdir(DIR); |
390 | closedir(DIR); | ||
391 | foreach my $file (@files) { | ||
392 | push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./); | ||
393 | } | ||
366 | } | 394 | } |
367 | } | ||
368 | 395 | ||
369 | if ($find_maintainer_files) { | 396 | if ($find_maintainer_files) { |
370 | find( { wanted => \&find_is_maintainer_file, | 397 | find( { wanted => \&find_is_maintainer_file, |
371 | preprocess => \&find_ignore_git, | 398 | preprocess => \&find_ignore_git, |
372 | no_chdir => 1, | 399 | no_chdir => 1, |
373 | }, "${lk_path}"); | 400 | }, "${lk_path}"); |
374 | } else { | 401 | } else { |
375 | push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; | 402 | push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS"; |
376 | } | 403 | } |
377 | 404 | ||
378 | foreach my $file (@mfiles) { | 405 | foreach my $file (@mfiles) { |
379 | read_maintainer_file("$file"); | 406 | read_maintainer_file("$file"); |
407 | } | ||
380 | } | 408 | } |
381 | 409 | ||
382 | # | 410 | # |
@@ -586,6 +614,135 @@ if ($web) { | |||
586 | 614 | ||
587 | exit($exit); | 615 | exit($exit); |
588 | 616 | ||
617 | sub self_test { | ||
618 | my @lsfiles = (); | ||
619 | my @good_links = (); | ||
620 | my @bad_links = (); | ||
621 | my @section_headers = (); | ||
622 | my $index = 0; | ||
623 | |||
624 | @lsfiles = vcs_list_files($lk_path); | ||
625 | |||
626 | for my $x (@self_test_info) { | ||
627 | $index++; | ||
628 | |||
629 | ## Section header duplication and missing section content | ||
630 | if (($self_test eq "" || $self_test =~ /\bsections\b/) && | ||
631 | $x->{line} =~ /^\S[^:]/ && | ||
632 | defined $self_test_info[$index] && | ||
633 | $self_test_info[$index]->{line} =~ /^([A-Z]):\s*\S/) { | ||
634 | my $has_S = 0; | ||
635 | my $has_F = 0; | ||
636 | my $has_ML = 0; | ||
637 | my $status = ""; | ||
638 | if (grep(m@^\Q$x->{line}\E@, @section_headers)) { | ||
639 | print("$x->{file}:$x->{linenr}: warning: duplicate section header\t$x->{line}\n"); | ||
640 | } else { | ||
641 | push(@section_headers, $x->{line}); | ||
642 | } | ||
643 | my $nextline = $index; | ||
644 | while (defined $self_test_info[$nextline] && | ||
645 | $self_test_info[$nextline]->{line} =~ /^([A-Z]):\s*(\S.*)/) { | ||
646 | my $type = $1; | ||
647 | my $value = $2; | ||
648 | if ($type eq "S") { | ||
649 | $has_S = 1; | ||
650 | $status = $value; | ||
651 | } elsif ($type eq "F" || $type eq "N") { | ||
652 | $has_F = 1; | ||
653 | } elsif ($type eq "M" || $type eq "R" || $type eq "L") { | ||
654 | $has_ML = 1; | ||
655 | } | ||
656 | $nextline++; | ||
657 | } | ||
658 | if (!$has_ML && $status !~ /orphan|obsolete/i) { | ||
659 | print("$x->{file}:$x->{linenr}: warning: section without email address\t$x->{line}\n"); | ||
660 | } | ||
661 | if (!$has_S) { | ||
662 | print("$x->{file}:$x->{linenr}: warning: section without status \t$x->{line}\n"); | ||
663 | } | ||
664 | if (!$has_F) { | ||
665 | print("$x->{file}:$x->{linenr}: warning: section without file pattern\t$x->{line}\n"); | ||
666 | } | ||
667 | } | ||
668 | |||
669 | next if ($x->{line} !~ /^([A-Z]):\s*(.*)/); | ||
670 | |||
671 | my $type = $1; | ||
672 | my $value = $2; | ||
673 | |||
674 | ## Filename pattern matching | ||
675 | if (($type eq "F" || $type eq "X") && | ||
676 | ($self_test eq "" || $self_test =~ /\bpatterns\b/)) { | ||
677 | $value =~ s@\.@\\\.@g; ##Convert . to \. | ||
678 | $value =~ s/\*/\.\*/g; ##Convert * to .* | ||
679 | $value =~ s/\?/\./g; ##Convert ? to . | ||
680 | ##if pattern is a directory and it lacks a trailing slash, add one | ||
681 | if ((-d $value)) { | ||
682 | $value =~ s@([^/])$@$1/@; | ||
683 | } | ||
684 | if (!grep(m@^$value@, @lsfiles)) { | ||
685 | print("$x->{file}:$x->{linenr}: warning: no file matches\t$x->{line}\n"); | ||
686 | } | ||
687 | |||
688 | ## Link reachability | ||
689 | } elsif (($type eq "W" || $type eq "Q" || $type eq "B") && | ||
690 | $value =~ /^https?:/ && | ||
691 | ($self_test eq "" || $self_test =~ /\blinks\b/)) { | ||
692 | next if (grep(m@^\Q$value\E$@, @good_links)); | ||
693 | my $isbad = 0; | ||
694 | if (grep(m@^\Q$value\E$@, @bad_links)) { | ||
695 | $isbad = 1; | ||
696 | } else { | ||
697 | my $output = `wget --spider -q --no-check-certificate --timeout 10 --tries 1 $value`; | ||
698 | if ($? == 0) { | ||
699 | push(@good_links, $value); | ||
700 | } else { | ||
701 | push(@bad_links, $value); | ||
702 | $isbad = 1; | ||
703 | } | ||
704 | } | ||
705 | if ($isbad) { | ||
706 | print("$x->{file}:$x->{linenr}: warning: possible bad link\t$x->{line}\n"); | ||
707 | } | ||
708 | |||
709 | ## SCM reachability | ||
710 | } elsif ($type eq "T" && | ||
711 | ($self_test eq "" || $self_test =~ /\bscm\b/)) { | ||
712 | next if (grep(m@^\Q$value\E$@, @good_links)); | ||
713 | my $isbad = 0; | ||
714 | if (grep(m@^\Q$value\E$@, @bad_links)) { | ||
715 | $isbad = 1; | ||
716 | } elsif ($value !~ /^(?:git|quilt|hg)\s+\S/) { | ||
717 | print("$x->{file}:$x->{linenr}: warning: malformed entry\t$x->{line}\n"); | ||
718 | } elsif ($value =~ /^git\s+(\S+)(\s+([^\(]+\S+))?/) { | ||
719 | my $url = $1; | ||
720 | my $branch = ""; | ||
721 | $branch = $3 if $3; | ||
722 | my $output = `git ls-remote --exit-code -h "$url" $branch > /dev/null 2>&1`; | ||
723 | if ($? == 0) { | ||
724 | push(@good_links, $value); | ||
725 | } else { | ||
726 | push(@bad_links, $value); | ||
727 | $isbad = 1; | ||
728 | } | ||
729 | } elsif ($value =~ /^(?:quilt|hg)\s+(https?:\S+)/) { | ||
730 | my $url = $1; | ||
731 | my $output = `wget --spider -q --no-check-certificate --timeout 10 --tries 1 $url`; | ||
732 | if ($? == 0) { | ||
733 | push(@good_links, $value); | ||
734 | } else { | ||
735 | push(@bad_links, $value); | ||
736 | $isbad = 1; | ||
737 | } | ||
738 | } | ||
739 | if ($isbad) { | ||
740 | print("$x->{file}:$x->{linenr}: warning: possible bad link\t$x->{line}\n"); | ||
741 | } | ||
742 | } | ||
743 | } | ||
744 | } | ||
745 | |||
589 | sub ignore_email_address { | 746 | sub ignore_email_address { |
590 | my ($address) = @_; | 747 | my ($address) = @_; |
591 | 748 | ||
@@ -863,6 +1020,7 @@ Other options: | |||
863 | --sections => print all of the subsystem sections with pattern matches | 1020 | --sections => print all of the subsystem sections with pattern matches |
864 | --letters => print all matching 'letter' types from all matching sections | 1021 | --letters => print all matching 'letter' types from all matching sections |
865 | --mailmap => use .mailmap file (default: $email_use_mailmap) | 1022 | --mailmap => use .mailmap file (default: $email_use_mailmap) |
1023 | --self-test => show potential issues with MAINTAINERS file content | ||
866 | --version => show version | 1024 | --version => show version |
867 | --help => show this help information | 1025 | --help => show this help information |
868 | 1026 | ||
@@ -2192,6 +2350,23 @@ sub vcs_file_exists { | |||
2192 | return $exists; | 2350 | return $exists; |
2193 | } | 2351 | } |
2194 | 2352 | ||
2353 | sub vcs_list_files { | ||
2354 | my ($file) = @_; | ||
2355 | |||
2356 | my @lsfiles = (); | ||
2357 | |||
2358 | my $vcs_used = vcs_exists(); | ||
2359 | return 0 if (!$vcs_used); | ||
2360 | |||
2361 | my $cmd = $VCS_cmds{"list_files_cmd"}; | ||
2362 | $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd | ||
2363 | @lsfiles = &{$VCS_cmds{"execute_cmd"}}($cmd); | ||
2364 | |||
2365 | return () if ($? != 0); | ||
2366 | |||
2367 | return @lsfiles; | ||
2368 | } | ||
2369 | |||
2195 | sub uniq { | 2370 | sub uniq { |
2196 | my (@parms) = @_; | 2371 | my (@parms) = @_; |
2197 | 2372 | ||
diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl index 5dbd2faa2449..255cef1b098d 100644 --- a/scripts/parse-maintainers.pl +++ b/scripts/parse-maintainers.pl | |||
@@ -2,9 +2,44 @@ | |||
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | use strict; | 4 | use strict; |
5 | use Getopt::Long qw(:config no_auto_abbrev); | ||
6 | |||
7 | my $input_file = "MAINTAINERS"; | ||
8 | my $output_file = "MAINTAINERS.new"; | ||
9 | my $output_section = "SECTION.new"; | ||
10 | my $help = 0; | ||
5 | 11 | ||
6 | my $P = $0; | 12 | my $P = $0; |
7 | 13 | ||
14 | if (!GetOptions( | ||
15 | 'input=s' => \$input_file, | ||
16 | 'output=s' => \$output_file, | ||
17 | 'section=s' => \$output_section, | ||
18 | 'h|help|usage' => \$help, | ||
19 | )) { | ||
20 | die "$P: invalid argument - use --help if necessary\n"; | ||
21 | } | ||
22 | |||
23 | if ($help != 0) { | ||
24 | usage(); | ||
25 | exit 0; | ||
26 | } | ||
27 | |||
28 | sub usage { | ||
29 | print <<EOT; | ||
30 | usage: $P [options] <pattern matching regexes> | ||
31 | |||
32 | --input => MAINTAINERS file to read (default: MAINTAINERS) | ||
33 | --output => sorted MAINTAINERS file to write (default: MAINTAINERS.new) | ||
34 | --section => new sorted MAINTAINERS file to write to (default: SECTION.new) | ||
35 | |||
36 | If <pattern match regexes> exist, then the sections that match the | ||
37 | regexes are not written to the output file but are written to the | ||
38 | section file. | ||
39 | |||
40 | EOT | ||
41 | } | ||
42 | |||
8 | # sort comparison functions | 43 | # sort comparison functions |
9 | sub by_category($$) { | 44 | sub by_category($$) { |
10 | my ($a, $b) = @_; | 45 | my ($a, $b) = @_; |
@@ -56,13 +91,20 @@ sub trim { | |||
56 | sub alpha_output { | 91 | sub alpha_output { |
57 | my ($hashref, $filename) = (@_); | 92 | my ($hashref, $filename) = (@_); |
58 | 93 | ||
94 | return if ! scalar(keys %$hashref); | ||
95 | |||
59 | open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n"; | 96 | open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n"; |
97 | my $separator; | ||
60 | foreach my $key (sort by_category keys %$hashref) { | 98 | foreach my $key (sort by_category keys %$hashref) { |
61 | if ($key eq " ") { | 99 | if ($key eq " ") { |
62 | chomp $$hashref{$key}; | ||
63 | print $file $$hashref{$key}; | 100 | print $file $$hashref{$key}; |
64 | } else { | 101 | } else { |
65 | print $file "\n" . $key . "\n"; | 102 | if (! defined $separator) { |
103 | $separator = "\n"; | ||
104 | } else { | ||
105 | print $file $separator; | ||
106 | } | ||
107 | print $file $key . "\n"; | ||
66 | foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) { | 108 | foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) { |
67 | print $file ($pattern . "\n"); | 109 | print $file ($pattern . "\n"); |
68 | } | 110 | } |
@@ -112,7 +154,7 @@ sub file_input { | |||
112 | my %hash; | 154 | my %hash; |
113 | my %new_hash; | 155 | my %new_hash; |
114 | 156 | ||
115 | file_input(\%hash, "MAINTAINERS"); | 157 | file_input(\%hash, $input_file); |
116 | 158 | ||
117 | foreach my $type (@ARGV) { | 159 | foreach my $type (@ARGV) { |
118 | foreach my $key (keys %hash) { | 160 | foreach my $key (keys %hash) { |
@@ -123,7 +165,7 @@ foreach my $type (@ARGV) { | |||
123 | } | 165 | } |
124 | } | 166 | } |
125 | 167 | ||
126 | alpha_output(\%hash, "MAINTAINERS.new"); | 168 | alpha_output(\%hash, $output_file); |
127 | alpha_output(\%new_hash, "SECTION.new"); | 169 | alpha_output(\%new_hash, $output_section); |
128 | 170 | ||
129 | exit(0); | 171 | exit(0); |
diff --git a/scripts/spelling.txt b/scripts/spelling.txt index aa0cc49ad1ad..9a058cff49d4 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt | |||
@@ -1187,6 +1187,10 @@ unknonw||unknown | |||
1187 | unknow||unknown | 1187 | unknow||unknown |
1188 | unkown||unknown | 1188 | unkown||unknown |
1189 | unneded||unneeded | 1189 | unneded||unneeded |
1190 | unneccecary||unnecessary | ||
1191 | unneccesary||unnecessary | ||
1192 | unneccessary||unnecessary | ||
1193 | unnecesary||unnecessary | ||
1190 | unneedingly||unnecessarily | 1194 | unneedingly||unnecessarily |
1191 | unnsupported||unsupported | 1195 | unnsupported||unsupported |
1192 | unmached||unmatched | 1196 | unmached||unmatched |
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index 7c214ceb9386..315df0a70265 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c | |||
@@ -436,13 +436,13 @@ create_arg_exp(enum filter_exp_type etype) | |||
436 | return NULL; | 436 | return NULL; |
437 | 437 | ||
438 | arg->type = FILTER_ARG_EXP; | 438 | arg->type = FILTER_ARG_EXP; |
439 | arg->op.type = etype; | 439 | arg->exp.type = etype; |
440 | 440 | ||
441 | return arg; | 441 | return arg; |
442 | } | 442 | } |
443 | 443 | ||
444 | static struct filter_arg * | 444 | static struct filter_arg * |
445 | create_arg_cmp(enum filter_exp_type etype) | 445 | create_arg_cmp(enum filter_cmp_type ctype) |
446 | { | 446 | { |
447 | struct filter_arg *arg; | 447 | struct filter_arg *arg; |
448 | 448 | ||
@@ -452,7 +452,7 @@ create_arg_cmp(enum filter_exp_type etype) | |||
452 | 452 | ||
453 | /* Use NUM and change if necessary */ | 453 | /* Use NUM and change if necessary */ |
454 | arg->type = FILTER_ARG_NUM; | 454 | arg->type = FILTER_ARG_NUM; |
455 | arg->op.type = etype; | 455 | arg->num.type = ctype; |
456 | 456 | ||
457 | return arg; | 457 | return arg; |
458 | } | 458 | } |
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index e49eca1915f8..7f45806bd863 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile | |||
@@ -18,6 +18,7 @@ TEST_GEN_FILES += transhuge-stress | |||
18 | TEST_GEN_FILES += userfaultfd | 18 | TEST_GEN_FILES += userfaultfd |
19 | TEST_GEN_FILES += mlock-random-test | 19 | TEST_GEN_FILES += mlock-random-test |
20 | TEST_GEN_FILES += virtual_address_range | 20 | TEST_GEN_FILES += virtual_address_range |
21 | TEST_GEN_FILES += gup_benchmark | ||
21 | 22 | ||
22 | TEST_PROGS := run_vmtests | 23 | TEST_PROGS := run_vmtests |
23 | 24 | ||
diff --git a/tools/testing/selftests/vm/gup_benchmark.c b/tools/testing/selftests/vm/gup_benchmark.c new file mode 100644 index 000000000000..36df55132036 --- /dev/null +++ b/tools/testing/selftests/vm/gup_benchmark.c | |||
@@ -0,0 +1,91 @@ | |||
1 | #include <fcntl.h> | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <unistd.h> | ||
5 | |||
6 | #include <sys/ioctl.h> | ||
7 | #include <sys/mman.h> | ||
8 | #include <sys/prctl.h> | ||
9 | #include <sys/stat.h> | ||
10 | #include <sys/types.h> | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | #define MB (1UL << 20) | ||
15 | #define PAGE_SIZE sysconf(_SC_PAGESIZE) | ||
16 | |||
17 | #define GUP_FAST_BENCHMARK _IOWR('g', 1, struct gup_benchmark) | ||
18 | |||
19 | struct gup_benchmark { | ||
20 | __u64 delta_usec; | ||
21 | __u64 addr; | ||
22 | __u64 size; | ||
23 | __u32 nr_pages_per_call; | ||
24 | __u32 flags; | ||
25 | }; | ||
26 | |||
27 | int main(int argc, char **argv) | ||
28 | { | ||
29 | struct gup_benchmark gup; | ||
30 | unsigned long size = 128 * MB; | ||
31 | int i, fd, opt, nr_pages = 1, thp = -1, repeats = 1, write = 0; | ||
32 | char *p; | ||
33 | |||
34 | while ((opt = getopt(argc, argv, "m:r:n:tT")) != -1) { | ||
35 | switch (opt) { | ||
36 | case 'm': | ||
37 | size = atoi(optarg) * MB; | ||
38 | break; | ||
39 | case 'r': | ||
40 | repeats = atoi(optarg); | ||
41 | break; | ||
42 | case 'n': | ||
43 | nr_pages = atoi(optarg); | ||
44 | break; | ||
45 | case 't': | ||
46 | thp = 1; | ||
47 | break; | ||
48 | case 'T': | ||
49 | thp = 0; | ||
50 | break; | ||
51 | case 'w': | ||
52 | write = 1; | ||
53 | default: | ||
54 | return -1; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | gup.nr_pages_per_call = nr_pages; | ||
59 | gup.flags = write; | ||
60 | |||
61 | fd = open("/sys/kernel/debug/gup_benchmark", O_RDWR); | ||
62 | if (fd == -1) | ||
63 | perror("open"), exit(1); | ||
64 | |||
65 | p = mmap(NULL, size, PROT_READ | PROT_WRITE, | ||
66 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
67 | if (p == MAP_FAILED) | ||
68 | perror("mmap"), exit(1); | ||
69 | gup.addr = (unsigned long)p; | ||
70 | |||
71 | if (thp == 1) | ||
72 | madvise(p, size, MADV_HUGEPAGE); | ||
73 | else if (thp == 0) | ||
74 | madvise(p, size, MADV_NOHUGEPAGE); | ||
75 | |||
76 | for (; (unsigned long)p < gup.addr + size; p += PAGE_SIZE) | ||
77 | p[0] = 0; | ||
78 | |||
79 | for (i = 0; i < repeats; i++) { | ||
80 | gup.size = size; | ||
81 | if (ioctl(fd, GUP_FAST_BENCHMARK, &gup)) | ||
82 | perror("ioctl"), exit(1); | ||
83 | |||
84 | printf("Time: %lld us", gup.delta_usec); | ||
85 | if (gup.size != size) | ||
86 | printf(", truncated (size: %lld)", gup.size); | ||
87 | printf("\n"); | ||
88 | } | ||
89 | |||
90 | return 0; | ||
91 | } | ||