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

Configure Feed

Select the types of activity you want to include in your feed.

x86/fpu, sched: Introduce CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT and use it on x86

Don't burden architectures without dynamic task_struct sizing
with the overhead of dynamic sizing.

Also optimize the x86 code a bit by caching task_struct_size.

Acked-and-Tested-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave@sr71.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1437128892-9831-3-git-send-email-mingo@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+27 -18
+4
arch/Kconfig
··· 221 221 config ARCH_THREAD_INFO_ALLOCATOR 222 222 bool 223 223 224 + # Select if arch wants to size task_struct dynamically via arch_task_struct_size: 225 + config ARCH_WANTS_DYNAMIC_TASK_STRUCT 226 + bool 227 + 224 228 config HAVE_REGS_AND_STACK_ACCESS_API 225 229 bool 226 230 help
+1
arch/x86/Kconfig
··· 41 41 select ARCH_USE_CMPXCHG_LOCKREF if X86_64 42 42 select ARCH_USE_QUEUED_RWLOCKS 43 43 select ARCH_USE_QUEUED_SPINLOCKS 44 + select ARCH_WANTS_DYNAMIC_TASK_STRUCT 44 45 select ARCH_WANT_FRAME_POINTERS 45 46 select ARCH_WANT_IPC_PARSE_VERSION if X86_32 46 47 select ARCH_WANT_OPTIONAL_GPIOLIB
+9 -8
arch/x86/kernel/fpu/init.c
··· 4 4 #include <asm/fpu/internal.h> 5 5 #include <asm/tlbflush.h> 6 6 7 + #include <linux/sched.h> 8 + 7 9 /* 8 10 * Initialize the TS bit in CR0 according to the style of context-switches 9 11 * we are using: ··· 138 136 unsigned int xstate_size; 139 137 EXPORT_SYMBOL_GPL(xstate_size); 140 138 141 - #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \ 142 - BUILD_BUG_ON((sizeof(TYPE) - \ 143 - offsetof(TYPE, MEMBER) - \ 144 - sizeof(((TYPE *)0)->MEMBER)) > \ 145 - 0) \ 139 + /* Enforce that 'MEMBER' is the last field of 'TYPE': */ 140 + #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \ 141 + BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER)) 146 142 147 143 /* 148 - * We append the 'struct fpu' to the task_struct. 144 + * We append the 'struct fpu' to the task_struct: 149 145 */ 150 - int __weak arch_task_struct_size(void) 146 + static void __init fpu__init_task_struct_size(void) 151 147 { 152 148 int task_size = sizeof(struct task_struct); 153 149 ··· 172 172 CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu); 173 173 CHECK_MEMBER_AT_END_OF(struct task_struct, thread); 174 174 175 - return task_size; 175 + arch_task_struct_size = task_size; 176 176 } 177 177 178 178 /* ··· 326 326 fpu__init_system_generic(); 327 327 fpu__init_system_xstate_size_legacy(); 328 328 fpu__init_system_xstate(); 329 + fpu__init_task_struct_size(); 329 330 330 331 fpu__init_system_ctx_switch(); 331 332 }
+1 -1
arch/x86/kernel/process.c
··· 81 81 */ 82 82 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 83 83 { 84 - memcpy(dst, src, arch_task_struct_size()); 84 + memcpy(dst, src, arch_task_struct_size); 85 85 86 86 return fpu__copy(&dst->thread.fpu, &src->thread.fpu); 87 87 }
+2 -2
fs/proc/kcore.c
··· 92 92 roundup(sizeof(CORE_STR), 4)) + 93 93 roundup(sizeof(struct elf_prstatus), 4) + 94 94 roundup(sizeof(struct elf_prpsinfo), 4) + 95 - roundup(arch_task_struct_size(), 4); 95 + roundup(arch_task_struct_size, 4); 96 96 *elf_buflen = PAGE_ALIGN(*elf_buflen); 97 97 return size + *elf_buflen; 98 98 } ··· 415 415 /* set up the task structure */ 416 416 notes[2].name = CORE_STR; 417 417 notes[2].type = NT_TASKSTRUCT; 418 - notes[2].datasz = arch_task_struct_size(); 418 + notes[2].datasz = arch_task_struct_size; 419 419 notes[2].data = current; 420 420 421 421 nhdr->p_filesz += notesize(&notes[2]);
+5 -1
include/linux/sched.h
··· 1786 1786 */ 1787 1787 }; 1788 1788 1789 - extern int arch_task_struct_size(void); 1789 + #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT 1790 + extern int arch_task_struct_size __read_mostly; 1791 + #else 1792 + # define arch_task_struct_size (sizeof(struct task_struct)) 1793 + #endif 1790 1794 1791 1795 /* Future-safe accessor for struct task_struct's cpus_allowed. */ 1792 1796 #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
+5 -6
kernel/fork.c
··· 287 287 max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS); 288 288 } 289 289 290 - int __weak arch_task_struct_size(void) 291 - { 292 - return sizeof(struct task_struct); 293 - } 290 + #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT 291 + /* Initialized by the architecture: */ 292 + int arch_task_struct_size __read_mostly; 293 + #endif 294 294 295 295 void __init fork_init(void) 296 296 { 297 - int task_struct_size = arch_task_struct_size(); 298 297 #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR 299 298 #ifndef ARCH_MIN_TASKALIGN 300 299 #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES 301 300 #endif 302 301 /* create a slab on which task_structs can be allocated */ 303 302 task_struct_cachep = 304 - kmem_cache_create("task_struct", task_struct_size, 303 + kmem_cache_create("task_struct", arch_task_struct_size, 305 304 ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL); 306 305 #endif 307 306