Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mm-nonmm-stable-2022-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull non-MM updates from Andrew Morton:

- hfs and hfsplus kmap API modernization (Fabio Francesco)

- make crash-kexec work properly when invoked from an NMI-time panic
(Valentin Schneider)

- ntfs bugfixes (Hawkins Jiawei)

- improve IPC msg scalability by replacing atomic_t's with percpu
counters (Jiebin Sun)

- nilfs2 cleanups (Minghao Chi)

- lots of other single patches all over the tree!

* tag 'mm-nonmm-stable-2022-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (71 commits)
include/linux/entry-common.h: remove has_signal comment of arch_do_signal_or_restart() prototype
proc: test how it holds up with mapping'less process
mailmap: update Frank Rowand email address
ia64: mca: use strscpy() is more robust and safer
init/Kconfig: fix unmet direct dependencies
ia64: update config files
nilfs2: replace WARN_ONs by nilfs_error for checkpoint acquisition failure
fork: remove duplicate included header files
init/main.c: remove unnecessary (void*) conversions
proc: mark more files as permanent
nilfs2: remove the unneeded result variable
nilfs2: delete unnecessary checks before brelse()
checkpatch: warn for non-standard fixes tag style
usr/gen_init_cpio.c: remove unnecessary -1 values from int file
ipc/msg: mitigate the lock contention with percpu counter
percpu: add percpu_counter_add_local and percpu_counter_sub_local
fs/ocfs2: fix repeated words in comments
relay: use kvcalloc to alloc page array in relay_alloc_page_array
proc: make config PROC_CHILDREN depend on PROC_FS
fs: uninline inode_maybe_inc_iversion()
...

+1148 -621
+1
.mailmap
··· 137 137 Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> 138 138 Franck Bui-Huu <vagabon.xyz@gmail.com> 139 139 Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> 140 + Frank Rowand <frowand.list@gmail.com> <frank.rowand@sony.com> 140 141 Frank Rowand <frowand.list@gmail.com> <frank.rowand@sonymobile.com> 141 142 Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com> 142 143 Frank Zago <fzago@systemfabricworks.com>
+5
Documentation/admin-guide/sysctl/kernel.rst
··· 65 65 4 s3_beep 66 66 = ======= 67 67 68 + arch 69 + ==== 70 + 71 + The machine hardware name, the same output as ``uname -m`` 72 + (e.g. ``x86_64`` or ``aarch64``). 68 73 69 74 auto_msgmni 70 75 ===========
+7
Documentation/dev-tools/checkpatch.rst
··· 612 612 613 613 See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes 614 614 615 + **BAD_FIXES_TAG** 616 + The Fixes: tag is malformed or does not follow the community conventions. 617 + This can occur if the tag have been split into multiple lines (e.g., when 618 + pasted in an email program with word wrapping enabled). 619 + 620 + See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes 621 + 615 622 616 623 Comparison style 617 624 ----------------
+1 -1
arch/alpha/configs/defconfig
··· 65 65 CONFIG_NLS_CODEPAGE_437=y 66 66 CONFIG_MAGIC_SYSRQ=y 67 67 CONFIG_DEBUG_KERNEL=y 68 - CONFIG_DEBUG_INFO=y 68 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 69 69 CONFIG_ALPHA_LEGACY_START_ADDRESS=y 70 70 CONFIG_MATHEMU=y 71 71 CONFIG_CRYPTO_HMAC=y
-2
arch/alpha/include/asm/processor.h
··· 36 36 37 37 /* Free all resources held by a thread. */ 38 38 struct task_struct; 39 - extern void release_thread(struct task_struct *); 40 - 41 39 unsigned long __get_wchan(struct task_struct *p); 42 40 43 41 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
-5
arch/alpha/kernel/process.c
··· 225 225 current_thread_info()->pcb.unique = 0; 226 226 } 227 227 228 - void 229 - release_thread(struct task_struct *dead_task) 230 - { 231 - } 232 - 233 228 /* 234 229 * Copy architecture-specific thread state 235 230 */
+2 -2
arch/alpha/kernel/setup.c
··· 491 491 boot flags depending on the boot mode, we need some shorthand. 492 492 This should do for installation. */ 493 493 if (strcmp(COMMAND_LINE, "INSTALL") == 0) { 494 - strlcpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof command_line); 494 + strscpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof(command_line)); 495 495 } else { 496 - strlcpy(command_line, COMMAND_LINE, sizeof command_line); 496 + strscpy(command_line, COMMAND_LINE, sizeof(command_line)); 497 497 } 498 498 strcpy(boot_command_line, command_line); 499 499 *cmdline_p = command_line;
+1 -1
arch/arc/configs/tb10x_defconfig
··· 90 90 CONFIG_CONFIGFS_FS=y 91 91 # CONFIG_MISC_FILESYSTEMS is not set 92 92 # CONFIG_NETWORK_FILESYSTEMS is not set 93 - CONFIG_DEBUG_INFO=y 93 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 94 94 CONFIG_STRIP_ASM_SYMS=y 95 95 CONFIG_DEBUG_FS=y 96 96 CONFIG_HEADERS_INSTALL=y
-3
arch/arc/include/asm/processor.h
··· 43 43 #define task_pt_regs(p) \ 44 44 ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1) 45 45 46 - /* Free all resources held by a thread */ 47 - #define release_thread(thread) do { } while (0) 48 - 49 46 /* 50 47 * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise 51 48 * get optimised away by gcc
-3
arch/arm/include/asm/processor.h
··· 81 81 /* Forward declaration, a strange C thing */ 82 82 struct task_struct; 83 83 84 - /* Free all resources held by a thread. */ 85 - extern void release_thread(struct task_struct *); 86 - 87 84 unsigned long __get_wchan(struct task_struct *p); 88 85 89 86 #define task_pt_regs(p) \
-4
arch/arm/kernel/process.c
··· 232 232 thread_notify(THREAD_NOTIFY_FLUSH, thread); 233 233 } 234 234 235 - void release_thread(struct task_struct *dead_task) 236 - { 237 - } 238 - 239 235 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 240 236 241 237 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
-3
arch/arm64/include/asm/processor.h
··· 323 323 /* Forward declaration, a strange C thing */ 324 324 struct task_struct; 325 325 326 - /* Free all resources held by a thread. */ 327 - extern void release_thread(struct task_struct *); 328 - 329 326 unsigned long __get_wchan(struct task_struct *p); 330 327 331 328 void update_sctlr_el1(u64 sctlr);
-4
arch/arm64/kernel/process.c
··· 279 279 flush_tagged_addr_state(); 280 280 } 281 281 282 - void release_thread(struct task_struct *dead_task) 283 - { 284 - } 285 - 286 282 void arch_release_task_struct(struct task_struct *tsk) 287 283 { 288 284 fpsimd_release_task(tsk);
-5
arch/csky/include/asm/processor.h
··· 69 69 /* Forward declaration, a strange C thing */ 70 70 struct task_struct; 71 71 72 - /* Free all resources held by a thread. */ 73 - static inline void release_thread(struct task_struct *dead_task) 74 - { 75 - } 76 - 77 72 /* Prepare to copy thread state - unlazy all lazy status */ 78 73 #define prepare_to_copy(tsk) do { } while (0) 79 74
-4
arch/hexagon/include/asm/processor.h
··· 60 60 #define KSTK_EIP(tsk) (pt_elr(task_pt_regs(tsk))) 61 61 #define KSTK_ESP(tsk) (pt_psp(task_pt_regs(tsk))) 62 62 63 - /* Free all resources held by a thread; defined in process.c */ 64 - extern void release_thread(struct task_struct *dead_task); 65 - 66 - /* Get wait channel for task P. */ 67 63 extern unsigned long __get_wchan(struct task_struct *p); 68 64 69 65 /* The following stuff is pretty HEXAGON specific. */
-7
arch/hexagon/kernel/process.c
··· 113 113 } 114 114 115 115 /* 116 - * Release any architecture-specific resources locked by thread 117 - */ 118 - void release_thread(struct task_struct *dead_task) 119 - { 120 - } 121 - 122 - /* 123 116 * Some archs flush debug and FPU info here 124 117 */ 125 118 void flush_thread(void)
-2
arch/ia64/configs/bigsur_defconfig
··· 20 20 CONFIG_INET=y 21 21 # CONFIG_IPV6 is not set 22 22 CONFIG_BLK_DEV_LOOP=m 23 - CONFIG_BLK_DEV_CRYPTOLOOP=m 24 23 CONFIG_BLK_DEV_NBD=m 25 24 CONFIG_BLK_DEV_RAM=m 26 25 CONFIG_ATA=m ··· 90 91 CONFIG_NFSD=m 91 92 CONFIG_NFSD_V4=y 92 93 CONFIG_CIFS=m 93 - CONFIG_CIFS_STATS=y 94 94 CONFIG_CIFS_XATTR=y 95 95 CONFIG_CIFS_POSIX=y 96 96 CONFIG_NLS_CODEPAGE_437=y
-2
arch/ia64/configs/generic_defconfig
··· 39 39 CONFIG_CONNECTOR=y 40 40 # CONFIG_PNP_DEBUG_MESSAGES is not set 41 41 CONFIG_BLK_DEV_LOOP=m 42 - CONFIG_BLK_DEV_CRYPTOLOOP=m 43 42 CONFIG_BLK_DEV_NBD=m 44 43 CONFIG_BLK_DEV_RAM=y 45 44 CONFIG_SGI_XP=m ··· 90 91 # CONFIG_HW_RANDOM is not set 91 92 CONFIG_RTC_CLASS=y 92 93 CONFIG_RTC_DRV_EFI=y 93 - CONFIG_RAW_DRIVER=m 94 94 CONFIG_HPET=y 95 95 CONFIG_AGP=m 96 96 CONFIG_AGP_I460=m
-3
arch/ia64/configs/gensparse_defconfig
··· 31 31 CONFIG_SYN_COOKIES=y 32 32 # CONFIG_IPV6 is not set 33 33 CONFIG_BLK_DEV_LOOP=m 34 - CONFIG_BLK_DEV_CRYPTOLOOP=m 35 34 CONFIG_BLK_DEV_NBD=m 36 35 CONFIG_BLK_DEV_RAM=y 37 36 CONFIG_ATA=y 38 - CONFIG_BLK_DEV_IDECD=y 39 37 CONFIG_ATA_GENERIC=y 40 38 CONFIG_PATA_CMD64X=y 41 39 CONFIG_ATA_PIIX=y ··· 79 81 # CONFIG_HW_RANDOM is not set 80 82 CONFIG_RTC_CLASS=y 81 83 CONFIG_RTC_DRV_EFI=y 82 - CONFIG_RAW_DRIVER=m 83 84 CONFIG_HPET=y 84 85 CONFIG_AGP=m 85 86 CONFIG_AGP_I460=m
-2
arch/ia64/configs/tiger_defconfig
··· 36 36 CONFIG_SYN_COOKIES=y 37 37 # CONFIG_IPV6 is not set 38 38 CONFIG_BLK_DEV_LOOP=m 39 - CONFIG_BLK_DEV_CRYPTOLOOP=m 40 39 CONFIG_BLK_DEV_NBD=m 41 40 CONFIG_BLK_DEV_RAM=y 42 41 CONFIG_ATA=y ··· 84 85 # CONFIG_HW_RANDOM is not set 85 86 CONFIG_RTC_CLASS=y 86 87 CONFIG_RTC_DRV_EFI=y 87 - CONFIG_RAW_DRIVER=m 88 88 CONFIG_HPET=y 89 89 CONFIG_AGP=m 90 90 CONFIG_AGP_I460=m
-1
arch/ia64/configs/zx1_defconfig
··· 30 30 CONFIG_SCSI=y 31 31 CONFIG_BLK_DEV_SD=y 32 32 CONFIG_CHR_DEV_ST=y 33 - CONFIG_CHR_DEV_OSST=y 34 33 CONFIG_BLK_DEV_SR=y 35 34 CONFIG_CHR_DEV_SG=y 36 35 CONFIG_SCSI_CONSTANTS=y
-7
arch/ia64/include/asm/processor.h
··· 318 318 struct mm_struct; 319 319 struct task_struct; 320 320 321 - /* 322 - * Free all resources held by a thread. This is called after the 323 - * parent of DEAD_TASK has collected the exit status of the task via 324 - * wait(). 325 - */ 326 - #define release_thread(dead_task) 327 - 328 321 /* Get wait channel for task P. */ 329 322 extern unsigned long __get_wchan (struct task_struct *p); 330 323
+1 -1
arch/ia64/kernel/mca.c
··· 1793 1793 p->parent = p->real_parent = p->group_leader = p; 1794 1794 INIT_LIST_HEAD(&p->children); 1795 1795 INIT_LIST_HEAD(&p->sibling); 1796 - strncpy(p->comm, type, sizeof(p->comm)-1); 1796 + strscpy(p->comm, type, sizeof(p->comm)-1); 1797 1797 } 1798 1798 1799 1799 /* Caller prevents this from being called after init */
+1 -1
arch/ia64/kernel/setup.c
··· 552 552 ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); 553 553 554 554 *cmdline_p = __va(ia64_boot_param->command_line); 555 - strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); 555 + strscpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); 556 556 557 557 efi_init(); 558 558 io_port_init();
+26
arch/ia64/kernel/sys_ia64.c
··· 166 166 force_successful_syscall_return(); 167 167 return addr; 168 168 } 169 + 170 + asmlinkage long 171 + ia64_clock_getres(const clockid_t which_clock, struct __kernel_timespec __user *tp) 172 + { 173 + /* 174 + * ia64's clock_gettime() syscall is implemented as a vdso call 175 + * fsys_clock_gettime(). Currently it handles only 176 + * CLOCK_REALTIME and CLOCK_MONOTONIC. Both are based on 177 + * 'ar.itc' counter which gets incremented at a constant 178 + * frequency. It's usually 400MHz, ~2.5x times slower than CPU 179 + * clock frequency. Which is almost a 1ns hrtimer, but not quite. 180 + * 181 + * Let's special-case these timers to report correct precision 182 + * based on ITC frequency and not HZ frequency for supported 183 + * clocks. 184 + */ 185 + switch (which_clock) { 186 + case CLOCK_REALTIME: 187 + case CLOCK_MONOTONIC: 188 + s64 tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, local_cpu_data->itc_freq); 189 + struct timespec64 rtn_tp = ns_to_timespec64(tick_ns); 190 + return put_timespec64(&rtn_tp, tp); 191 + } 192 + 193 + return sys_clock_getres(which_clock, tp); 194 + }
+1 -1
arch/ia64/kernel/syscalls/syscall.tbl
··· 240 240 228 common timer_delete sys_timer_delete 241 241 229 common clock_settime sys_clock_settime 242 242 230 common clock_gettime sys_clock_gettime 243 - 231 common clock_getres sys_clock_getres 243 + 231 common clock_getres ia64_clock_getres 244 244 232 common clock_nanosleep sys_clock_nanosleep 245 245 233 common fstatfs64 sys_fstatfs64 246 246 234 common statfs64 sys_statfs64
-3
arch/loongarch/include/asm/processor.h
··· 176 176 177 177 struct task_struct; 178 178 179 - /* Free all resources held by a thread. */ 180 - #define release_thread(thread) do { } while (0) 181 - 182 179 enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_HALT, IDLE_NOMWAIT, IDLE_POLL}; 183 180 184 181 extern unsigned long boot_option_idle_override;
-5
arch/m68k/include/asm/processor.h
··· 145 145 /* Forward declaration, a strange C thing */ 146 146 struct task_struct; 147 147 148 - /* Free all resources held by a thread. */ 149 - static inline void release_thread(struct task_struct *dead_task) 150 - { 151 - } 152 - 153 148 unsigned long __get_wchan(struct task_struct *p); 154 149 void show_registers(struct pt_regs *regs); 155 150
+1 -1
arch/microblaze/configs/mmu_defconfig
··· 83 83 CONFIG_CIFS_STATS2=y 84 84 CONFIG_ENCRYPTED_KEYS=y 85 85 CONFIG_DMA_CMA=y 86 - CONFIG_DEBUG_INFO=y 86 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 87 87 CONFIG_KGDB=y 88 88 CONFIG_KGDB_TESTS=y 89 89 CONFIG_KGDB_KDB=y
-5
arch/microblaze/include/asm/processor.h
··· 63 63 .pgdir = swapper_pg_dir, \ 64 64 } 65 65 66 - /* Free all resources held by a thread. */ 67 - static inline void release_thread(struct task_struct *dead_task) 68 - { 69 - } 70 - 71 66 unsigned long __get_wchan(struct task_struct *p); 72 67 73 68 /* The size allocated for kernel stacks. This _must_ be a power of two! */
+1 -1
arch/mips/configs/bcm47xx_defconfig
··· 72 72 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y 73 73 CONFIG_CRC32_SARWATE=y 74 74 CONFIG_PRINTK_TIME=y 75 - CONFIG_DEBUG_INFO=y 75 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 76 76 CONFIG_DEBUG_INFO_REDUCED=y 77 77 CONFIG_STRIP_ASM_SYMS=y 78 78 CONFIG_DEBUG_FS=y
+1 -1
arch/mips/configs/cavium_octeon_defconfig
··· 161 161 CONFIG_CRYPTO_SHA256_OCTEON=m 162 162 CONFIG_CRYPTO_SHA512_OCTEON=m 163 163 CONFIG_CRYPTO_DES=y 164 - CONFIG_DEBUG_INFO=y 164 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 165 165 CONFIG_DEBUG_FS=y 166 166 CONFIG_MAGIC_SYSRQ=y 167 167 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/mips/configs/ci20_defconfig
··· 199 199 CONFIG_DMA_CMA=y 200 200 CONFIG_CMA_SIZE_MBYTES=32 201 201 CONFIG_PRINTK_TIME=y 202 - CONFIG_DEBUG_INFO=y 202 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 203 203 CONFIG_STRIP_ASM_SYMS=y 204 204 CONFIG_MAGIC_SYSRQ=y 205 205 CONFIG_DEBUG_FS=y
+1 -1
arch/mips/configs/cu1000-neo_defconfig
··· 113 113 CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 114 114 CONFIG_CONSOLE_LOGLEVEL_QUIET=15 115 115 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 116 - CONFIG_DEBUG_INFO=y 116 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 117 117 CONFIG_STRIP_ASM_SYMS=y 118 118 CONFIG_MAGIC_SYSRQ=y 119 119 CONFIG_DEBUG_FS=y
+1 -1
arch/mips/configs/cu1830-neo_defconfig
··· 116 116 CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 117 117 CONFIG_CONSOLE_LOGLEVEL_QUIET=15 118 118 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 119 - CONFIG_DEBUG_INFO=y 119 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 120 120 CONFIG_STRIP_ASM_SYMS=y 121 121 CONFIG_MAGIC_SYSRQ=y 122 122 CONFIG_DEBUG_FS=y
+1 -1
arch/mips/configs/generic_defconfig
··· 82 82 # CONFIG_XZ_DEC_ARMTHUMB is not set 83 83 # CONFIG_XZ_DEC_SPARC is not set 84 84 CONFIG_PRINTK_TIME=y 85 - CONFIG_DEBUG_INFO=y 85 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 86 86 CONFIG_DEBUG_INFO_REDUCED=y 87 87 CONFIG_DEBUG_FS=y 88 88 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/mips/configs/omega2p_defconfig
··· 113 113 CONFIG_CRC16=y 114 114 CONFIG_XZ_DEC=y 115 115 CONFIG_PRINTK_TIME=y 116 - CONFIG_DEBUG_INFO=y 116 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 117 117 CONFIG_STRIP_ASM_SYMS=y 118 118 CONFIG_DEBUG_FS=y 119 119 CONFIG_MAGIC_SYSRQ=y
+1 -1
arch/mips/configs/qi_lb60_defconfig
··· 166 166 CONFIG_FONTS=y 167 167 CONFIG_FONT_SUN8x16=y 168 168 CONFIG_PRINTK_TIME=y 169 - CONFIG_DEBUG_INFO=y 169 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 170 170 CONFIG_STRIP_ASM_SYMS=y 171 171 CONFIG_READABLE_ASM=y 172 172 CONFIG_KGDB=y
+1 -1
arch/mips/configs/vocore2_defconfig
··· 113 113 CONFIG_CRC16=y 114 114 CONFIG_XZ_DEC=y 115 115 CONFIG_PRINTK_TIME=y 116 - CONFIG_DEBUG_INFO=y 116 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 117 117 CONFIG_STRIP_ASM_SYMS=y 118 118 CONFIG_DEBUG_FS=y 119 119 CONFIG_MAGIC_SYSRQ=y
-3
arch/mips/include/asm/processor.h
··· 344 344 345 345 struct task_struct; 346 346 347 - /* Free all resources held by a thread. */ 348 - #define release_thread(thread) do { } while(0) 349 - 350 347 /* 351 348 * Do necessary setup to start up a newly executed thread. 352 349 */
+1 -1
arch/nios2/configs/10m50_defconfig
··· 74 74 CONFIG_NFS_V3_ACL=y 75 75 CONFIG_ROOT_NFS=y 76 76 CONFIG_SUNRPC_DEBUG=y 77 - CONFIG_DEBUG_INFO=y 77 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+1 -1
arch/nios2/configs/3c120_defconfig
··· 71 71 CONFIG_NFS_V3_ACL=y 72 72 CONFIG_ROOT_NFS=y 73 73 CONFIG_SUNRPC_DEBUG=y 74 - CONFIG_DEBUG_INFO=y 74 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
-5
arch/nios2/include/asm/processor.h
··· 64 64 65 65 struct task_struct; 66 66 67 - /* Free all resources held by a thread. */ 68 - static inline void release_thread(struct task_struct *dead_task) 69 - { 70 - } 71 - 72 67 extern unsigned long __get_wchan(struct task_struct *p); 73 68 74 69 #define task_pt_regs(p) \
-1
arch/openrisc/include/asm/processor.h
··· 72 72 73 73 74 74 void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); 75 - void release_thread(struct task_struct *); 76 75 unsigned long __get_wchan(struct task_struct *p); 77 76 78 77 #define cpu_relax() barrier()
-4
arch/openrisc/kernel/process.c
··· 125 125 show_registers(regs); 126 126 } 127 127 128 - void release_thread(struct task_struct *dead_task) 129 - { 130 - } 131 - 132 128 /* 133 129 * Copy the thread-specific (arch specific) info from the current 134 130 * process to the new one p
-3
arch/parisc/include/asm/processor.h
··· 266 266 267 267 struct mm_struct; 268 268 269 - /* Free all resources held by a thread. */ 270 - extern void release_thread(struct task_struct *); 271 - 272 269 extern unsigned long __get_wchan(struct task_struct *p); 273 270 274 271 #define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
-4
arch/parisc/kernel/process.c
··· 146 146 */ 147 147 } 148 148 149 - void release_thread(struct task_struct *dead_task) 150 - { 151 - } 152 - 153 149 /* 154 150 * Idle thread support 155 151 *
-1
arch/powerpc/include/asm/processor.h
··· 75 75 76 76 struct task_struct; 77 77 void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); 78 - void release_thread(struct task_struct *); 79 78 80 79 #define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET] 81 80 #define TS_CKFPR(i) ckfp_state.fpr[i][TS_FPROFFSET]
-5
arch/powerpc/kernel/process.c
··· 1655 1655 1656 1656 #endif /* CONFIG_PPC64 */ 1657 1657 1658 - void 1659 - release_thread(struct task_struct *t) 1660 - { 1661 - } 1662 - 1663 1658 /* 1664 1659 * this gets called so that we can store coprocessor state into memory and 1665 1660 * copy the current task into the new thread.
-5
arch/riscv/include/asm/processor.h
··· 65 65 extern void start_thread(struct pt_regs *regs, 66 66 unsigned long pc, unsigned long sp); 67 67 68 - /* Free all resources held by a thread. */ 69 - static inline void release_thread(struct task_struct *dead_task) 70 - { 71 - } 72 - 73 68 extern unsigned long __get_wchan(struct task_struct *p); 74 69 75 70
-3
arch/s390/include/asm/processor.h
··· 186 186 void show_registers(struct pt_regs *regs); 187 187 void show_cacheinfo(struct seq_file *m); 188 188 189 - /* Free all resources held by a thread. */ 190 - static inline void release_thread(struct task_struct *tsk) { } 191 - 192 189 /* Free guarded storage control block */ 193 190 void guarded_storage_release(struct task_struct *tsk); 194 191 void gs_load_bc_cb(struct pt_regs *regs);
+1 -1
arch/sh/configs/apsh4a3a_defconfig
··· 85 85 CONFIG_DEBUG_KERNEL=y 86 86 # CONFIG_DEBUG_PREEMPT is not set 87 87 # CONFIG_DEBUG_BUGVERBOSE is not set 88 - CONFIG_DEBUG_INFO=y 88 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 89 89 # CONFIG_FTRACE is not set 90 90 # CONFIG_CRYPTO_ANSI_CPRNG is not set 91 91 # CONFIG_CRYPTO_HW is not set
+1 -1
arch/sh/configs/apsh4ad0a_defconfig
··· 116 116 CONFIG_DEBUG_KERNEL=y 117 117 CONFIG_DEBUG_SHIRQ=y 118 118 CONFIG_DETECT_HUNG_TASK=y 119 - CONFIG_DEBUG_INFO=y 119 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 120 120 CONFIG_DEBUG_VM=y 121 121 CONFIG_DWARF_UNWINDER=y 122 122 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+1 -1
arch/sh/configs/edosk7760_defconfig
··· 107 107 CONFIG_DETECT_HUNG_TASK=y 108 108 # CONFIG_SCHED_DEBUG is not set 109 109 CONFIG_TIMER_STATS=y 110 - CONFIG_DEBUG_INFO=y 110 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 111 111 CONFIG_CRYPTO=y 112 112 CONFIG_CRYPTO_MD5=y 113 113 CONFIG_CRYPTO_DES=y
+1 -1
arch/sh/configs/magicpanelr2_defconfig
··· 84 84 CONFIG_DEBUG_KERNEL=y 85 85 # CONFIG_SCHED_DEBUG is not set 86 86 CONFIG_DEBUG_KOBJECT=y 87 - CONFIG_DEBUG_INFO=y 87 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 88 88 CONFIG_FRAME_POINTER=y 89 89 CONFIG_CRC_CCITT=m 90 90 CONFIG_CRC16=m
+1 -1
arch/sh/configs/polaris_defconfig
··· 79 79 CONFIG_DEBUG_RT_MUTEXES=y 80 80 CONFIG_DEBUG_LOCK_ALLOC=y 81 81 CONFIG_DEBUG_SPINLOCK_SLEEP=y 82 - CONFIG_DEBUG_INFO=y 82 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 83 83 CONFIG_DEBUG_SG=y
+1 -1
arch/sh/configs/r7780mp_defconfig
··· 101 101 CONFIG_DEBUG_KERNEL=y 102 102 CONFIG_DETECT_HUNG_TASK=y 103 103 # CONFIG_DEBUG_PREEMPT is not set 104 - CONFIG_DEBUG_INFO=y 104 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 105 105 CONFIG_CRYPTO_ECB=m 106 106 CONFIG_CRYPTO_PCBC=m 107 107 CONFIG_CRYPTO_HMAC=y
+1 -1
arch/sh/configs/r7785rp_defconfig
··· 96 96 # CONFIG_DEBUG_PREEMPT is not set 97 97 CONFIG_DEBUG_LOCK_ALLOC=y 98 98 CONFIG_DEBUG_LOCKING_API_SELFTESTS=y 99 - CONFIG_DEBUG_INFO=y 99 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 100 100 CONFIG_SH_STANDARD_BIOS=y 101 101 CONFIG_DEBUG_STACK_USAGE=y 102 102 CONFIG_4KSTACKS=y
+1 -1
arch/sh/configs/rsk7203_defconfig
··· 112 112 CONFIG_DEBUG_OBJECTS=y 113 113 CONFIG_DEBUG_MUTEXES=y 114 114 CONFIG_DEBUG_SPINLOCK_SLEEP=y 115 - CONFIG_DEBUG_INFO=y 115 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 116 116 CONFIG_DEBUG_VM=y 117 117 CONFIG_DEBUG_LIST=y 118 118 CONFIG_DEBUG_SG=y
+1 -1
arch/sh/configs/sdk7780_defconfig
··· 131 131 CONFIG_DETECT_HUNG_TASK=y 132 132 # CONFIG_SCHED_DEBUG is not set 133 133 CONFIG_TIMER_STATS=y 134 - CONFIG_DEBUG_INFO=y 134 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 135 135 CONFIG_SH_STANDARD_BIOS=y 136 136 CONFIG_CRYPTO_MD5=y 137 137 CONFIG_CRYPTO_DES=y
+1 -1
arch/sh/configs/se7712_defconfig
··· 93 93 CONFIG_NFS_FS=y 94 94 CONFIG_ROOT_NFS=y 95 95 CONFIG_DEBUG_KERNEL=y 96 - CONFIG_DEBUG_INFO=y 96 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 97 97 CONFIG_FRAME_POINTER=y 98 98 CONFIG_CRYPTO_ECB=m 99 99 CONFIG_CRYPTO_PCBC=m
+1 -1
arch/sh/configs/se7721_defconfig
··· 121 121 CONFIG_NLS_CODEPAGE_932=y 122 122 CONFIG_NLS_ISO8859_1=y 123 123 CONFIG_DEBUG_KERNEL=y 124 - CONFIG_DEBUG_INFO=y 124 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 125 125 CONFIG_FRAME_POINTER=y 126 126 # CONFIG_CRYPTO_ANSI_CPRNG is not set 127 127 CONFIG_CRC_CCITT=y
+1 -1
arch/sh/configs/sh2007_defconfig
··· 159 159 CONFIG_DEBUG_KERNEL=y 160 160 # CONFIG_DETECT_SOFTLOCKUP is not set 161 161 # CONFIG_SCHED_DEBUG is not set 162 - CONFIG_DEBUG_INFO=y 162 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 163 163 CONFIG_FRAME_POINTER=y 164 164 CONFIG_SH_STANDARD_BIOS=y 165 165 CONFIG_CRYPTO_NULL=y
+1 -1
arch/sh/configs/sh7757lcr_defconfig
··· 80 80 CONFIG_DEBUG_KERNEL=y 81 81 # CONFIG_SCHED_DEBUG is not set 82 82 # CONFIG_DEBUG_BUGVERBOSE is not set 83 - CONFIG_DEBUG_INFO=y 83 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 84 84 # CONFIG_FTRACE is not set 85 85 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+1 -1
arch/sh/configs/sh7785lcr_32bit_defconfig
··· 141 141 CONFIG_DEBUG_SPINLOCK=y 142 142 CONFIG_DEBUG_MUTEXES=y 143 143 CONFIG_DEBUG_SPINLOCK_SLEEP=y 144 - CONFIG_DEBUG_INFO=y 144 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 145 145 CONFIG_LATENCYTOP=y 146 146 # CONFIG_FTRACE is not set 147 147 CONFIG_CRYPTO_HMAC=y
+1 -1
arch/sh/configs/urquell_defconfig
··· 138 138 CONFIG_DEBUG_FS=y 139 139 CONFIG_DEBUG_KERNEL=y 140 140 CONFIG_DETECT_HUNG_TASK=y 141 - CONFIG_DEBUG_INFO=y 141 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 142 142 CONFIG_FRAME_POINTER=y 143 143 # CONFIG_FTRACE is not set 144 144 # CONFIG_DUMP_CODE is not set
-3
arch/sh/include/asm/processor_32.h
··· 127 127 128 128 extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp); 129 129 130 - /* Free all resources held by a thread. */ 131 - extern void release_thread(struct task_struct *); 132 - 133 130 /* 134 131 * FPU lazy state save handling. 135 132 */
-5
arch/sh/kernel/process_32.c
··· 84 84 #endif 85 85 } 86 86 87 - void release_thread(struct task_struct *dead_task) 88 - { 89 - /* do nothing */ 90 - } 91 - 92 87 asmlinkage void ret_from_fork(void); 93 88 asmlinkage void ret_from_kernel_thread(void); 94 89
-3
arch/sparc/include/asm/processor_32.h
··· 80 80 : "memory"); 81 81 } 82 82 83 - /* Free all resources held by a thread. */ 84 - #define release_thread(tsk) do { } while(0) 85 - 86 83 unsigned long __get_wchan(struct task_struct *); 87 84 88 85 #define task_pt_regs(tsk) ((tsk)->thread.kregs)
-3
arch/sparc/include/asm/processor_64.h
··· 176 176 regs->tstate &= ~TSTATE_PEF; \ 177 177 } while (0) 178 178 179 - /* Free all resources held by a thread. */ 180 - #define release_thread(tsk) do { } while (0) 181 - 182 179 unsigned long __get_wchan(struct task_struct *task); 183 180 184 181 #define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
+1 -1
arch/um/configs/i386_defconfig
··· 69 69 CONFIG_PROC_KCORE=y 70 70 CONFIG_TMPFS=y 71 71 CONFIG_NLS=y 72 - CONFIG_DEBUG_INFO=y 72 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 73 73 CONFIG_DEBUG_KERNEL=y
+1 -1
arch/um/configs/x86_64_defconfig
··· 67 67 CONFIG_PROC_KCORE=y 68 68 CONFIG_TMPFS=y 69 69 CONFIG_NLS=y 70 - CONFIG_DEBUG_INFO=y 70 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 71 71 CONFIG_FRAME_WARN=1024 72 72 CONFIG_DEBUG_KERNEL=y
-4
arch/um/include/asm/processor-generic.h
··· 55 55 .request = { 0 } \ 56 56 } 57 57 58 - static inline void release_thread(struct task_struct *task) 59 - { 60 - } 61 - 62 58 /* 63 59 * User space process size: 3GB (default). 64 60 */
-3
arch/x86/include/asm/processor.h
··· 587 587 588 588 #endif /* CONFIG_PARAVIRT_XXL */ 589 589 590 - /* Free all resources held by a thread. */ 591 - extern void release_thread(struct task_struct *); 592 - 593 590 unsigned long __get_wchan(struct task_struct *p); 594 591 595 592 /*
+1 -1
arch/xtensa/configs/audio_kc705_defconfig
··· 120 120 CONFIG_NLS_ISO8859_1=y 121 121 CONFIG_PRINTK_TIME=y 122 122 CONFIG_DYNAMIC_DEBUG=y 123 - CONFIG_DEBUG_INFO=y 123 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 124 124 CONFIG_MAGIC_SYSRQ=y 125 125 CONFIG_LOCKUP_DETECTOR=y 126 126 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/xtensa/configs/cadence_csp_defconfig
··· 100 100 CONFIG_NLS_ISO8859_1=y 101 101 CONFIG_PRINTK_TIME=y 102 102 CONFIG_DYNAMIC_DEBUG=y 103 - CONFIG_DEBUG_INFO=y 103 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 104 104 CONFIG_MAGIC_SYSRQ=y 105 105 CONFIG_LOCKUP_DETECTOR=y 106 106 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/xtensa/configs/generic_kc705_defconfig
··· 107 107 CONFIG_NLS_ISO8859_1=y 108 108 CONFIG_PRINTK_TIME=y 109 109 CONFIG_DYNAMIC_DEBUG=y 110 - CONFIG_DEBUG_INFO=y 110 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 111 111 CONFIG_MAGIC_SYSRQ=y 112 112 CONFIG_LOCKUP_DETECTOR=y 113 113 # CONFIG_SCHED_DEBUG is not set
+1 -1
arch/xtensa/configs/nommu_kc705_defconfig
··· 105 105 CONFIG_NLS_ISO8859_1=y 106 106 CONFIG_PRINTK_TIME=y 107 107 CONFIG_DYNAMIC_DEBUG=y 108 - CONFIG_DEBUG_INFO=y 108 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 109 109 # CONFIG_FRAME_POINTER is not set 110 110 CONFIG_MAGIC_SYSRQ=y 111 111 CONFIG_DEBUG_VM=y
+1 -1
arch/xtensa/configs/smp_lx200_defconfig
··· 111 111 CONFIG_NLS_ISO8859_1=y 112 112 CONFIG_PRINTK_TIME=y 113 113 CONFIG_DYNAMIC_DEBUG=y 114 - CONFIG_DEBUG_INFO=y 114 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 115 115 CONFIG_MAGIC_SYSRQ=y 116 116 CONFIG_DEBUG_VM=y 117 117 CONFIG_LOCKUP_DETECTOR=y
+1 -1
arch/xtensa/configs/virt_defconfig
··· 97 97 CONFIG_FONTS=y 98 98 CONFIG_PRINTK_TIME=y 99 99 CONFIG_DYNAMIC_DEBUG=y 100 - CONFIG_DEBUG_INFO=y 100 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 101 101 CONFIG_MAGIC_SYSRQ=y 102 102 # CONFIG_SCHED_DEBUG is not set 103 103 CONFIG_SCHEDSTATS=y
+1 -1
arch/xtensa/configs/xip_kc705_defconfig
··· 102 102 CONFIG_CRYPTO_ANSI_CPRNG=y 103 103 CONFIG_PRINTK_TIME=y 104 104 CONFIG_DYNAMIC_DEBUG=y 105 - CONFIG_DEBUG_INFO=y 105 + CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 106 106 CONFIG_MAGIC_SYSRQ=y 107 107 CONFIG_DETECT_HUNG_TASK=y 108 108 # CONFIG_SCHED_DEBUG is not set
-3
arch/xtensa/include/asm/processor.h
··· 224 224 struct task_struct; 225 225 struct mm_struct; 226 226 227 - /* Free all resources held by a thread. */ 228 - #define release_thread(thread) do { } while(0) 229 - 230 227 extern unsigned long __get_wchan(struct task_struct *p); 231 228 232 229 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
+3 -6
fs/aio.c
··· 951 951 local_irq_save(flags); 952 952 kcpu = this_cpu_ptr(ctx->cpu); 953 953 if (!kcpu->reqs_available) { 954 - int old, avail = atomic_read(&ctx->reqs_available); 954 + int avail = atomic_read(&ctx->reqs_available); 955 955 956 956 do { 957 957 if (avail < ctx->req_batch) 958 958 goto out; 959 - 960 - old = avail; 961 - avail = atomic_cmpxchg(&ctx->reqs_available, 962 - avail, avail - ctx->req_batch); 963 - } while (avail != old); 959 + } while (!atomic_try_cmpxchg(&ctx->reqs_available, 960 + &avail, avail - ctx->req_batch)); 964 961 965 962 kcpu->reqs_available += ctx->req_batch; 966 963 }
+5 -9
fs/buffer.c
··· 1453 1453 1454 1454 static void discard_buffer(struct buffer_head * bh) 1455 1455 { 1456 - unsigned long b_state, b_state_old; 1456 + unsigned long b_state; 1457 1457 1458 1458 lock_buffer(bh); 1459 1459 clear_buffer_dirty(bh); 1460 1460 bh->b_bdev = NULL; 1461 - b_state = bh->b_state; 1462 - for (;;) { 1463 - b_state_old = cmpxchg(&bh->b_state, b_state, 1464 - (b_state & ~BUFFER_FLAGS_DISCARD)); 1465 - if (b_state_old == b_state) 1466 - break; 1467 - b_state = b_state_old; 1468 - } 1461 + b_state = READ_ONCE(bh->b_state); 1462 + do { 1463 + } while (!try_cmpxchg(&bh->b_state, &b_state, 1464 + b_state & ~BUFFER_FLAGS_DISCARD)); 1469 1465 unlock_buffer(bh); 1470 1466 } 1471 1467
+1 -1
fs/eventpoll.c
··· 1065 1065 * added to the list from another CPU: the winner observes 1066 1066 * new->next == new. 1067 1067 */ 1068 - if (cmpxchg(&new->next, new, head) != new) 1068 + if (!try_cmpxchg(&new->next, &new, head)) 1069 1069 return false; 1070 1070 1071 1071 /*
+12 -20
fs/hfs/bnode.c
··· 21 21 int pagenum; 22 22 int bytes_read; 23 23 int bytes_to_read; 24 - void *vaddr; 25 24 26 25 off += node->page_offset; 27 26 pagenum = off >> PAGE_SHIFT; ··· 32 33 page = node->page[pagenum]; 33 34 bytes_to_read = min_t(int, len - bytes_read, PAGE_SIZE - off); 34 35 35 - vaddr = kmap_atomic(page); 36 - memcpy(buf + bytes_read, vaddr + off, bytes_to_read); 37 - kunmap_atomic(vaddr); 36 + memcpy_from_page(buf + bytes_read, page, off, bytes_to_read); 38 37 39 38 pagenum++; 40 39 off = 0; /* page offset only applies to the first page */ ··· 77 80 off += node->page_offset; 78 81 page = node->page[0]; 79 82 80 - memcpy(kmap(page) + off, buf, len); 81 - kunmap(page); 83 + memcpy_to_page(page, off, buf, len); 82 84 set_page_dirty(page); 83 85 } 84 86 ··· 101 105 off += node->page_offset; 102 106 page = node->page[0]; 103 107 104 - memset(kmap(page) + off, 0, len); 105 - kunmap(page); 108 + memzero_page(page, off, len); 106 109 set_page_dirty(page); 107 110 } 108 111 ··· 118 123 src_page = src_node->page[0]; 119 124 dst_page = dst_node->page[0]; 120 125 121 - memcpy(kmap(dst_page) + dst, kmap(src_page) + src, len); 122 - kunmap(src_page); 123 - kunmap(dst_page); 126 + memcpy_page(dst_page, dst, src_page, src, len); 124 127 set_page_dirty(dst_page); 125 128 } 126 129 ··· 133 140 src += node->page_offset; 134 141 dst += node->page_offset; 135 142 page = node->page[0]; 136 - ptr = kmap(page); 143 + ptr = kmap_local_page(page); 137 144 memmove(ptr + dst, ptr + src, len); 138 - kunmap(page); 145 + kunmap_local(ptr); 139 146 set_page_dirty(page); 140 147 } 141 148 ··· 339 346 if (!test_bit(HFS_BNODE_NEW, &node->flags)) 340 347 return node; 341 348 342 - desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + node->page_offset); 349 + desc = (struct hfs_bnode_desc *)(kmap_local_page(node->page[0]) + 350 + node->page_offset); 343 351 node->prev = be32_to_cpu(desc->prev); 344 352 node->next = be32_to_cpu(desc->next); 345 353 node->num_recs = be16_to_cpu(desc->num_recs); 346 354 node->type = desc->type; 347 355 node->height = desc->height; 348 - kunmap(node->page[0]); 356 + kunmap_local(desc); 349 357 350 358 switch (node->type) { 351 359 case HFS_NODE_HEADER: ··· 430 436 } 431 437 432 438 pagep = node->page; 433 - memset(kmap(*pagep) + node->page_offset, 0, 434 - min((int)PAGE_SIZE, (int)tree->node_size)); 439 + memzero_page(*pagep, node->page_offset, 440 + min((int)PAGE_SIZE, (int)tree->node_size)); 435 441 set_page_dirty(*pagep); 436 - kunmap(*pagep); 437 442 for (i = 1; i < tree->pages_per_bnode; i++) { 438 - memset(kmap(*++pagep), 0, PAGE_SIZE); 443 + memzero_page(*++pagep, 0, PAGE_SIZE); 439 444 set_page_dirty(*pagep); 440 - kunmap(*pagep); 441 445 } 442 446 clear_bit(HFS_BNODE_NEW, &node->flags); 443 447 wake_up(&node->lock_wq);
+16 -13
fs/hfs/btree.c
··· 80 80 goto free_inode; 81 81 82 82 /* Load the header */ 83 - head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); 83 + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + 84 + sizeof(struct hfs_bnode_desc)); 84 85 tree->root = be32_to_cpu(head->root); 85 86 tree->leaf_count = be32_to_cpu(head->leaf_count); 86 87 tree->leaf_head = be32_to_cpu(head->leaf_head); ··· 120 119 tree->node_size_shift = ffs(size) - 1; 121 120 tree->pages_per_bnode = (tree->node_size + PAGE_SIZE - 1) >> PAGE_SHIFT; 122 121 123 - kunmap(page); 122 + kunmap_local(head); 124 123 put_page(page); 125 124 return tree; 126 125 127 126 fail_page: 127 + kunmap_local(head); 128 128 put_page(page); 129 129 free_inode: 130 130 tree->inode->i_mapping->a_ops = &hfs_aops; ··· 171 169 return; 172 170 /* Load the header */ 173 171 page = node->page[0]; 174 - head = (struct hfs_btree_header_rec *)(kmap(page) + sizeof(struct hfs_bnode_desc)); 172 + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + 173 + sizeof(struct hfs_bnode_desc)); 175 174 176 175 head->root = cpu_to_be32(tree->root); 177 176 head->leaf_count = cpu_to_be32(tree->leaf_count); ··· 183 180 head->attributes = cpu_to_be32(tree->attributes); 184 181 head->depth = cpu_to_be16(tree->depth); 185 182 186 - kunmap(page); 183 + kunmap_local(head); 187 184 set_page_dirty(page); 188 185 hfs_bnode_put(node); 189 186 } ··· 271 268 272 269 off += node->page_offset; 273 270 pagep = node->page + (off >> PAGE_SHIFT); 274 - data = kmap(*pagep); 271 + data = kmap_local_page(*pagep); 275 272 off &= ~PAGE_MASK; 276 273 idx = 0; 277 274 ··· 284 281 idx += i; 285 282 data[off] |= m; 286 283 set_page_dirty(*pagep); 287 - kunmap(*pagep); 284 + kunmap_local(data); 288 285 tree->free_nodes--; 289 286 mark_inode_dirty(tree->inode); 290 287 hfs_bnode_put(node); ··· 293 290 } 294 291 } 295 292 if (++off >= PAGE_SIZE) { 296 - kunmap(*pagep); 297 - data = kmap(*++pagep); 293 + kunmap_local(data); 294 + data = kmap_local_page(*++pagep); 298 295 off = 0; 299 296 } 300 297 idx += 8; 301 298 len--; 302 299 } 303 - kunmap(*pagep); 300 + kunmap_local(data); 304 301 nidx = node->next; 305 302 if (!nidx) { 306 303 printk(KERN_DEBUG "create new bmap node...\n"); ··· 316 313 off = off16; 317 314 off += node->page_offset; 318 315 pagep = node->page + (off >> PAGE_SHIFT); 319 - data = kmap(*pagep); 316 + data = kmap_local_page(*pagep); 320 317 off &= ~PAGE_MASK; 321 318 } 322 319 } ··· 363 360 } 364 361 off += node->page_offset + nidx / 8; 365 362 page = node->page[off >> PAGE_SHIFT]; 366 - data = kmap(page); 363 + data = kmap_local_page(page); 367 364 off &= ~PAGE_MASK; 368 365 m = 1 << (~nidx & 7); 369 366 byte = data[off]; 370 367 if (!(byte & m)) { 371 368 pr_crit("trying to free free bnode %u(%d)\n", 372 369 node->this, node->type); 373 - kunmap(page); 370 + kunmap_local(data); 374 371 hfs_bnode_put(node); 375 372 return; 376 373 } 377 374 data[off] = byte & ~m; 378 375 set_page_dirty(page); 379 - kunmap(page); 376 + kunmap_local(data); 380 377 hfs_bnode_put(node); 381 378 tree->free_nodes++; 382 379 mark_inode_dirty(tree->inode);
+10 -10
fs/hfsplus/bitmap.c
··· 39 39 start = size; 40 40 goto out; 41 41 } 42 - pptr = kmap(page); 42 + pptr = kmap_local_page(page); 43 43 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; 44 44 i = offset % 32; 45 45 offset &= ~(PAGE_CACHE_BITS - 1); ··· 74 74 } 75 75 curr++; 76 76 } 77 - kunmap(page); 77 + kunmap_local(pptr); 78 78 offset += PAGE_CACHE_BITS; 79 79 if (offset >= size) 80 80 break; ··· 84 84 start = size; 85 85 goto out; 86 86 } 87 - curr = pptr = kmap(page); 87 + curr = pptr = kmap_local_page(page); 88 88 if ((size ^ offset) / PAGE_CACHE_BITS) 89 89 end = pptr + PAGE_CACHE_BITS / 32; 90 90 else ··· 127 127 len -= 32; 128 128 } 129 129 set_page_dirty(page); 130 - kunmap(page); 130 + kunmap_local(pptr); 131 131 offset += PAGE_CACHE_BITS; 132 132 page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, 133 133 NULL); ··· 135 135 start = size; 136 136 goto out; 137 137 } 138 - pptr = kmap(page); 138 + pptr = kmap_local_page(page); 139 139 curr = pptr; 140 140 end = pptr + PAGE_CACHE_BITS / 32; 141 141 } ··· 151 151 done: 152 152 *curr = cpu_to_be32(n); 153 153 set_page_dirty(page); 154 - kunmap(page); 154 + kunmap_local(pptr); 155 155 *max = offset + (curr - pptr) * 32 + i - start; 156 156 sbi->free_blocks -= *max; 157 157 hfsplus_mark_mdb_dirty(sb); ··· 185 185 page = read_mapping_page(mapping, pnr, NULL); 186 186 if (IS_ERR(page)) 187 187 goto kaboom; 188 - pptr = kmap(page); 188 + pptr = kmap_local_page(page); 189 189 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; 190 190 end = pptr + PAGE_CACHE_BITS / 32; 191 191 len = count; ··· 215 215 if (!count) 216 216 break; 217 217 set_page_dirty(page); 218 - kunmap(page); 218 + kunmap_local(pptr); 219 219 page = read_mapping_page(mapping, ++pnr, NULL); 220 220 if (IS_ERR(page)) 221 221 goto kaboom; 222 - pptr = kmap(page); 222 + pptr = kmap_local_page(page); 223 223 curr = pptr; 224 224 end = pptr + PAGE_CACHE_BITS / 32; 225 225 } ··· 231 231 } 232 232 out: 233 233 set_page_dirty(page); 234 - kunmap(page); 234 + kunmap_local(pptr); 235 235 sbi->free_blocks += len; 236 236 hfsplus_mark_mdb_dirty(sb); 237 237 mutex_unlock(&sbi->alloc_mutex);
+48 -57
fs/hfsplus/bnode.c
··· 29 29 off &= ~PAGE_MASK; 30 30 31 31 l = min_t(int, len, PAGE_SIZE - off); 32 - memcpy(buf, kmap(*pagep) + off, l); 33 - kunmap(*pagep); 32 + memcpy_from_page(buf, *pagep, off, l); 34 33 35 34 while ((len -= l) != 0) { 36 35 buf += l; 37 36 l = min_t(int, len, PAGE_SIZE); 38 - memcpy(buf, kmap(*++pagep), l); 39 - kunmap(*pagep); 37 + memcpy_from_page(buf, *++pagep, 0, l); 40 38 } 41 39 } 42 40 ··· 80 82 off &= ~PAGE_MASK; 81 83 82 84 l = min_t(int, len, PAGE_SIZE - off); 83 - memcpy(kmap(*pagep) + off, buf, l); 85 + memcpy_to_page(*pagep, off, buf, l); 84 86 set_page_dirty(*pagep); 85 - kunmap(*pagep); 86 87 87 88 while ((len -= l) != 0) { 88 89 buf += l; 89 90 l = min_t(int, len, PAGE_SIZE); 90 - memcpy(kmap(*++pagep), buf, l); 91 + memcpy_to_page(*++pagep, 0, buf, l); 91 92 set_page_dirty(*pagep); 92 - kunmap(*pagep); 93 93 } 94 94 } 95 95 ··· 108 112 off &= ~PAGE_MASK; 109 113 110 114 l = min_t(int, len, PAGE_SIZE - off); 111 - memset(kmap(*pagep) + off, 0, l); 115 + memzero_page(*pagep, off, l); 112 116 set_page_dirty(*pagep); 113 - kunmap(*pagep); 114 117 115 118 while ((len -= l) != 0) { 116 119 l = min_t(int, len, PAGE_SIZE); 117 - memset(kmap(*++pagep), 0, l); 120 + memzero_page(*++pagep, 0, l); 118 121 set_page_dirty(*pagep); 119 - kunmap(*pagep); 120 122 } 121 123 } 122 124 ··· 136 142 137 143 if (src == dst) { 138 144 l = min_t(int, len, PAGE_SIZE - src); 139 - memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l); 140 - kunmap(*src_page); 145 + memcpy_page(*dst_page, src, *src_page, src, l); 141 146 set_page_dirty(*dst_page); 142 - kunmap(*dst_page); 143 147 144 148 while ((len -= l) != 0) { 145 149 l = min_t(int, len, PAGE_SIZE); 146 - memcpy(kmap(*++dst_page), kmap(*++src_page), l); 147 - kunmap(*src_page); 150 + memcpy_page(*++dst_page, 0, *++src_page, 0, l); 148 151 set_page_dirty(*dst_page); 149 - kunmap(*dst_page); 150 152 } 151 153 } else { 152 154 void *src_ptr, *dst_ptr; 153 155 154 156 do { 155 - src_ptr = kmap(*src_page) + src; 156 - dst_ptr = kmap(*dst_page) + dst; 157 + dst_ptr = kmap_local_page(*dst_page) + dst; 158 + src_ptr = kmap_local_page(*src_page) + src; 157 159 if (PAGE_SIZE - src < PAGE_SIZE - dst) { 158 160 l = PAGE_SIZE - src; 159 161 src = 0; ··· 161 171 } 162 172 l = min(len, l); 163 173 memcpy(dst_ptr, src_ptr, l); 164 - kunmap(*src_page); 174 + kunmap_local(src_ptr); 165 175 set_page_dirty(*dst_page); 166 - kunmap(*dst_page); 176 + kunmap_local(dst_ptr); 167 177 if (!dst) 168 178 dst_page++; 169 179 else ··· 175 185 void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) 176 186 { 177 187 struct page **src_page, **dst_page; 188 + void *src_ptr, *dst_ptr; 178 189 int l; 179 190 180 191 hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); ··· 193 202 194 203 if (src == dst) { 195 204 while (src < len) { 196 - memmove(kmap(*dst_page), kmap(*src_page), src); 197 - kunmap(*src_page); 205 + dst_ptr = kmap_local_page(*dst_page); 206 + src_ptr = kmap_local_page(*src_page); 207 + memmove(dst_ptr, src_ptr, src); 208 + kunmap_local(src_ptr); 198 209 set_page_dirty(*dst_page); 199 - kunmap(*dst_page); 210 + kunmap_local(dst_ptr); 200 211 len -= src; 201 212 src = PAGE_SIZE; 202 213 src_page--; 203 214 dst_page--; 204 215 } 205 216 src -= len; 206 - memmove(kmap(*dst_page) + src, 207 - kmap(*src_page) + src, len); 208 - kunmap(*src_page); 217 + dst_ptr = kmap_local_page(*dst_page); 218 + src_ptr = kmap_local_page(*src_page); 219 + memmove(dst_ptr + src, src_ptr + src, len); 220 + kunmap_local(src_ptr); 209 221 set_page_dirty(*dst_page); 210 - kunmap(*dst_page); 222 + kunmap_local(dst_ptr); 211 223 } else { 212 - void *src_ptr, *dst_ptr; 213 - 214 224 do { 215 - src_ptr = kmap(*src_page) + src; 216 - dst_ptr = kmap(*dst_page) + dst; 225 + dst_ptr = kmap_local_page(*dst_page) + dst; 226 + src_ptr = kmap_local_page(*src_page) + src; 217 227 if (src < dst) { 218 228 l = src; 219 229 src = PAGE_SIZE; ··· 226 234 } 227 235 l = min(len, l); 228 236 memmove(dst_ptr - l, src_ptr - l, l); 229 - kunmap(*src_page); 237 + kunmap_local(src_ptr); 230 238 set_page_dirty(*dst_page); 231 - kunmap(*dst_page); 239 + kunmap_local(dst_ptr); 232 240 if (dst == PAGE_SIZE) 233 241 dst_page--; 234 242 else ··· 243 251 244 252 if (src == dst) { 245 253 l = min_t(int, len, PAGE_SIZE - src); 246 - memmove(kmap(*dst_page) + src, 247 - kmap(*src_page) + src, l); 248 - kunmap(*src_page); 254 + 255 + dst_ptr = kmap_local_page(*dst_page) + src; 256 + src_ptr = kmap_local_page(*src_page) + src; 257 + memmove(dst_ptr, src_ptr, l); 258 + kunmap_local(src_ptr); 249 259 set_page_dirty(*dst_page); 250 - kunmap(*dst_page); 260 + kunmap_local(dst_ptr); 251 261 252 262 while ((len -= l) != 0) { 253 263 l = min_t(int, len, PAGE_SIZE); 254 - memmove(kmap(*++dst_page), 255 - kmap(*++src_page), l); 256 - kunmap(*src_page); 264 + dst_ptr = kmap_local_page(*++dst_page); 265 + src_ptr = kmap_local_page(*++src_page); 266 + memmove(dst_ptr, src_ptr, l); 267 + kunmap_local(src_ptr); 257 268 set_page_dirty(*dst_page); 258 - kunmap(*dst_page); 269 + kunmap_local(dst_ptr); 259 270 } 260 271 } else { 261 - void *src_ptr, *dst_ptr; 262 - 263 272 do { 264 - src_ptr = kmap(*src_page) + src; 265 - dst_ptr = kmap(*dst_page) + dst; 273 + dst_ptr = kmap_local_page(*dst_page) + dst; 274 + src_ptr = kmap_local_page(*src_page) + src; 266 275 if (PAGE_SIZE - src < 267 276 PAGE_SIZE - dst) { 268 277 l = PAGE_SIZE - src; ··· 276 283 } 277 284 l = min(len, l); 278 285 memmove(dst_ptr, src_ptr, l); 279 - kunmap(*src_page); 286 + kunmap_local(src_ptr); 280 287 set_page_dirty(*dst_page); 281 - kunmap(*dst_page); 288 + kunmap_local(dst_ptr); 282 289 if (!dst) 283 290 dst_page++; 284 291 else ··· 491 498 if (!test_bit(HFS_BNODE_NEW, &node->flags)) 492 499 return node; 493 500 494 - desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + 495 - node->page_offset); 501 + desc = (struct hfs_bnode_desc *)(kmap_local_page(node->page[0]) + 502 + node->page_offset); 496 503 node->prev = be32_to_cpu(desc->prev); 497 504 node->next = be32_to_cpu(desc->next); 498 505 node->num_recs = be16_to_cpu(desc->num_recs); 499 506 node->type = desc->type; 500 507 node->height = desc->height; 501 - kunmap(node->page[0]); 508 + kunmap_local(desc); 502 509 503 510 switch (node->type) { 504 511 case HFS_NODE_HEADER: ··· 582 589 } 583 590 584 591 pagep = node->page; 585 - memset(kmap(*pagep) + node->page_offset, 0, 586 - min_t(int, PAGE_SIZE, tree->node_size)); 592 + memzero_page(*pagep, node->page_offset, 593 + min_t(int, PAGE_SIZE, tree->node_size)); 587 594 set_page_dirty(*pagep); 588 - kunmap(*pagep); 589 595 for (i = 1; i < tree->pages_per_bnode; i++) { 590 - memset(kmap(*++pagep), 0, PAGE_SIZE); 596 + memzero_page(*++pagep, 0, PAGE_SIZE); 591 597 set_page_dirty(*pagep); 592 - kunmap(*pagep); 593 598 } 594 599 clear_bit(HFS_BNODE_NEW, &node->flags); 595 600 wake_up(&node->lock_wq);
+14 -13
fs/hfsplus/btree.c
··· 163 163 goto free_inode; 164 164 165 165 /* Load the header */ 166 - head = (struct hfs_btree_header_rec *)(kmap(page) + 166 + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + 167 167 sizeof(struct hfs_bnode_desc)); 168 168 tree->root = be32_to_cpu(head->root); 169 169 tree->leaf_count = be32_to_cpu(head->leaf_count); ··· 240 240 (tree->node_size + PAGE_SIZE - 1) >> 241 241 PAGE_SHIFT; 242 242 243 - kunmap(page); 243 + kunmap_local(head); 244 244 put_page(page); 245 245 return tree; 246 246 247 247 fail_page: 248 + kunmap_local(head); 248 249 put_page(page); 249 250 free_inode: 250 251 tree->inode->i_mapping->a_ops = &hfsplus_aops; ··· 292 291 return -EIO; 293 292 /* Load the header */ 294 293 page = node->page[0]; 295 - head = (struct hfs_btree_header_rec *)(kmap(page) + 294 + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + 296 295 sizeof(struct hfs_bnode_desc)); 297 296 298 297 head->root = cpu_to_be32(tree->root); ··· 304 303 head->attributes = cpu_to_be32(tree->attributes); 305 304 head->depth = cpu_to_be16(tree->depth); 306 305 307 - kunmap(page); 306 + kunmap_local(head); 308 307 set_page_dirty(page); 309 308 hfs_bnode_put(node); 310 309 return 0; ··· 395 394 396 395 off += node->page_offset; 397 396 pagep = node->page + (off >> PAGE_SHIFT); 398 - data = kmap(*pagep); 397 + data = kmap_local_page(*pagep); 399 398 off &= ~PAGE_MASK; 400 399 idx = 0; 401 400 ··· 408 407 idx += i; 409 408 data[off] |= m; 410 409 set_page_dirty(*pagep); 411 - kunmap(*pagep); 410 + kunmap_local(data); 412 411 tree->free_nodes--; 413 412 mark_inode_dirty(tree->inode); 414 413 hfs_bnode_put(node); ··· 418 417 } 419 418 } 420 419 if (++off >= PAGE_SIZE) { 421 - kunmap(*pagep); 422 - data = kmap(*++pagep); 420 + kunmap_local(data); 421 + data = kmap_local_page(*++pagep); 423 422 off = 0; 424 423 } 425 424 idx += 8; 426 425 len--; 427 426 } 428 - kunmap(*pagep); 427 + kunmap_local(data); 429 428 nidx = node->next; 430 429 if (!nidx) { 431 430 hfs_dbg(BNODE_MOD, "create new bmap node\n"); ··· 441 440 off = off16; 442 441 off += node->page_offset; 443 442 pagep = node->page + (off >> PAGE_SHIFT); 444 - data = kmap(*pagep); 443 + data = kmap_local_page(*pagep); 445 444 off &= ~PAGE_MASK; 446 445 } 447 446 } ··· 491 490 } 492 491 off += node->page_offset + nidx / 8; 493 492 page = node->page[off >> PAGE_SHIFT]; 494 - data = kmap(page); 493 + data = kmap_local_page(page); 495 494 off &= ~PAGE_MASK; 496 495 m = 1 << (~nidx & 7); 497 496 byte = data[off]; ··· 499 498 pr_crit("trying to free free bnode " 500 499 "%u(%d)\n", 501 500 node->this, node->type); 502 - kunmap(page); 501 + kunmap_local(data); 503 502 hfs_bnode_put(node); 504 503 return; 505 504 } 506 505 data[off] = byte & ~m; 507 506 set_page_dirty(page); 508 - kunmap(page); 507 + kunmap_local(data); 509 508 hfs_bnode_put(node); 510 509 tree->free_nodes++; 511 510 mark_inode_dirty(tree->inode);
+10 -10
fs/isofs/compress.c
··· 67 67 for ( i = 0 ; i < pcount ; i++ ) { 68 68 if (!pages[i]) 69 69 continue; 70 - memset(page_address(pages[i]), 0, PAGE_SIZE); 71 - flush_dcache_page(pages[i]); 70 + memzero_page(pages[i], 0, PAGE_SIZE); 72 71 SetPageUptodate(pages[i]); 73 72 } 74 73 return ((loff_t)pcount) << PAGE_SHIFT; ··· 119 120 zerr != Z_STREAM_END) { 120 121 if (!stream.avail_out) { 121 122 if (pages[curpage]) { 122 - stream.next_out = page_address(pages[curpage]) 123 + stream.next_out = kmap_local_page(pages[curpage]) 123 124 + poffset; 124 125 stream.avail_out = PAGE_SIZE - poffset; 125 126 poffset = 0; ··· 175 176 flush_dcache_page(pages[curpage]); 176 177 SetPageUptodate(pages[curpage]); 177 178 } 179 + if (stream.next_out != (unsigned char *)zisofs_sink_page) { 180 + kunmap_local(stream.next_out); 181 + stream.next_out = NULL; 182 + } 178 183 curpage++; 179 184 } 180 185 if (!stream.avail_in) ··· 186 183 } 187 184 inflate_out: 188 185 zlib_inflateEnd(&stream); 186 + if (stream.next_out && stream.next_out != (unsigned char *)zisofs_sink_page) 187 + kunmap_local(stream.next_out); 189 188 190 189 z_eio: 191 190 mutex_unlock(&zisofs_zlib_lock); ··· 288 283 } 289 284 290 285 if (poffset && *pages) { 291 - memset(page_address(*pages) + poffset, 0, 292 - PAGE_SIZE - poffset); 293 - flush_dcache_page(*pages); 286 + memzero_page(*pages, poffset, PAGE_SIZE - poffset); 294 287 SetPageUptodate(*pages); 295 288 } 296 289 return 0; ··· 346 343 for (i = 0; i < pcount; i++, index++) { 347 344 if (i != full_page) 348 345 pages[i] = grab_cache_page_nowait(mapping, index); 349 - if (pages[i]) { 346 + if (pages[i]) 350 347 ClearPageError(pages[i]); 351 - kmap(pages[i]); 352 - } 353 348 } 354 349 355 350 err = zisofs_fill_pages(inode, full_page, pcount, pages); ··· 358 357 flush_dcache_page(pages[i]); 359 358 if (i == full_page && err) 360 359 SetPageError(pages[i]); 361 - kunmap(pages[i]); 362 360 unlock_page(pages[i]); 363 361 if (i != full_page) 364 362 put_page(pages[i]);
+46
fs/libfs.c
··· 15 15 #include <linux/mutex.h> 16 16 #include <linux/namei.h> 17 17 #include <linux/exportfs.h> 18 + #include <linux/iversion.h> 18 19 #include <linux/writeback.h> 19 20 #include <linux/buffer_head.h> /* sync_mapping_buffers */ 20 21 #include <linux/fs_context.h> ··· 1521 1520 #endif 1522 1521 } 1523 1522 EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops); 1523 + 1524 + /** 1525 + * inode_maybe_inc_iversion - increments i_version 1526 + * @inode: inode with the i_version that should be updated 1527 + * @force: increment the counter even if it's not necessary? 1528 + * 1529 + * Every time the inode is modified, the i_version field must be seen to have 1530 + * changed by any observer. 1531 + * 1532 + * If "force" is set or the QUERIED flag is set, then ensure that we increment 1533 + * the value, and clear the queried flag. 1534 + * 1535 + * In the common case where neither is set, then we can return "false" without 1536 + * updating i_version. 1537 + * 1538 + * If this function returns false, and no other metadata has changed, then we 1539 + * can avoid logging the metadata. 1540 + */ 1541 + bool inode_maybe_inc_iversion(struct inode *inode, bool force) 1542 + { 1543 + u64 cur, new; 1544 + 1545 + /* 1546 + * The i_version field is not strictly ordered with any other inode 1547 + * information, but the legacy inode_inc_iversion code used a spinlock 1548 + * to serialize increments. 1549 + * 1550 + * Here, we add full memory barriers to ensure that any de-facto 1551 + * ordering with other info is preserved. 1552 + * 1553 + * This barrier pairs with the barrier in inode_query_iversion() 1554 + */ 1555 + smp_mb(); 1556 + cur = inode_peek_iversion_raw(inode); 1557 + do { 1558 + /* If flag is clear then we needn't do anything */ 1559 + if (!force && !(cur & I_VERSION_QUERIED)) 1560 + return false; 1561 + 1562 + /* Since lowest bit is flag, add 2 to avoid it */ 1563 + new = (cur & ~I_VERSION_QUERIED) + I_VERSION_INCREMENT; 1564 + } while (!atomic64_try_cmpxchg(&inode->i_version, &cur, new)); 1565 + return true; 1566 + } 1567 + EXPORT_SYMBOL(inode_maybe_inc_iversion);
+2 -4
fs/nilfs2/btree.c
··· 1668 1668 maxkey = nilfs_btree_node_get_key(node, nchildren - 1); 1669 1669 nextmaxkey = (nchildren > 1) ? 1670 1670 nilfs_btree_node_get_key(node, nchildren - 2) : 0; 1671 - if (bh != NULL) 1672 - brelse(bh); 1671 + brelse(bh); 1673 1672 1674 1673 return (maxkey == key) && (nextmaxkey < NILFS_BMAP_LARGE_LOW); 1675 1674 } ··· 1716 1717 ptrs[i] = le64_to_cpu(dptrs[i]); 1717 1718 } 1718 1719 1719 - if (bh != NULL) 1720 - brelse(bh); 1720 + brelse(bh); 1721 1721 1722 1722 return nitems; 1723 1723 }
+11 -7
fs/nilfs2/segment.c
··· 875 875 nilfs_mdt_mark_dirty(nilfs->ns_cpfile); 876 876 nilfs_cpfile_put_checkpoint( 877 877 nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); 878 - } else 879 - WARN_ON(err == -EINVAL || err == -ENOENT); 880 - 878 + } else if (err == -EINVAL || err == -ENOENT) { 879 + nilfs_error(sci->sc_super, 880 + "checkpoint creation failed due to metadata corruption."); 881 + err = -EIO; 882 + } 881 883 return err; 882 884 } 883 885 ··· 893 891 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0, 894 892 &raw_cp, &bh_cp); 895 893 if (unlikely(err)) { 896 - WARN_ON(err == -EINVAL || err == -ENOENT); 894 + if (err == -EINVAL || err == -ENOENT) { 895 + nilfs_error(sci->sc_super, 896 + "checkpoint finalization failed due to metadata corruption."); 897 + err = -EIO; 898 + } 897 899 goto failed_ibh; 898 900 } 899 901 raw_cp->cp_snapshot_list.ssl_next = 0; ··· 2241 2235 struct the_nilfs *nilfs = sb->s_fs_info; 2242 2236 struct nilfs_sc_info *sci = nilfs->ns_writer; 2243 2237 struct nilfs_transaction_info *ti; 2244 - int err; 2245 2238 2246 2239 if (!sci) 2247 2240 return -EROFS; ··· 2248 2243 /* A call inside transactions causes a deadlock. */ 2249 2244 BUG_ON((ti = current->journal_info) && ti->ti_magic == NILFS_TI_MAGIC); 2250 2245 2251 - err = nilfs_segctor_sync(sci); 2252 - return err; 2246 + return nilfs_segctor_sync(sci); 2253 2247 } 2254 2248 2255 2249 /**
+24 -4
fs/ntfs/attrib.c
··· 594 594 for (;; a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) { 595 595 u8 *mrec_end = (u8 *)ctx->mrec + 596 596 le32_to_cpu(ctx->mrec->bytes_allocated); 597 - u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) + 598 - a->name_length * sizeof(ntfschar); 599 - if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end || 600 - name_end > mrec_end) 597 + u8 *name_end; 598 + 599 + /* check whether ATTR_RECORD wrap */ 600 + if ((u8 *)a < (u8 *)ctx->mrec) 601 601 break; 602 + 603 + /* check whether Attribute Record Header is within bounds */ 604 + if ((u8 *)a > mrec_end || 605 + (u8 *)a + sizeof(ATTR_RECORD) > mrec_end) 606 + break; 607 + 608 + /* check whether ATTR_RECORD's name is within bounds */ 609 + name_end = (u8 *)a + le16_to_cpu(a->name_offset) + 610 + a->name_length * sizeof(ntfschar); 611 + if (name_end > mrec_end) 612 + break; 613 + 602 614 ctx->attr = a; 603 615 if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) || 604 616 a->type == AT_END)) 605 617 return -ENOENT; 606 618 if (unlikely(!a->length)) 607 619 break; 620 + 621 + /* check whether ATTR_RECORD's length wrap */ 622 + if ((u8 *)a + le32_to_cpu(a->length) < (u8 *)a) 623 + break; 624 + /* check whether ATTR_RECORD's length is within bounds */ 625 + if ((u8 *)a + le32_to_cpu(a->length) > mrec_end) 626 + break; 627 + 608 628 if (a->type != type) 609 629 continue; 610 630 /*
+7
fs/ntfs/inode.c
··· 1829 1829 goto err_out; 1830 1830 } 1831 1831 1832 + /* Sanity check offset to the first attribute */ 1833 + if (le16_to_cpu(m->attrs_offset) >= le32_to_cpu(m->bytes_allocated)) { 1834 + ntfs_error(sb, "Incorrect mft offset to the first attribute %u in superblock.", 1835 + le16_to_cpu(m->attrs_offset)); 1836 + goto err_out; 1837 + } 1838 + 1832 1839 /* Need this to sanity check attribute list references to $MFT. */ 1833 1840 vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number); 1834 1841
+4 -4
fs/ocfs2/ocfs2_fs.h
··· 527 527 * value -1 (0xFFFF) is OCFS2_INVALID_SLOT. This marks a slot empty. 528 528 */ 529 529 struct ocfs2_slot_map { 530 - /*00*/ __le16 sm_slots[0]; 530 + /*00*/ DECLARE_FLEX_ARRAY(__le16, sm_slots); 531 531 /* 532 532 * Actual on-disk size is one block. OCFS2_MAX_SLOTS is 255, 533 533 * 255 * sizeof(__le16) == 512B, within the 512B block minimum blocksize. ··· 548 548 * i_size. 549 549 */ 550 550 struct ocfs2_slot_map_extended { 551 - /*00*/ struct ocfs2_extended_slot se_slots[0]; 551 + /*00*/ DECLARE_FLEX_ARRAY(struct ocfs2_extended_slot, se_slots); 552 552 /* 553 553 * Actual size is i_size of the slot_map system file. It should 554 554 * match s_max_slots * sizeof(struct ocfs2_extended_slot) ··· 727 727 struct ocfs2_extent_list i_list; 728 728 struct ocfs2_truncate_log i_dealloc; 729 729 struct ocfs2_inline_data i_data; 730 - __u8 i_symlink[0]; 730 + DECLARE_FLEX_ARRAY(__u8, i_symlink); 731 731 } id2; 732 732 /* Actual on-disk size is one block */ 733 733 }; ··· 892 892 /*30*/ struct ocfs2_block_check bg_check; /* Error checking */ 893 893 __le64 bg_reserved2; 894 894 /*40*/ union { 895 - __u8 bg_bitmap[0]; 895 + DECLARE_FLEX_ARRAY(__u8, bg_bitmap); 896 896 struct { 897 897 /* 898 898 * Block groups may be discontiguous when
+1 -1
fs/ocfs2/refcounttree.c
··· 2614 2614 } 2615 2615 2616 2616 /* 2617 - * Calculate out the start and number of virtual clusters we need to to CoW. 2617 + * Calculate out the start and number of virtual clusters we need to CoW. 2618 2618 * 2619 2619 * cpos is vitual start cluster position we want to do CoW in a 2620 2620 * file and write_len is the cluster length.
+2 -2
fs/ocfs2/stackglue.c
··· 334 334 goto out; 335 335 } 336 336 337 - strlcpy(new_conn->cc_name, group, GROUP_NAME_MAX + 1); 337 + strscpy(new_conn->cc_name, group, GROUP_NAME_MAX + 1); 338 338 new_conn->cc_namelen = grouplen; 339 339 if (cluster_name_len) 340 - strlcpy(new_conn->cc_cluster_name, cluster_name, 340 + strscpy(new_conn->cc_cluster_name, cluster_name, 341 341 CLUSTER_NAME_MAX + 1); 342 342 new_conn->cc_cluster_name_len = cluster_name_len; 343 343 new_conn->cc_recovery_handler = recovery_handler;
+1 -1
fs/ocfs2/suballoc.h
··· 106 106 u32 *cluster_start, 107 107 u32 *num_clusters); 108 108 /* 109 - * Use this variant of ocfs2_claim_clusters to specify a maxiumum 109 + * Use this variant of ocfs2_claim_clusters to specify a maximum 110 110 * number of clusters smaller than the allocation reserved. 111 111 */ 112 112 int __ocfs2_claim_clusters(handle_t *handle,
+1 -1
fs/ocfs2/super.c
··· 2219 2219 goto out_journal; 2220 2220 } 2221 2221 2222 - strlcpy(osb->vol_label, di->id2.i_super.s_label, 2222 + strscpy(osb->vol_label, di->id2.i_super.s_label, 2223 2223 OCFS2_MAX_VOL_LABEL_LEN); 2224 2224 osb->root_blkno = le64_to_cpu(di->id2.i_super.s_root_blkno); 2225 2225 osb->system_dir_blkno = le64_to_cpu(di->id2.i_super.s_system_dir_blkno);
+1
fs/proc/Kconfig
··· 92 92 93 93 config PROC_CHILDREN 94 94 bool "Include /proc/<pid>/task/<tid>/children file" 95 + depends on PROC_FS 95 96 default n 96 97 help 97 98 Provides a fast way to retrieve first level children pids of a task. See
+5 -1
fs/proc/devices.c
··· 4 4 #include <linux/proc_fs.h> 5 5 #include <linux/seq_file.h> 6 6 #include <linux/blkdev.h> 7 + #include "internal.h" 7 8 8 9 static int devinfo_show(struct seq_file *f, void *v) 9 10 { ··· 55 54 56 55 static int __init proc_devices_init(void) 57 56 { 58 - proc_create_seq("devices", 0, NULL, &devinfo_ops); 57 + struct proc_dir_entry *pde; 58 + 59 + pde = proc_create_seq("devices", 0, NULL, &devinfo_ops); 60 + pde_make_permanent(pde); 59 61 return 0; 60 62 } 61 63 fs_initcall(proc_devices_init);
+5
fs/proc/internal.h
··· 79 79 return pde->flags & PROC_ENTRY_PERMANENT; 80 80 } 81 81 82 + static inline void pde_make_permanent(struct proc_dir_entry *pde) 83 + { 84 + pde->flags |= PROC_ENTRY_PERMANENT; 85 + } 86 + 82 87 extern struct kmem_cache *proc_dir_entry_cache; 83 88 void pde_free(struct proc_dir_entry *pde); 84 89
+5 -1
fs/proc/loadavg.c
··· 9 9 #include <linux/seq_file.h> 10 10 #include <linux/seqlock.h> 11 11 #include <linux/time.h> 12 + #include "internal.h" 12 13 13 14 static int loadavg_proc_show(struct seq_file *m, void *v) 14 15 { ··· 28 27 29 28 static int __init proc_loadavg_init(void) 30 29 { 31 - proc_create_single("loadavg", 0, NULL, loadavg_proc_show); 30 + struct proc_dir_entry *pde; 31 + 32 + pde = proc_create_single("loadavg", 0, NULL, loadavg_proc_show); 33 + pde_make_permanent(pde); 32 34 return 0; 33 35 } 34 36 fs_initcall(proc_loadavg_init);
+4 -1
fs/proc/meminfo.c
··· 164 164 165 165 static int __init proc_meminfo_init(void) 166 166 { 167 - proc_create_single("meminfo", 0, NULL, meminfo_proc_show); 167 + struct proc_dir_entry *pde; 168 + 169 + pde = proc_create_single("meminfo", 0, NULL, meminfo_proc_show); 170 + pde_make_permanent(pde); 168 171 return 0; 169 172 } 170 173 fs_initcall(proc_meminfo_init);
+3
fs/proc/page.c
··· 91 91 } 92 92 93 93 static const struct proc_ops kpagecount_proc_ops = { 94 + .proc_flags = PROC_ENTRY_PERMANENT, 94 95 .proc_lseek = mem_lseek, 95 96 .proc_read = kpagecount_read, 96 97 }; ··· 269 268 } 270 269 271 270 static const struct proc_ops kpageflags_proc_ops = { 271 + .proc_flags = PROC_ENTRY_PERMANENT, 272 272 .proc_lseek = mem_lseek, 273 273 .proc_read = kpageflags_read, 274 274 }; ··· 324 322 } 325 323 326 324 static const struct proc_ops kpagecgroup_proc_ops = { 325 + .proc_flags = PROC_ENTRY_PERMANENT, 327 326 .proc_lseek = mem_lseek, 328 327 .proc_read = kpagecgroup_read, 329 328 };
+5 -1
fs/proc/softirqs.c
··· 3 3 #include <linux/kernel_stat.h> 4 4 #include <linux/proc_fs.h> 5 5 #include <linux/seq_file.h> 6 + #include "internal.h" 6 7 7 8 /* 8 9 * /proc/softirqs ... display the number of softirqs ··· 28 27 29 28 static int __init proc_softirqs_init(void) 30 29 { 31 - proc_create_single("softirqs", 0, NULL, show_softirqs); 30 + struct proc_dir_entry *pde; 31 + 32 + pde = proc_create_single("softirqs", 0, NULL, show_softirqs); 33 + pde_make_permanent(pde); 32 34 return 0; 33 35 } 34 36 fs_initcall(proc_softirqs_init);
+5 -1
fs/proc/uptime.c
··· 7 7 #include <linux/time.h> 8 8 #include <linux/time_namespace.h> 9 9 #include <linux/kernel_stat.h> 10 + #include "internal.h" 10 11 11 12 static int uptime_proc_show(struct seq_file *m, void *v) 12 13 { ··· 40 39 41 40 static int __init proc_uptime_init(void) 42 41 { 43 - proc_create_single("uptime", 0, NULL, uptime_proc_show); 42 + struct proc_dir_entry *pde; 43 + 44 + pde = proc_create_single("uptime", 0, NULL, uptime_proc_show); 45 + pde_make_permanent(pde); 44 46 return 0; 45 47 } 46 48 fs_initcall(proc_uptime_init);
+5 -1
fs/proc/version.c
··· 5 5 #include <linux/proc_fs.h> 6 6 #include <linux/seq_file.h> 7 7 #include <linux/utsname.h> 8 + #include "internal.h" 8 9 9 10 static int version_proc_show(struct seq_file *m, void *v) 10 11 { ··· 18 17 19 18 static int __init proc_version_init(void) 20 19 { 21 - proc_create_single("version", 0, NULL, version_proc_show); 20 + struct proc_dir_entry *pde; 21 + 22 + pde = proc_create_single("version", 0, NULL, version_proc_show); 23 + pde_make_permanent(pde); 22 24 return 0; 23 25 } 24 26 fs_initcall(proc_version_init);
+2 -4
fs/qnx6/inode.c
··· 470 470 out1: 471 471 iput(sbi->inodes); 472 472 out: 473 - if (bh1) 474 - brelse(bh1); 475 - if (bh2) 476 - brelse(bh2); 473 + brelse(bh1); 474 + brelse(bh2); 477 475 outnobh: 478 476 kfree(qs); 479 477 s->s_fs_info = NULL;
+2 -2
fs/reiserfs/procfs.c
··· 411 411 char *s; 412 412 413 413 /* Some block devices use /'s */ 414 - strlcpy(b, sb->s_id, BDEVNAME_SIZE); 414 + strscpy(b, sb->s_id, BDEVNAME_SIZE); 415 415 s = strchr(b, '/'); 416 416 if (s) 417 417 *s = '!'; ··· 441 441 char *s; 442 442 443 443 /* Some block devices use /'s */ 444 - strlcpy(b, sb->s_id, BDEVNAME_SIZE); 444 + strscpy(b, sb->s_id, BDEVNAME_SIZE); 445 445 s = strchr(b, '/'); 446 446 if (s) 447 447 *s = '!';
+1 -1
include/asm-generic/unaligned.h
··· 126 126 __put_unaligned_le24(val, p); 127 127 } 128 128 129 - static inline void __put_unaligned_be48(const u64 val, __u8 *p) 129 + static inline void __put_unaligned_be48(const u64 val, u8 *p) 130 130 { 131 131 *p++ = val >> 40; 132 132 *p++ = val >> 32;
+6 -5
include/linux/bitops.h
··· 347 347 const typeof(*(ptr)) mask__ = (mask), bits__ = (bits); \ 348 348 typeof(*(ptr)) old__, new__; \ 349 349 \ 350 + old__ = READ_ONCE(*(ptr)); \ 350 351 do { \ 351 - old__ = READ_ONCE(*(ptr)); \ 352 352 new__ = (old__ & ~mask__) | bits__; \ 353 - } while (cmpxchg(ptr, old__, new__) != old__); \ 353 + } while (!try_cmpxchg(ptr, &old__, new__)); \ 354 354 \ 355 355 old__; \ 356 356 }) ··· 362 362 const typeof(*(ptr)) clear__ = (clear), test__ = (test);\ 363 363 typeof(*(ptr)) old__, new__; \ 364 364 \ 365 + old__ = READ_ONCE(*(ptr)); \ 365 366 do { \ 366 - old__ = READ_ONCE(*(ptr)); \ 367 + if (old__ & test__) \ 368 + break; \ 367 369 new__ = old__ & ~clear__; \ 368 - } while (!(old__ & test__) && \ 369 - cmpxchg(ptr, old__, new__) != old__); \ 370 + } while (!try_cmpxchg(ptr, &old__, new__)); \ 370 371 \ 371 372 !(old__ & test__); \ 372 373 })
-1
include/linux/entry-common.h
··· 253 253 /** 254 254 * arch_do_signal_or_restart - Architecture specific signal delivery function 255 255 * @regs: Pointer to currents pt_regs 256 - * @has_signal: actual signal to handle 257 256 * 258 257 * Invoked from exit_to_user_mode_loop(). 259 258 */
+1 -1
include/linux/init.h
··· 134 134 135 135 extern initcall_entry_t __con_initcall_start[], __con_initcall_end[]; 136 136 137 - /* Used for contructor calls. */ 137 + /* Used for constructor calls. */ 138 138 typedef void (*ctor_fn_t)(void); 139 139 140 140 struct file_system_type;
+3 -2
include/linux/ipc_namespace.h
··· 11 11 #include <linux/refcount.h> 12 12 #include <linux/rhashtable-types.h> 13 13 #include <linux/sysctl.h> 14 + #include <linux/percpu_counter.h> 14 15 15 16 struct user_namespace; 16 17 ··· 37 36 unsigned int msg_ctlmax; 38 37 unsigned int msg_ctlmnb; 39 38 unsigned int msg_ctlmni; 40 - atomic_t msg_bytes; 41 - atomic_t msg_hdrs; 39 + struct percpu_counter percpu_msg_bytes; 40 + struct percpu_counter percpu_msg_hdrs; 42 41 43 42 size_t shm_ctlmax; 44 43 size_t shm_ctlall;
+7 -65
include/linux/iversion.h
··· 123 123 static inline void 124 124 inode_set_max_iversion_raw(struct inode *inode, u64 val) 125 125 { 126 - u64 cur, old; 126 + u64 cur = inode_peek_iversion_raw(inode); 127 127 128 - cur = inode_peek_iversion_raw(inode); 129 - for (;;) { 128 + do { 130 129 if (cur > val) 131 130 break; 132 - old = atomic64_cmpxchg(&inode->i_version, cur, val); 133 - if (likely(old == cur)) 134 - break; 135 - cur = old; 136 - } 131 + } while (!atomic64_try_cmpxchg(&inode->i_version, &cur, val)); 137 132 } 138 133 139 134 /** ··· 172 177 I_VERSION_QUERIED); 173 178 } 174 179 175 - /** 176 - * inode_maybe_inc_iversion - increments i_version 177 - * @inode: inode with the i_version that should be updated 178 - * @force: increment the counter even if it's not necessary? 179 - * 180 - * Every time the inode is modified, the i_version field must be seen to have 181 - * changed by any observer. 182 - * 183 - * If "force" is set or the QUERIED flag is set, then ensure that we increment 184 - * the value, and clear the queried flag. 185 - * 186 - * In the common case where neither is set, then we can return "false" without 187 - * updating i_version. 188 - * 189 - * If this function returns false, and no other metadata has changed, then we 190 - * can avoid logging the metadata. 191 - */ 192 - static inline bool 193 - inode_maybe_inc_iversion(struct inode *inode, bool force) 194 - { 195 - u64 cur, old, new; 196 - 197 - /* 198 - * The i_version field is not strictly ordered with any other inode 199 - * information, but the legacy inode_inc_iversion code used a spinlock 200 - * to serialize increments. 201 - * 202 - * Here, we add full memory barriers to ensure that any de-facto 203 - * ordering with other info is preserved. 204 - * 205 - * This barrier pairs with the barrier in inode_query_iversion() 206 - */ 207 - smp_mb(); 208 - cur = inode_peek_iversion_raw(inode); 209 - for (;;) { 210 - /* If flag is clear then we needn't do anything */ 211 - if (!force && !(cur & I_VERSION_QUERIED)) 212 - return false; 213 - 214 - /* Since lowest bit is flag, add 2 to avoid it */ 215 - new = (cur & ~I_VERSION_QUERIED) + I_VERSION_INCREMENT; 216 - 217 - old = atomic64_cmpxchg(&inode->i_version, cur, new); 218 - if (likely(old == cur)) 219 - break; 220 - cur = old; 221 - } 222 - return true; 223 - } 224 - 180 + bool inode_maybe_inc_iversion(struct inode *inode, bool force); 225 181 226 182 /** 227 183 * inode_inc_iversion - forcibly increment i_version ··· 250 304 static inline u64 251 305 inode_query_iversion(struct inode *inode) 252 306 { 253 - u64 cur, old, new; 307 + u64 cur, new; 254 308 255 309 cur = inode_peek_iversion_raw(inode); 256 - for (;;) { 310 + do { 257 311 /* If flag is already set, then no need to swap */ 258 312 if (cur & I_VERSION_QUERIED) { 259 313 /* ··· 266 320 } 267 321 268 322 new = cur | I_VERSION_QUERIED; 269 - old = atomic64_cmpxchg(&inode->i_version, cur, new); 270 - if (likely(old == cur)) 271 - break; 272 - cur = old; 273 - } 323 + } while (!atomic64_try_cmpxchg(&inode->i_version, &cur, new)); 274 324 return cur >> I_VERSION_QUERIED_SHIFT; 275 325 } 276 326
+1 -1
include/linux/kexec.h
··· 427 427 extern bool kexec_in_progress; 428 428 429 429 int crash_shrink_memory(unsigned long new_size); 430 - size_t crash_get_memory_size(void); 430 + ssize_t crash_get_memory_size(void); 431 431 432 432 #ifndef arch_kexec_protect_crashkres 433 433 /*
+32
include/linux/percpu_counter.h
··· 15 15 #include <linux/types.h> 16 16 #include <linux/gfp.h> 17 17 18 + /* percpu_counter batch for local add or sub */ 19 + #define PERCPU_COUNTER_LOCAL_BATCH INT_MAX 20 + 18 21 #ifdef CONFIG_SMP 19 22 20 23 struct percpu_counter { ··· 57 54 static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) 58 55 { 59 56 percpu_counter_add_batch(fbc, amount, percpu_counter_batch); 57 + } 58 + 59 + /* 60 + * With percpu_counter_add_local() and percpu_counter_sub_local(), counts 61 + * are accumulated in local per cpu counter and not in fbc->count until 62 + * local count overflows PERCPU_COUNTER_LOCAL_BATCH. This makes counter 63 + * write efficient. 64 + * But percpu_counter_sum(), instead of percpu_counter_read(), needs to be 65 + * used to add up the counts from each CPU to account for all the local 66 + * counts. So percpu_counter_add_local() and percpu_counter_sub_local() 67 + * should be used when a counter is updated frequently and read rarely. 68 + */ 69 + static inline void 70 + percpu_counter_add_local(struct percpu_counter *fbc, s64 amount) 71 + { 72 + percpu_counter_add_batch(fbc, amount, PERCPU_COUNTER_LOCAL_BATCH); 60 73 } 61 74 62 75 static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) ··· 157 138 preempt_enable(); 158 139 } 159 140 141 + /* non-SMP percpu_counter_add_local is the same with percpu_counter_add */ 142 + static inline void 143 + percpu_counter_add_local(struct percpu_counter *fbc, s64 amount) 144 + { 145 + percpu_counter_add(fbc, amount); 146 + } 147 + 160 148 static inline void 161 149 percpu_counter_add_batch(struct percpu_counter *fbc, s64 amount, s32 batch) 162 150 { ··· 217 191 static inline void percpu_counter_sub(struct percpu_counter *fbc, s64 amount) 218 192 { 219 193 percpu_counter_add(fbc, -amount); 194 + } 195 + 196 + static inline void 197 + percpu_counter_sub_local(struct percpu_counter *fbc, s64 amount) 198 + { 199 + percpu_counter_add_local(fbc, -amount); 220 200 } 221 201 222 202 #endif /* _LINUX_PERCPU_COUNTER_H */
+3
include/linux/sched/task.h
··· 127 127 128 128 void put_task_struct_rcu_user(struct task_struct *task); 129 129 130 + /* Free all architecture-specific resources held by a thread. */ 131 + void release_thread(struct task_struct *dead_task); 132 + 130 133 #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT 131 134 extern int arch_task_struct_size __read_mostly; 132 135 #else
+1
init/Kconfig
··· 1267 1267 1268 1268 config CHECKPOINT_RESTORE 1269 1269 bool "Checkpoint/restore support" 1270 + depends on PROC_FS 1270 1271 select PROC_CHILDREN 1271 1272 select KCMP 1272 1273 default n
+2 -2
init/do_mounts.c
··· 296 296 297 297 static int __init root_dev_setup(char *line) 298 298 { 299 - strlcpy(saved_root_name, line, sizeof(saved_root_name)); 299 + strscpy(saved_root_name, line, sizeof(saved_root_name)); 300 300 return 1; 301 301 } 302 302 ··· 343 343 int count = 1; 344 344 char *p = page; 345 345 346 - strlcpy(p, root_fs_names, size); 346 + strscpy(p, root_fs_names, size); 347 347 while (*p++) { 348 348 if (p[-1] == ',') { 349 349 p[-1] = '\0';
+1 -1
init/initramfs.c
··· 482 482 return origLen; 483 483 } 484 484 485 - static unsigned long my_inptr; /* index of next byte to be processed in inbuf */ 485 + static unsigned long my_inptr __initdata; /* index of next byte to be processed in inbuf */ 486 486 487 487 #include <linux/decompress/generic.h> 488 488
+4 -4
init/main.c
··· 424 424 if (!data) 425 425 data = xbc_get_embedded_bootconfig(&size); 426 426 427 - strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); 427 + strscpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); 428 428 err = parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, 429 429 bootconfig_params); 430 430 ··· 764 764 return; 765 765 766 766 /* All fall through to do_early_param. */ 767 - strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); 767 + strscpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); 768 768 parse_early_options(tmp_cmdline); 769 769 done = 1; 770 770 } ··· 1244 1244 static __init_or_module void 1245 1245 trace_initcall_start_cb(void *data, initcall_t fn) 1246 1246 { 1247 - ktime_t *calltime = (ktime_t *)data; 1247 + ktime_t *calltime = data; 1248 1248 1249 1249 printk(KERN_DEBUG "calling %pS @ %i\n", fn, task_pid_nr(current)); 1250 1250 *calltime = ktime_get(); ··· 1253 1253 static __init_or_module void 1254 1254 trace_initcall_finish_cb(void *data, initcall_t fn, int ret) 1255 1255 { 1256 - ktime_t rettime, *calltime = (ktime_t *)data; 1256 + ktime_t rettime, *calltime = data; 1257 1257 1258 1258 rettime = ktime_get(); 1259 1259 printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n",
+1 -2
ipc/mqueue.c
··· 986 986 987 987 out_unlock: 988 988 inode_unlock(d_inode(mnt->mnt_root)); 989 - if (inode) 990 - iput(inode); 989 + iput(inode); 991 990 mnt_drop_write(mnt); 992 991 out_name: 993 992 putname(name);
+34 -14
ipc/msg.c
··· 39 39 #include <linux/nsproxy.h> 40 40 #include <linux/ipc_namespace.h> 41 41 #include <linux/rhashtable.h> 42 + #include <linux/percpu_counter.h> 42 43 43 44 #include <asm/current.h> 44 45 #include <linux/uaccess.h> ··· 286 285 rcu_read_unlock(); 287 286 288 287 list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) { 289 - atomic_dec(&ns->msg_hdrs); 288 + percpu_counter_sub_local(&ns->percpu_msg_hdrs, 1); 290 289 free_msg(msg); 291 290 } 292 - atomic_sub(msq->q_cbytes, &ns->msg_bytes); 291 + percpu_counter_sub_local(&ns->percpu_msg_bytes, msq->q_cbytes); 293 292 ipc_update_pid(&msq->q_lspid, NULL); 294 293 ipc_update_pid(&msq->q_lrpid, NULL); 295 294 ipc_rcu_putref(&msq->q_perm, msg_rcu_free); ··· 496 495 msginfo->msgssz = MSGSSZ; 497 496 msginfo->msgseg = MSGSEG; 498 497 down_read(&msg_ids(ns).rwsem); 499 - if (cmd == MSG_INFO) { 498 + if (cmd == MSG_INFO) 500 499 msginfo->msgpool = msg_ids(ns).in_use; 501 - msginfo->msgmap = atomic_read(&ns->msg_hdrs); 502 - msginfo->msgtql = atomic_read(&ns->msg_bytes); 500 + max_idx = ipc_get_maxidx(&msg_ids(ns)); 501 + up_read(&msg_ids(ns).rwsem); 502 + if (cmd == MSG_INFO) { 503 + msginfo->msgmap = min_t(int, 504 + percpu_counter_sum(&ns->percpu_msg_hdrs), 505 + INT_MAX); 506 + msginfo->msgtql = min_t(int, 507 + percpu_counter_sum(&ns->percpu_msg_bytes), 508 + INT_MAX); 503 509 } else { 504 510 msginfo->msgmap = MSGMAP; 505 511 msginfo->msgpool = MSGPOOL; 506 512 msginfo->msgtql = MSGTQL; 507 513 } 508 - max_idx = ipc_get_maxidx(&msg_ids(ns)); 509 - up_read(&msg_ids(ns).rwsem); 510 514 return (max_idx < 0) ? 0 : max_idx; 511 515 } 512 516 ··· 941 935 list_add_tail(&msg->m_list, &msq->q_messages); 942 936 msq->q_cbytes += msgsz; 943 937 msq->q_qnum++; 944 - atomic_add(msgsz, &ns->msg_bytes); 945 - atomic_inc(&ns->msg_hdrs); 938 + percpu_counter_add_local(&ns->percpu_msg_bytes, msgsz); 939 + percpu_counter_add_local(&ns->percpu_msg_hdrs, 1); 946 940 } 947 941 948 942 err = 0; ··· 1165 1159 msq->q_rtime = ktime_get_real_seconds(); 1166 1160 ipc_update_pid(&msq->q_lrpid, task_tgid(current)); 1167 1161 msq->q_cbytes -= msg->m_ts; 1168 - atomic_sub(msg->m_ts, &ns->msg_bytes); 1169 - atomic_dec(&ns->msg_hdrs); 1162 + percpu_counter_sub_local(&ns->percpu_msg_bytes, msg->m_ts); 1163 + percpu_counter_sub_local(&ns->percpu_msg_hdrs, 1); 1170 1164 ss_wakeup(msq, &wake_q, false); 1171 1165 1172 1166 goto out_unlock0; ··· 1303 1297 } 1304 1298 #endif 1305 1299 1306 - void msg_init_ns(struct ipc_namespace *ns) 1300 + int msg_init_ns(struct ipc_namespace *ns) 1307 1301 { 1302 + int ret; 1303 + 1308 1304 ns->msg_ctlmax = MSGMAX; 1309 1305 ns->msg_ctlmnb = MSGMNB; 1310 1306 ns->msg_ctlmni = MSGMNI; 1311 1307 1312 - atomic_set(&ns->msg_bytes, 0); 1313 - atomic_set(&ns->msg_hdrs, 0); 1308 + ret = percpu_counter_init(&ns->percpu_msg_bytes, 0, GFP_KERNEL); 1309 + if (ret) 1310 + goto fail_msg_bytes; 1311 + ret = percpu_counter_init(&ns->percpu_msg_hdrs, 0, GFP_KERNEL); 1312 + if (ret) 1313 + goto fail_msg_hdrs; 1314 1314 ipc_init_ids(&ns->ids[IPC_MSG_IDS]); 1315 + return 0; 1316 + 1317 + fail_msg_hdrs: 1318 + percpu_counter_destroy(&ns->percpu_msg_bytes); 1319 + fail_msg_bytes: 1320 + return ret; 1315 1321 } 1316 1322 1317 1323 #ifdef CONFIG_IPC_NS 1318 1324 void msg_exit_ns(struct ipc_namespace *ns) 1319 1325 { 1326 + percpu_counter_destroy(&ns->percpu_msg_bytes); 1327 + percpu_counter_destroy(&ns->percpu_msg_hdrs); 1320 1328 free_ipcs(ns, &msg_ids(ns), freeque); 1321 1329 idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr); 1322 1330 rhashtable_destroy(&ns->ids[IPC_MSG_IDS].key_ht);
+4 -1
ipc/namespace.c
··· 66 66 if (!setup_ipc_sysctls(ns)) 67 67 goto fail_mq; 68 68 69 + err = msg_init_ns(ns); 70 + if (err) 71 + goto fail_put; 72 + 69 73 sem_init_ns(ns); 70 - msg_init_ns(ns); 71 74 shm_init_ns(ns); 72 75 73 76 return ns;
+32 -21
ipc/util.c
··· 782 782 return iter->pid_ns; 783 783 } 784 784 785 - /* 786 - * This routine locks the ipc structure found at least at position pos. 785 + /** 786 + * sysvipc_find_ipc - Find and lock the ipc structure based on seq pos 787 + * @ids: ipc identifier set 788 + * @pos: expected position 789 + * 790 + * The function finds an ipc structure, based on the sequence file 791 + * position @pos. If there is no ipc structure at position @pos, then 792 + * the successor is selected. 793 + * If a structure is found, then it is locked (both rcu_read_lock() and 794 + * ipc_lock_object()) and @pos is set to the position needed to locate 795 + * the found ipc structure. 796 + * If nothing is found (i.e. EOF), @pos is not modified. 797 + * 798 + * The function returns the found ipc structure, or NULL at EOF. 787 799 */ 788 - static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, 789 - loff_t *new_pos) 800 + static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t *pos) 790 801 { 791 - struct kern_ipc_perm *ipc = NULL; 792 - int max_idx = ipc_get_maxidx(ids); 802 + int tmpidx; 803 + struct kern_ipc_perm *ipc; 793 804 794 - if (max_idx == -1 || pos > max_idx) 795 - goto out; 805 + /* convert from position to idr index -> "-1" */ 806 + tmpidx = *pos - 1; 796 807 797 - for (; pos <= max_idx; pos++) { 798 - ipc = idr_find(&ids->ipcs_idr, pos); 799 - if (ipc != NULL) { 800 - rcu_read_lock(); 801 - ipc_lock_object(ipc); 802 - break; 803 - } 808 + ipc = idr_get_next(&ids->ipcs_idr, &tmpidx); 809 + if (ipc != NULL) { 810 + rcu_read_lock(); 811 + ipc_lock_object(ipc); 812 + 813 + /* convert from idr index to position -> "+1" */ 814 + *pos = tmpidx + 1; 804 815 } 805 - out: 806 - *new_pos = pos + 1; 807 816 return ipc; 808 817 } 809 818 ··· 826 817 if (ipc && ipc != SEQ_START_TOKEN) 827 818 ipc_unlock(ipc); 828 819 829 - return sysvipc_find_ipc(&iter->ns->ids[iface->ids], *pos, pos); 820 + /* Next -> search for *pos+1 */ 821 + (*pos)++; 822 + return sysvipc_find_ipc(&iter->ns->ids[iface->ids], pos); 830 823 } 831 824 832 825 /* 833 - * File positions: pos 0 -> header, pos n -> ipc id = n - 1. 826 + * File positions: pos 0 -> header, pos n -> ipc idx = n - 1. 834 827 * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START. 835 828 */ 836 829 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) ··· 857 846 if (*pos == 0) 858 847 return SEQ_START_TOKEN; 859 848 860 - /* Find the (pos-1)th ipc */ 861 - return sysvipc_find_ipc(ids, *pos - 1, pos); 849 + /* Otherwise return the correct ipc structure */ 850 + return sysvipc_find_ipc(ids, pos); 862 851 } 863 852 864 853 static void sysvipc_proc_stop(struct seq_file *s, void *it)
+2 -2
ipc/util.h
··· 64 64 65 65 #ifdef CONFIG_SYSVIPC 66 66 void sem_init_ns(struct ipc_namespace *ns); 67 - void msg_init_ns(struct ipc_namespace *ns); 67 + int msg_init_ns(struct ipc_namespace *ns); 68 68 void shm_init_ns(struct ipc_namespace *ns); 69 69 70 70 void sem_exit_ns(struct ipc_namespace *ns); ··· 72 72 void shm_exit_ns(struct ipc_namespace *ns); 73 73 #else 74 74 static inline void sem_init_ns(struct ipc_namespace *ns) { } 75 - static inline void msg_init_ns(struct ipc_namespace *ns) { } 75 + static inline int msg_init_ns(struct ipc_namespace *ns) { return 0; } 76 76 static inline void shm_init_ns(struct ipc_namespace *ns) { } 77 77 78 78 static inline void sem_exit_ns(struct ipc_namespace *ns) { }
+4
kernel/exit.c
··· 184 184 call_rcu(&task->rcu, delayed_put_task_struct); 185 185 } 186 186 187 + void __weak release_thread(struct task_struct *dead_task) 188 + { 189 + } 190 + 187 191 void release_task(struct task_struct *p) 188 192 { 189 193 struct task_struct *leader;
+10 -16
kernel/fail_function.c
··· 247 247 /* cut off if it is too long */ 248 248 if (count > KSYM_NAME_LEN) 249 249 count = KSYM_NAME_LEN; 250 - buf = kmalloc(count + 1, GFP_KERNEL); 251 - if (!buf) 252 - return -ENOMEM; 253 250 254 - if (copy_from_user(buf, buffer, count)) { 255 - ret = -EFAULT; 256 - goto out_free; 257 - } 258 - buf[count] = '\0'; 251 + buf = memdup_user_nul(buffer, count); 252 + if (IS_ERR(buf)) 253 + return PTR_ERR(buf); 254 + 259 255 sym = strstrip(buf); 260 256 261 257 mutex_lock(&fei_lock); ··· 294 298 } 295 299 296 300 ret = register_kprobe(&attr->kp); 297 - if (!ret) 298 - fei_debugfs_add_attr(attr); 299 - if (ret < 0) 300 - fei_attr_remove(attr); 301 - else { 302 - list_add_tail(&attr->list, &fei_attr_list); 303 - ret = count; 301 + if (ret) { 302 + fei_attr_free(attr); 303 + goto out; 304 304 } 305 + fei_debugfs_add_attr(attr); 306 + list_add_tail(&attr->list, &fei_attr_list); 307 + ret = count; 305 308 out: 306 309 mutex_unlock(&fei_lock); 307 - out_free: 308 310 kfree(buf); 309 311 return ret; 310 312 }
-1
kernel/fork.c
··· 97 97 #include <linux/scs.h> 98 98 #include <linux/io_uring.h> 99 99 #include <linux/bpf.h> 100 - #include <linux/sched/mm.h> 101 100 102 101 #include <asm/pgalloc.h> 103 102 #include <linux/uaccess.h>
+4 -7
kernel/kexec.c
··· 93 93 94 94 /* 95 95 * Because we write directly to the reserved memory region when loading 96 - * crash kernels we need a mutex here to prevent multiple crash kernels 97 - * from attempting to load simultaneously, and to prevent a crash kernel 98 - * from loading over the top of a in use crash kernel. 99 - * 100 - * KISS: always take the mutex. 96 + * crash kernels we need a serialization here to prevent multiple crash 97 + * kernels from attempting to load simultaneously. 101 98 */ 102 - if (!mutex_trylock(&kexec_mutex)) 99 + if (!kexec_trylock()) 103 100 return -EBUSY; 104 101 105 102 if (flags & KEXEC_ON_CRASH) { ··· 162 165 163 166 kimage_free(image); 164 167 out_unlock: 165 - mutex_unlock(&kexec_mutex); 168 + kexec_unlock(); 166 169 return ret; 167 170 } 168 171
+20 -16
kernel/kexec_core.c
··· 46 46 #include <crypto/hash.h> 47 47 #include "kexec_internal.h" 48 48 49 - DEFINE_MUTEX(kexec_mutex); 49 + atomic_t __kexec_lock = ATOMIC_INIT(0); 50 50 51 51 /* Per cpu memory for storing cpu states in case of system crash. */ 52 52 note_buf_t __percpu *crash_notes; ··· 809 809 if (result < 0) 810 810 goto out; 811 811 812 - ptr = kmap(page); 812 + ptr = kmap_local_page(page); 813 813 /* Start with a clear page */ 814 814 clear_page(ptr); 815 815 ptr += maddr & ~PAGE_MASK; ··· 822 822 memcpy(ptr, kbuf, uchunk); 823 823 else 824 824 result = copy_from_user(ptr, buf, uchunk); 825 - kunmap(page); 825 + kunmap_local(ptr); 826 826 if (result) { 827 827 result = -EFAULT; 828 828 goto out; ··· 873 873 goto out; 874 874 } 875 875 arch_kexec_post_alloc_pages(page_address(page), 1, 0); 876 - ptr = kmap(page); 876 + ptr = kmap_local_page(page); 877 877 ptr += maddr & ~PAGE_MASK; 878 878 mchunk = min_t(size_t, mbytes, 879 879 PAGE_SIZE - (maddr & ~PAGE_MASK)); ··· 889 889 else 890 890 result = copy_from_user(ptr, buf, uchunk); 891 891 kexec_flush_icache_page(page); 892 - kunmap(page); 892 + kunmap_local(ptr); 893 893 arch_kexec_pre_free_pages(page_address(page), 1); 894 894 if (result) { 895 895 result = -EFAULT; ··· 959 959 */ 960 960 void __noclone __crash_kexec(struct pt_regs *regs) 961 961 { 962 - /* Take the kexec_mutex here to prevent sys_kexec_load 962 + /* Take the kexec_lock here to prevent sys_kexec_load 963 963 * running on one cpu from replacing the crash kernel 964 964 * we are using after a panic on a different cpu. 965 965 * ··· 967 967 * of memory the xchg(&kexec_crash_image) would be 968 968 * sufficient. But since I reuse the memory... 969 969 */ 970 - if (mutex_trylock(&kexec_mutex)) { 970 + if (kexec_trylock()) { 971 971 if (kexec_crash_image) { 972 972 struct pt_regs fixed_regs; 973 973 ··· 976 976 machine_crash_shutdown(&fixed_regs); 977 977 machine_kexec(kexec_crash_image); 978 978 } 979 - mutex_unlock(&kexec_mutex); 979 + kexec_unlock(); 980 980 } 981 981 } 982 982 STACK_FRAME_NON_STANDARD(__crash_kexec); ··· 1004 1004 } 1005 1005 } 1006 1006 1007 - size_t crash_get_memory_size(void) 1007 + ssize_t crash_get_memory_size(void) 1008 1008 { 1009 - size_t size = 0; 1009 + ssize_t size = 0; 1010 1010 1011 - mutex_lock(&kexec_mutex); 1011 + if (!kexec_trylock()) 1012 + return -EBUSY; 1013 + 1012 1014 if (crashk_res.end != crashk_res.start) 1013 1015 size = resource_size(&crashk_res); 1014 - mutex_unlock(&kexec_mutex); 1016 + 1017 + kexec_unlock(); 1015 1018 return size; 1016 1019 } 1017 1020 ··· 1025 1022 unsigned long old_size; 1026 1023 struct resource *ram_res; 1027 1024 1028 - mutex_lock(&kexec_mutex); 1025 + if (!kexec_trylock()) 1026 + return -EBUSY; 1029 1027 1030 1028 if (kexec_crash_image) { 1031 1029 ret = -ENOENT; ··· 1064 1060 insert_resource(&iomem_resource, ram_res); 1065 1061 1066 1062 unlock: 1067 - mutex_unlock(&kexec_mutex); 1063 + kexec_unlock(); 1068 1064 return ret; 1069 1065 } 1070 1066 ··· 1136 1132 { 1137 1133 int error = 0; 1138 1134 1139 - if (!mutex_trylock(&kexec_mutex)) 1135 + if (!kexec_trylock()) 1140 1136 return -EBUSY; 1141 1137 if (!kexec_image) { 1142 1138 error = -EINVAL; ··· 1212 1208 #endif 1213 1209 1214 1210 Unlock: 1215 - mutex_unlock(&kexec_mutex); 1211 + kexec_unlock(); 1216 1212 return error; 1217 1213 }
+2 -2
kernel/kexec_file.c
··· 339 339 340 340 image = NULL; 341 341 342 - if (!mutex_trylock(&kexec_mutex)) 342 + if (!kexec_trylock()) 343 343 return -EBUSY; 344 344 345 345 dest_image = &kexec_image; ··· 411 411 if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image) 412 412 arch_kexec_protect_crashkres(); 413 413 414 - mutex_unlock(&kexec_mutex); 414 + kexec_unlock(); 415 415 kimage_free(image); 416 416 return ret; 417 417 }
+14 -1
kernel/kexec_internal.h
··· 13 13 int kimage_is_destination_range(struct kimage *image, 14 14 unsigned long start, unsigned long end); 15 15 16 - extern struct mutex kexec_mutex; 16 + /* 17 + * Whatever is used to serialize accesses to the kexec_crash_image needs to be 18 + * NMI safe, as __crash_kexec() can happen during nmi_panic(), so here we use a 19 + * "simple" atomic variable that is acquired with a cmpxchg(). 20 + */ 21 + extern atomic_t __kexec_lock; 22 + static inline bool kexec_trylock(void) 23 + { 24 + return atomic_cmpxchg_acquire(&__kexec_lock, 0, 1) == 0; 25 + } 26 + static inline void kexec_unlock(void) 27 + { 28 + atomic_set_release(&__kexec_lock, 0); 29 + } 17 30 18 31 #ifdef CONFIG_KEXEC_FILE 19 32 #include <linux/purgatory.h>
+6 -1
kernel/ksysfs.c
··· 105 105 static ssize_t kexec_crash_size_show(struct kobject *kobj, 106 106 struct kobj_attribute *attr, char *buf) 107 107 { 108 - return sprintf(buf, "%zu\n", crash_get_memory_size()); 108 + ssize_t size = crash_get_memory_size(); 109 + 110 + if (size < 0) 111 + return size; 112 + 113 + return sprintf(buf, "%zd\n", size); 109 114 } 110 115 static ssize_t kexec_crash_size_store(struct kobject *kobj, 111 116 struct kobj_attribute *attr,
+2 -2
kernel/latencytop.c
··· 112 112 account_global_scheduler_latency(struct task_struct *tsk, 113 113 struct latency_record *lat) 114 114 { 115 - int firstnonnull = MAXLR + 1; 115 + int firstnonnull = MAXLR; 116 116 int i; 117 117 118 118 /* skip kernel threads for now */ ··· 150 150 } 151 151 152 152 i = firstnonnull; 153 - if (i >= MAXLR - 1) 153 + if (i >= MAXLR) 154 154 return; 155 155 156 156 /* Allocted a new one: */
+14 -18
kernel/profile.c
··· 59 59 static const char schedstr[] = "schedule"; 60 60 static const char sleepstr[] = "sleep"; 61 61 static const char kvmstr[] = "kvm"; 62 + const char *select = NULL; 62 63 int par; 63 64 64 65 if (!strncmp(str, sleepstr, strlen(sleepstr))) { 65 66 #ifdef CONFIG_SCHEDSTATS 66 67 force_schedstat_enabled(); 67 68 prof_on = SLEEP_PROFILING; 68 - if (str[strlen(sleepstr)] == ',') 69 - str += strlen(sleepstr) + 1; 70 - if (get_option(&str, &par)) 71 - prof_shift = clamp(par, 0, BITS_PER_LONG - 1); 72 - pr_info("kernel sleep profiling enabled (shift: %u)\n", 73 - prof_shift); 69 + select = sleepstr; 74 70 #else 75 71 pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n"); 76 72 #endif /* CONFIG_SCHEDSTATS */ 77 73 } else if (!strncmp(str, schedstr, strlen(schedstr))) { 78 74 prof_on = SCHED_PROFILING; 79 - if (str[strlen(schedstr)] == ',') 80 - str += strlen(schedstr) + 1; 81 - if (get_option(&str, &par)) 82 - prof_shift = clamp(par, 0, BITS_PER_LONG - 1); 83 - pr_info("kernel schedule profiling enabled (shift: %u)\n", 84 - prof_shift); 75 + select = schedstr; 85 76 } else if (!strncmp(str, kvmstr, strlen(kvmstr))) { 86 77 prof_on = KVM_PROFILING; 87 - if (str[strlen(kvmstr)] == ',') 88 - str += strlen(kvmstr) + 1; 89 - if (get_option(&str, &par)) 90 - prof_shift = clamp(par, 0, BITS_PER_LONG - 1); 91 - pr_info("kernel KVM profiling enabled (shift: %u)\n", 92 - prof_shift); 78 + select = kvmstr; 93 79 } else if (get_option(&str, &par)) { 94 80 prof_shift = clamp(par, 0, BITS_PER_LONG - 1); 95 81 prof_on = CPU_PROFILING; 96 82 pr_info("kernel profiling enabled (shift: %u)\n", 97 83 prof_shift); 98 84 } 85 + 86 + if (select) { 87 + if (str[strlen(select)] == ',') 88 + str += strlen(select) + 1; 89 + if (get_option(&str, &par)) 90 + prof_shift = clamp(par, 0, BITS_PER_LONG - 1); 91 + pr_info("kernel %s profiling enabled (shift: %u)\n", 92 + select, prof_shift); 93 + } 94 + 99 95 return 1; 100 96 } 101 97 __setup("profile=", profile_setup);
+1 -4
kernel/relay.c
··· 60 60 */ 61 61 static struct page **relay_alloc_page_array(unsigned int n_pages) 62 62 { 63 - const size_t pa_size = n_pages * sizeof(struct page *); 64 - if (pa_size > PAGE_SIZE) 65 - return vzalloc(pa_size); 66 - return kzalloc(pa_size, GFP_KERNEL); 63 + return kvcalloc(n_pages, sizeof(struct page *), GFP_KERNEL); 67 64 } 68 65 69 66 /*
+8 -7
kernel/smpboot.c
··· 433 433 434 434 /* The outgoing CPU will normally get done quite quickly. */ 435 435 if (atomic_read(&per_cpu(cpu_hotplug_state, cpu)) == CPU_DEAD) 436 - goto update_state; 436 + goto update_state_early; 437 437 udelay(5); 438 438 439 439 /* But if the outgoing CPU dawdles, wait increasingly long times. */ ··· 444 444 break; 445 445 sleep_jf = DIV_ROUND_UP(sleep_jf * 11, 10); 446 446 } 447 - update_state: 447 + update_state_early: 448 448 oldstate = atomic_read(&per_cpu(cpu_hotplug_state, cpu)); 449 + update_state: 449 450 if (oldstate == CPU_DEAD) { 450 451 /* Outgoing CPU died normally, update state. */ 451 452 smp_mb(); /* atomic_read() before update. */ 452 453 atomic_set(&per_cpu(cpu_hotplug_state, cpu), CPU_POST_DEAD); 453 454 } else { 454 455 /* Outgoing CPU still hasn't died, set state accordingly. */ 455 - if (atomic_cmpxchg(&per_cpu(cpu_hotplug_state, cpu), 456 - oldstate, CPU_BROKEN) != oldstate) 456 + if (!atomic_try_cmpxchg(&per_cpu(cpu_hotplug_state, cpu), 457 + &oldstate, CPU_BROKEN)) 457 458 goto update_state; 458 459 ret = false; 459 460 } ··· 476 475 int newstate; 477 476 int cpu = smp_processor_id(); 478 477 478 + oldstate = atomic_read(&per_cpu(cpu_hotplug_state, cpu)); 479 479 do { 480 - oldstate = atomic_read(&per_cpu(cpu_hotplug_state, cpu)); 481 480 if (oldstate != CPU_BROKEN) 482 481 newstate = CPU_DEAD; 483 482 else 484 483 newstate = CPU_DEAD_FROZEN; 485 - } while (atomic_cmpxchg(&per_cpu(cpu_hotplug_state, cpu), 486 - oldstate, newstate) != oldstate); 484 + } while (!atomic_try_cmpxchg(&per_cpu(cpu_hotplug_state, cpu), 485 + &oldstate, newstate)); 487 486 return newstate == CPU_DEAD; 488 487 } 489 488
+9 -7
kernel/task_work.c
··· 47 47 /* record the work call stack in order to print it in KASAN reports */ 48 48 kasan_record_aux_stack(work); 49 49 50 + head = READ_ONCE(task->task_works); 50 51 do { 51 - head = READ_ONCE(task->task_works); 52 52 if (unlikely(head == &work_exited)) 53 53 return -ESRCH; 54 54 work->next = head; 55 - } while (cmpxchg(&task->task_works, head, work) != head); 55 + } while (!try_cmpxchg(&task->task_works, &head, work)); 56 56 57 57 switch (notify) { 58 58 case TWA_NONE: ··· 100 100 * we raced with task_work_run(), *pprev == NULL/exited. 101 101 */ 102 102 raw_spin_lock_irqsave(&task->pi_lock, flags); 103 - while ((work = READ_ONCE(*pprev))) { 104 - if (!match(work, data)) 103 + work = READ_ONCE(*pprev); 104 + while (work) { 105 + if (!match(work, data)) { 105 106 pprev = &work->next; 106 - else if (cmpxchg(pprev, work, work->next) == work) 107 + work = READ_ONCE(*pprev); 108 + } else if (try_cmpxchg(pprev, &work, work->next)) 107 109 break; 108 110 } 109 111 raw_spin_unlock_irqrestore(&task->pi_lock, flags); ··· 153 151 * work->func() can do task_work_add(), do not set 154 152 * work_exited unless the list is empty. 155 153 */ 154 + work = READ_ONCE(task->task_works); 156 155 do { 157 156 head = NULL; 158 - work = READ_ONCE(task->task_works); 159 157 if (!work) { 160 158 if (task->flags & PF_EXITING) 161 159 head = &work_exited; 162 160 else 163 161 break; 164 162 } 165 - } while (cmpxchg(&task->task_works, work, head) != work); 163 + } while (!try_cmpxchg(&task->task_works, &work, head)); 166 164 167 165 if (!work) 168 166 break;
+7
kernel/utsname_sysctl.c
··· 76 76 77 77 static struct ctl_table uts_kern_table[] = { 78 78 { 79 + .procname = "arch", 80 + .data = init_uts_ns.name.machine, 81 + .maxlen = sizeof(init_uts_ns.name.machine), 82 + .mode = 0444, 83 + .proc_handler = proc_do_uts_string, 84 + }, 85 + { 79 86 .procname = "ostype", 80 87 .data = init_uts_ns.name.sysname, 81 88 .maxlen = sizeof(init_uts_ns.name.sysname),
+1 -1
lib/cmdline.c
··· 260 260 args[i-1] = '\0'; 261 261 } 262 262 } 263 - if (quoted && args[i-1] == '"') 263 + if (quoted && i > 0 && args[i-1] == '"') 264 264 args[i-1] = '\0'; 265 265 266 266 if (args[i]) {
+1 -1
lib/earlycpio.c
··· 126 126 "File %s exceeding MAX_CPIO_FILE_NAME [%d]\n", 127 127 p, MAX_CPIO_FILE_NAME); 128 128 } 129 - strlcpy(cd.name, p + mypathsize, MAX_CPIO_FILE_NAME); 129 + strscpy(cd.name, p + mypathsize, MAX_CPIO_FILE_NAME); 130 130 131 131 cd.data = (void *)dptr; 132 132 cd.size = ch[C_FILESIZE];
+4 -8
lib/llist.c
··· 30 30 31 31 do { 32 32 new_last->next = first = READ_ONCE(head->first); 33 - } while (cmpxchg(&head->first, first, new_first) != first); 33 + } while (!try_cmpxchg(&head->first, &first, new_first)); 34 34 35 35 return !first; 36 36 } ··· 52 52 */ 53 53 struct llist_node *llist_del_first(struct llist_head *head) 54 54 { 55 - struct llist_node *entry, *old_entry, *next; 55 + struct llist_node *entry, *next; 56 56 57 57 entry = smp_load_acquire(&head->first); 58 - for (;;) { 58 + do { 59 59 if (entry == NULL) 60 60 return NULL; 61 - old_entry = entry; 62 61 next = READ_ONCE(entry->next); 63 - entry = cmpxchg(&head->first, old_entry, next); 64 - if (entry == old_entry) 65 - break; 66 - } 62 + } while (!try_cmpxchg(&head->first, &entry, next)); 67 63 68 64 return entry; 69 65 }
+51 -1
scripts/checkpatch.pl
··· 576 576 (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 577 577 atomic_t 578 578 )}; 579 + our $typeStdioTypedefs = qr{(?x: 580 + FILE 581 + )}; 579 582 our $typeTypedefs = qr{(?x: 580 583 $typeC99Typedefs\b| 581 584 $typeOtherOSTypedefs\b| 582 - $typeKernelTypedefs\b 585 + $typeKernelTypedefs\b| 586 + $typeStdioTypedefs\b 583 587 )}; 584 588 585 589 our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; ··· 811 807 "rcu_barrier_sched" => "rcu_barrier", 812 808 "get_state_synchronize_sched" => "get_state_synchronize_rcu", 813 809 "cond_synchronize_sched" => "cond_synchronize_rcu", 810 + "kmap" => "kmap_local_page", 811 + "kmap_atomic" => "kmap_local_page", 814 812 ); 815 813 816 814 #Create a search pattern for all these strings to speed up a loop below ··· 3142 3136 } elsif ($1 ne $email) { 3143 3137 WARN("BAD_SIGN_OFF", 3144 3138 "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 3139 + } 3140 + } 3141 + } 3142 + 3143 + # Check Fixes: styles is correct 3144 + if (!$in_header_lines && 3145 + $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { 3146 + my $orig_commit = ""; 3147 + my $id = "0123456789ab"; 3148 + my $title = "commit title"; 3149 + my $tag_case = 1; 3150 + my $tag_space = 1; 3151 + my $id_length = 1; 3152 + my $id_case = 1; 3153 + my $title_has_quotes = 0; 3154 + 3155 + if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { 3156 + my $tag = $1; 3157 + $orig_commit = $2; 3158 + $title = $3; 3159 + 3160 + $tag_case = 0 if $tag eq "Fixes:"; 3161 + $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); 3162 + 3163 + $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); 3164 + $id_case = 0 if ($orig_commit !~ /[A-F]/); 3165 + 3166 + # Always strip leading/trailing parens then double quotes if existing 3167 + $title = substr($title, 1, -1); 3168 + if ($title =~ /^".*"$/) { 3169 + $title = substr($title, 1, -1); 3170 + $title_has_quotes = 1; 3171 + } 3172 + } 3173 + 3174 + my ($cid, $ctitle) = git_commit_info($orig_commit, $id, 3175 + $title); 3176 + 3177 + if ($ctitle ne $title || $tag_case || $tag_space || 3178 + $id_length || $id_case || !$title_has_quotes) { 3179 + if (WARN("BAD_FIXES_TAG", 3180 + "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) && 3181 + $fix) { 3182 + $fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")"; 3145 3183 } 3146 3184 } 3147 3185 }
+108 -18
scripts/decodecode
··· 1 - #!/bin/sh 1 + #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # Disassemble the Code: line in Linux oopses 4 4 # usage: decodecode < oops.file ··· 7 7 # e.g., to decode an i386 oops on an x86_64 system, use: 8 8 # AFLAGS=--32 decodecode < 386.oops 9 9 # PC=hex - the PC (program counter) the oops points to 10 + 11 + faultlinenum=1 10 12 11 13 cleanup() { 12 14 rm -f $T $T.s $T.o $T.oo $T.aa $T.dis ··· 104 102 grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1 105 103 } 106 104 105 + # Match the maximum number of opcode bytes from @op_bytes contained within 106 + # @opline 107 + # 108 + # Params: 109 + # @op_bytes: The string of bytes from the Code: line 110 + # @opline: The disassembled line coming from objdump 111 + # 112 + # Returns: 113 + # The max number of opcode bytes from the beginning of @op_bytes which match 114 + # the opcode bytes in the objdump line. 115 + get_substr_opcode_bytes_num() 116 + { 117 + local op_bytes=$1 118 + local opline=$2 119 + 120 + local retval=0 121 + substr="" 122 + 123 + for opc in $op_bytes; 124 + do 125 + substr+="$opc" 126 + 127 + # return if opcode bytes do not match @opline anymore 128 + if ! echo $opline | grep -q "$substr"; 129 + then 130 + break 131 + fi 132 + 133 + # add trailing space 134 + substr+=" " 135 + retval=$((retval+1)) 136 + done 137 + 138 + return $retval 139 + } 140 + 141 + # Return the line number in objdump output to where the IP marker in the Code: 142 + # line points to 143 + # 144 + # Params: 145 + # @all_code: code in bytes without the marker 146 + # @dis_file: disassembled file 147 + # @ip_byte: The byte to which the IP points to 148 + get_faultlinenum() 149 + { 150 + local all_code="$1" 151 + local dis_file="$2" 152 + 153 + # num bytes including IP byte 154 + local num_bytes_ip=$(( $3 + 1 * $width )) 155 + 156 + # Add the two header lines (we're counting from 1). 157 + local retval=3 158 + 159 + # remove marker 160 + all_code=$(echo $all_code | sed -e 's/[<>()]//g') 161 + 162 + while read line 163 + do 164 + get_substr_opcode_bytes_num "$all_code" "$line" 165 + ate_opcodes=$? 166 + 167 + if ! (( $ate_opcodes )); then 168 + continue 169 + fi 170 + 171 + num_bytes_ip=$((num_bytes_ip - ($ate_opcodes * $width) )) 172 + if (( $num_bytes_ip <= 0 )); then 173 + break 174 + fi 175 + 176 + # Delete matched opcode bytes from all_code. For that, compute 177 + # how many chars those opcodes are represented by and include 178 + # trailing space. 179 + # 180 + # a byte is 2 chars, ate_opcodes is also the number of trailing 181 + # spaces 182 + del_chars=$(( ($ate_opcodes * $width * 2) + $ate_opcodes )) 183 + 184 + all_code=$(echo $all_code | sed -e "s!^.\{$del_chars\}!!") 185 + 186 + let "retval+=1" 187 + 188 + done < $dis_file 189 + 190 + return $retval 191 + } 192 + 107 193 marker=`expr index "$code" "\<"` 108 194 if [ $marker -eq 0 ]; then 109 195 marker=`expr index "$code" "\("` 110 196 fi 111 197 112 - 113 198 touch $T.oo 114 199 if [ $marker -ne 0 ]; then 115 - # 2 opcode bytes and a single space 116 - pc_sub=$(( $marker / 3 )) 200 + # How many bytes to subtract from the program counter 201 + # in order to get to the beginning virtual address of the 202 + # Code: 203 + pc_sub=$(( (($marker - 1) / (2 * $width + 1)) * $width )) 117 204 echo All code >> $T.oo 118 205 echo ======== >> $T.oo 119 206 beforemark=`echo "$code"` 120 207 echo -n " .$type 0x" > $T.s 121 - echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s 122 - disas $T $pc_sub 123 - cat $T.dis >> $T.oo 124 - rm -f $T.o $T.s $T.dis 125 208 126 - # and fix code at-and-after marker 209 + echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s 210 + 211 + disas $T $pc_sub 212 + 213 + cat $T.dis >> $T.oo 214 + 215 + get_faultlinenum "$code" "$T.dis" $pc_sub 216 + faultlinenum=$? 217 + 218 + # and fix code at-and-after marker 127 219 code=`echo "$code" | cut -c$((${marker} + 1))-` 220 + 221 + rm -f $T.o $T.s $T.dis 128 222 fi 223 + 129 224 echo Code starting with the faulting instruction > $T.aa 130 225 echo =========================================== >> $T.aa 131 226 code=`echo $code | sed -e 's/\r//;s/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'` ··· 230 131 echo $code >> $T.s 231 132 disas $T 0 232 133 cat $T.dis >> $T.aa 233 - 234 - # (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3, 235 - # i.e. the title + the "===..=" line (sed is counting from 1, 0 address is 236 - # special) 237 - faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ 238 - $(wc -l $T.aa | cut -d" " -f1) + 3)) 239 - 240 - faultline=`cat $T.dis | head -1 | cut -d":" -f2-` 241 - faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` 242 134 243 135 cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" 244 136 echo
+1
tools/testing/selftests/proc/.gitignore
··· 5 5 /proc-fsconfig-hidepid 6 6 /proc-loadavg-001 7 7 /proc-multiple-procfs 8 + /proc-empty-vm 8 9 /proc-pid-vm 9 10 /proc-self-map-files-001 10 11 /proc-self-map-files-002
+1
tools/testing/selftests/proc/Makefile
··· 8 8 TEST_GEN_PROGS += fd-002-posix-eq 9 9 TEST_GEN_PROGS += fd-003-kthread 10 10 TEST_GEN_PROGS += proc-loadavg-001 11 + TEST_GEN_PROGS += proc-empty-vm 11 12 TEST_GEN_PROGS += proc-pid-vm 12 13 TEST_GEN_PROGS += proc-self-map-files-001 13 14 TEST_GEN_PROGS += proc-self-map-files-002
+386
tools/testing/selftests/proc/proc-empty-vm.c
··· 1 + /* 2 + * Copyright (c) 2022 Alexey Dobriyan <adobriyan@gmail.com> 3 + * 4 + * Permission to use, copy, modify, and distribute this software for any 5 + * purpose with or without fee is hereby granted, provided that the above 6 + * copyright notice and this permission notice appear in all copies. 7 + * 8 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 + */ 16 + /* 17 + * Create a process without mappings by unmapping everything at once and 18 + * holding it with ptrace(2). See what happens to 19 + * 20 + * /proc/${pid}/maps 21 + * /proc/${pid}/numa_maps 22 + * /proc/${pid}/smaps 23 + * /proc/${pid}/smaps_rollup 24 + */ 25 + #undef NDEBUG 26 + #include <assert.h> 27 + #include <errno.h> 28 + #include <stdio.h> 29 + #include <stdlib.h> 30 + #include <string.h> 31 + #include <fcntl.h> 32 + #include <sys/mman.h> 33 + #include <sys/ptrace.h> 34 + #include <sys/resource.h> 35 + #include <sys/types.h> 36 + #include <sys/wait.h> 37 + #include <unistd.h> 38 + 39 + /* 40 + * 0: vsyscall VMA doesn't exist vsyscall=none 41 + * 1: vsyscall VMA is --xp vsyscall=xonly 42 + * 2: vsyscall VMA is r-xp vsyscall=emulate 43 + */ 44 + static int g_vsyscall; 45 + static const char *g_proc_pid_maps_vsyscall; 46 + static const char *g_proc_pid_smaps_vsyscall; 47 + 48 + static const char proc_pid_maps_vsyscall_0[] = ""; 49 + static const char proc_pid_maps_vsyscall_1[] = 50 + "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n"; 51 + static const char proc_pid_maps_vsyscall_2[] = 52 + "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; 53 + 54 + static const char proc_pid_smaps_vsyscall_0[] = ""; 55 + 56 + static const char proc_pid_smaps_vsyscall_1[] = 57 + "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n" 58 + "Size: 4 kB\n" 59 + "KernelPageSize: 4 kB\n" 60 + "MMUPageSize: 4 kB\n" 61 + "Rss: 0 kB\n" 62 + "Pss: 0 kB\n" 63 + "Pss_Dirty: 0 kB\n" 64 + "Shared_Clean: 0 kB\n" 65 + "Shared_Dirty: 0 kB\n" 66 + "Private_Clean: 0 kB\n" 67 + "Private_Dirty: 0 kB\n" 68 + "Referenced: 0 kB\n" 69 + "Anonymous: 0 kB\n" 70 + "LazyFree: 0 kB\n" 71 + "AnonHugePages: 0 kB\n" 72 + "ShmemPmdMapped: 0 kB\n" 73 + "FilePmdMapped: 0 kB\n" 74 + "Shared_Hugetlb: 0 kB\n" 75 + "Private_Hugetlb: 0 kB\n" 76 + "Swap: 0 kB\n" 77 + "SwapPss: 0 kB\n" 78 + "Locked: 0 kB\n" 79 + "THPeligible: 0\n" 80 + /* 81 + * "ProtectionKey:" field is conditional. It is possible to check it as well, 82 + * but I don't have such machine. 83 + */ 84 + ; 85 + 86 + static const char proc_pid_smaps_vsyscall_2[] = 87 + "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n" 88 + "Size: 4 kB\n" 89 + "KernelPageSize: 4 kB\n" 90 + "MMUPageSize: 4 kB\n" 91 + "Rss: 0 kB\n" 92 + "Pss: 0 kB\n" 93 + "Pss_Dirty: 0 kB\n" 94 + "Shared_Clean: 0 kB\n" 95 + "Shared_Dirty: 0 kB\n" 96 + "Private_Clean: 0 kB\n" 97 + "Private_Dirty: 0 kB\n" 98 + "Referenced: 0 kB\n" 99 + "Anonymous: 0 kB\n" 100 + "LazyFree: 0 kB\n" 101 + "AnonHugePages: 0 kB\n" 102 + "ShmemPmdMapped: 0 kB\n" 103 + "FilePmdMapped: 0 kB\n" 104 + "Shared_Hugetlb: 0 kB\n" 105 + "Private_Hugetlb: 0 kB\n" 106 + "Swap: 0 kB\n" 107 + "SwapPss: 0 kB\n" 108 + "Locked: 0 kB\n" 109 + "THPeligible: 0\n" 110 + /* 111 + * "ProtectionKey:" field is conditional. It is possible to check it as well, 112 + * but I'm too tired. 113 + */ 114 + ; 115 + 116 + static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___) 117 + { 118 + _exit(EXIT_FAILURE); 119 + } 120 + 121 + static void sigaction_SIGSEGV_vsyscall(int _, siginfo_t *__, void *___) 122 + { 123 + _exit(g_vsyscall); 124 + } 125 + 126 + /* 127 + * vsyscall page can't be unmapped, probe it directly. 128 + */ 129 + static void vsyscall(void) 130 + { 131 + pid_t pid; 132 + int wstatus; 133 + 134 + pid = fork(); 135 + if (pid < 0) { 136 + fprintf(stderr, "fork, errno %d\n", errno); 137 + exit(1); 138 + } 139 + if (pid == 0) { 140 + setrlimit(RLIMIT_CORE, &(struct rlimit){}); 141 + 142 + /* Hide "segfault at ffffffffff600000" messages. */ 143 + struct sigaction act = {}; 144 + act.sa_flags = SA_SIGINFO; 145 + act.sa_sigaction = sigaction_SIGSEGV_vsyscall; 146 + sigaction(SIGSEGV, &act, NULL); 147 + 148 + g_vsyscall = 0; 149 + /* gettimeofday(NULL, NULL); */ 150 + asm volatile ( 151 + "call %P0" 152 + : 153 + : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) 154 + : "rax", "rcx", "r11" 155 + ); 156 + 157 + g_vsyscall = 1; 158 + *(volatile int *)0xffffffffff600000UL; 159 + 160 + g_vsyscall = 2; 161 + exit(g_vsyscall); 162 + } 163 + waitpid(pid, &wstatus, 0); 164 + if (WIFEXITED(wstatus)) { 165 + g_vsyscall = WEXITSTATUS(wstatus); 166 + } else { 167 + fprintf(stderr, "error: vsyscall wstatus %08x\n", wstatus); 168 + exit(1); 169 + } 170 + } 171 + 172 + static int test_proc_pid_maps(pid_t pid) 173 + { 174 + char buf[4096]; 175 + snprintf(buf, sizeof(buf), "/proc/%u/maps", pid); 176 + int fd = open(buf, O_RDONLY); 177 + if (fd == -1) { 178 + perror("open /proc/${pid}/maps"); 179 + return EXIT_FAILURE; 180 + } else { 181 + ssize_t rv = read(fd, buf, sizeof(buf)); 182 + close(fd); 183 + if (g_vsyscall == 0) { 184 + assert(rv == 0); 185 + } else { 186 + size_t len = strlen(g_proc_pid_maps_vsyscall); 187 + assert(rv == len); 188 + assert(memcmp(buf, g_proc_pid_maps_vsyscall, len) == 0); 189 + } 190 + return EXIT_SUCCESS; 191 + } 192 + } 193 + 194 + static int test_proc_pid_numa_maps(pid_t pid) 195 + { 196 + char buf[4096]; 197 + snprintf(buf, sizeof(buf), "/proc/%u/numa_maps", pid); 198 + int fd = open(buf, O_RDONLY); 199 + if (fd == -1) { 200 + if (errno == ENOENT) { 201 + /* 202 + * /proc/${pid}/numa_maps is under CONFIG_NUMA, 203 + * it doesn't necessarily exist. 204 + */ 205 + return EXIT_SUCCESS; 206 + } 207 + perror("open /proc/${pid}/numa_maps"); 208 + return EXIT_FAILURE; 209 + } else { 210 + ssize_t rv = read(fd, buf, sizeof(buf)); 211 + close(fd); 212 + assert(rv == 0); 213 + return EXIT_SUCCESS; 214 + } 215 + } 216 + 217 + static int test_proc_pid_smaps(pid_t pid) 218 + { 219 + char buf[4096]; 220 + snprintf(buf, sizeof(buf), "/proc/%u/smaps", pid); 221 + int fd = open(buf, O_RDONLY); 222 + if (fd == -1) { 223 + if (errno == ENOENT) { 224 + /* 225 + * /proc/${pid}/smaps is under CONFIG_PROC_PAGE_MONITOR, 226 + * it doesn't necessarily exist. 227 + */ 228 + return EXIT_SUCCESS; 229 + } 230 + perror("open /proc/${pid}/smaps"); 231 + return EXIT_FAILURE; 232 + } else { 233 + ssize_t rv = read(fd, buf, sizeof(buf)); 234 + close(fd); 235 + if (g_vsyscall == 0) { 236 + assert(rv == 0); 237 + } else { 238 + size_t len = strlen(g_proc_pid_maps_vsyscall); 239 + /* TODO "ProtectionKey:" */ 240 + assert(rv > len); 241 + assert(memcmp(buf, g_proc_pid_maps_vsyscall, len) == 0); 242 + } 243 + return EXIT_SUCCESS; 244 + } 245 + } 246 + 247 + static const char g_smaps_rollup[] = 248 + "00000000-00000000 ---p 00000000 00:00 0 [rollup]\n" 249 + "Rss: 0 kB\n" 250 + "Pss: 0 kB\n" 251 + "Pss_Dirty: 0 kB\n" 252 + "Pss_Anon: 0 kB\n" 253 + "Pss_File: 0 kB\n" 254 + "Pss_Shmem: 0 kB\n" 255 + "Shared_Clean: 0 kB\n" 256 + "Shared_Dirty: 0 kB\n" 257 + "Private_Clean: 0 kB\n" 258 + "Private_Dirty: 0 kB\n" 259 + "Referenced: 0 kB\n" 260 + "Anonymous: 0 kB\n" 261 + "LazyFree: 0 kB\n" 262 + "AnonHugePages: 0 kB\n" 263 + "ShmemPmdMapped: 0 kB\n" 264 + "FilePmdMapped: 0 kB\n" 265 + "Shared_Hugetlb: 0 kB\n" 266 + "Private_Hugetlb: 0 kB\n" 267 + "Swap: 0 kB\n" 268 + "SwapPss: 0 kB\n" 269 + "Locked: 0 kB\n" 270 + ; 271 + 272 + static int test_proc_pid_smaps_rollup(pid_t pid) 273 + { 274 + char buf[4096]; 275 + snprintf(buf, sizeof(buf), "/proc/%u/smaps_rollup", pid); 276 + int fd = open(buf, O_RDONLY); 277 + if (fd == -1) { 278 + if (errno == ENOENT) { 279 + /* 280 + * /proc/${pid}/smaps_rollup is under CONFIG_PROC_PAGE_MONITOR, 281 + * it doesn't necessarily exist. 282 + */ 283 + return EXIT_SUCCESS; 284 + } 285 + perror("open /proc/${pid}/smaps_rollup"); 286 + return EXIT_FAILURE; 287 + } else { 288 + ssize_t rv = read(fd, buf, sizeof(buf)); 289 + close(fd); 290 + assert(rv == sizeof(g_smaps_rollup) - 1); 291 + assert(memcmp(buf, g_smaps_rollup, sizeof(g_smaps_rollup) - 1) == 0); 292 + return EXIT_SUCCESS; 293 + } 294 + } 295 + 296 + int main(void) 297 + { 298 + int rv = EXIT_SUCCESS; 299 + 300 + vsyscall(); 301 + 302 + switch (g_vsyscall) { 303 + case 0: 304 + g_proc_pid_maps_vsyscall = proc_pid_maps_vsyscall_0; 305 + g_proc_pid_smaps_vsyscall = proc_pid_smaps_vsyscall_0; 306 + break; 307 + case 1: 308 + g_proc_pid_maps_vsyscall = proc_pid_maps_vsyscall_1; 309 + g_proc_pid_smaps_vsyscall = proc_pid_smaps_vsyscall_1; 310 + break; 311 + case 2: 312 + g_proc_pid_maps_vsyscall = proc_pid_maps_vsyscall_2; 313 + g_proc_pid_smaps_vsyscall = proc_pid_smaps_vsyscall_2; 314 + break; 315 + default: 316 + abort(); 317 + } 318 + 319 + pid_t pid = fork(); 320 + if (pid == -1) { 321 + perror("fork"); 322 + return EXIT_FAILURE; 323 + } else if (pid == 0) { 324 + rv = ptrace(PTRACE_TRACEME, 0, NULL, NULL); 325 + if (rv != 0) { 326 + if (errno == EPERM) { 327 + fprintf(stderr, 328 + "Did you know? ptrace(PTRACE_TRACEME) doesn't work under strace.\n" 329 + ); 330 + kill(getppid(), SIGTERM); 331 + return EXIT_FAILURE; 332 + } 333 + perror("ptrace PTRACE_TRACEME"); 334 + return EXIT_FAILURE; 335 + } 336 + 337 + /* 338 + * Hide "segfault at ..." messages. Signal handler won't run. 339 + */ 340 + struct sigaction act = {}; 341 + act.sa_flags = SA_SIGINFO; 342 + act.sa_sigaction = sigaction_SIGSEGV; 343 + sigaction(SIGSEGV, &act, NULL); 344 + 345 + #ifdef __amd64__ 346 + munmap(NULL, ((size_t)1 << 47) - 4096); 347 + #else 348 + #error "implement 'unmap everything'" 349 + #endif 350 + return EXIT_FAILURE; 351 + } else { 352 + /* 353 + * TODO find reliable way to signal parent that munmap(2) completed. 354 + * Child can't do it directly because it effectively doesn't exist 355 + * anymore. Looking at child's VM files isn't 100% reliable either: 356 + * due to a bug they may not become empty or empty-like. 357 + */ 358 + sleep(1); 359 + 360 + if (rv == EXIT_SUCCESS) { 361 + rv = test_proc_pid_maps(pid); 362 + } 363 + if (rv == EXIT_SUCCESS) { 364 + rv = test_proc_pid_numa_maps(pid); 365 + } 366 + if (rv == EXIT_SUCCESS) { 367 + rv = test_proc_pid_smaps(pid); 368 + } 369 + if (rv == EXIT_SUCCESS) { 370 + rv = test_proc_pid_smaps_rollup(pid); 371 + } 372 + /* 373 + * TODO test /proc/${pid}/statm, task_statm() 374 + * ->start_code, ->end_code aren't updated by munmap(). 375 + * Output can be "0 0 0 2 0 0 0\n" where "2" can be anything. 376 + */ 377 + 378 + /* Cut the rope. */ 379 + int wstatus; 380 + waitpid(pid, &wstatus, 0); 381 + assert(WIFSTOPPED(wstatus)); 382 + assert(WSTOPSIG(wstatus) == SIGSEGV); 383 + } 384 + 385 + return rv; 386 + }
+16 -40
tools/testing/selftests/proc/proc-pid-vm.c
··· 213 213 214 214 /* 215 215 * 0: vsyscall VMA doesn't exist vsyscall=none 216 - * 1: vsyscall VMA is r-xp vsyscall=emulate 217 - * 2: vsyscall VMA is --xp vsyscall=xonly 216 + * 1: vsyscall VMA is --xp vsyscall=xonly 217 + * 2: vsyscall VMA is r-xp vsyscall=emulate 218 218 */ 219 - static int g_vsyscall; 219 + static volatile int g_vsyscall; 220 220 static const char *str_vsyscall; 221 221 222 222 static const char str_vsyscall_0[] = ""; 223 223 static const char str_vsyscall_1[] = 224 - "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; 225 - static const char str_vsyscall_2[] = 226 224 "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n"; 225 + static const char str_vsyscall_2[] = 226 + "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; 227 227 228 228 #ifdef __x86_64__ 229 229 static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___) 230 230 { 231 - _exit(1); 231 + _exit(g_vsyscall); 232 232 } 233 233 234 234 /* ··· 255 255 act.sa_sigaction = sigaction_SIGSEGV; 256 256 (void)sigaction(SIGSEGV, &act, NULL); 257 257 258 + g_vsyscall = 0; 258 259 /* gettimeofday(NULL, NULL); */ 259 260 asm volatile ( 260 261 "call %P0" ··· 263 262 : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) 264 263 : "rax", "rcx", "r11" 265 264 ); 266 - exit(0); 265 + 266 + g_vsyscall = 1; 267 + *(volatile int *)0xffffffffff600000UL; 268 + 269 + g_vsyscall = 2; 270 + exit(g_vsyscall); 267 271 } 268 272 waitpid(pid, &wstatus, 0); 269 - if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) { 270 - /* vsyscall page exists and is executable. */ 273 + if (WIFEXITED(wstatus)) { 274 + g_vsyscall = WEXITSTATUS(wstatus); 271 275 } else { 272 - /* vsyscall page doesn't exist. */ 273 - g_vsyscall = 0; 274 - return; 275 - } 276 - 277 - pid = fork(); 278 - if (pid < 0) { 279 - fprintf(stderr, "fork, errno %d\n", errno); 276 + fprintf(stderr, "error: wstatus %08x\n", wstatus); 280 277 exit(1); 281 278 } 282 - if (pid == 0) { 283 - struct rlimit rlim = {0, 0}; 284 - (void)setrlimit(RLIMIT_CORE, &rlim); 285 - 286 - /* Hide "segfault at ffffffffff600000" messages. */ 287 - struct sigaction act; 288 - memset(&act, 0, sizeof(struct sigaction)); 289 - act.sa_flags = SA_SIGINFO; 290 - act.sa_sigaction = sigaction_SIGSEGV; 291 - (void)sigaction(SIGSEGV, &act, NULL); 292 - 293 - *(volatile int *)0xffffffffff600000UL; 294 - exit(0); 295 - } 296 - waitpid(pid, &wstatus, 0); 297 - if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) { 298 - /* vsyscall page is readable and executable. */ 299 - g_vsyscall = 1; 300 - return; 301 - } 302 - 303 - /* vsyscall page is executable but unreadable. */ 304 - g_vsyscall = 2; 305 279 } 306 280 307 281 int main(void)
+1 -1
usr/gen_init_cpio.c
··· 326 326 char s[256]; 327 327 struct stat buf; 328 328 unsigned long size; 329 - int file = -1; 329 + int file; 330 330 int retval; 331 331 int rc = -1; 332 332 int namesize;