Skip to content

Commit 5aaeb5c

Browse files
author
Ingo Molnar
committed
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 <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 0c8c0f0 commit 5aaeb5c

File tree

7 files changed

+27
-18
lines changed

7 files changed

+27
-18
lines changed

arch/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ config ARCH_TASK_STRUCT_ALLOCATOR
221221
config ARCH_THREAD_INFO_ALLOCATOR
222222
bool
223223

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+
224228
config HAVE_REGS_AND_STACK_ACCESS_API
225229
bool
226230
help

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ config X86
4141
select ARCH_USE_CMPXCHG_LOCKREF if X86_64
4242
select ARCH_USE_QUEUED_RWLOCKS
4343
select ARCH_USE_QUEUED_SPINLOCKS
44+
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
4445
select ARCH_WANT_FRAME_POINTERS
4546
select ARCH_WANT_IPC_PARSE_VERSION if X86_32
4647
select ARCH_WANT_OPTIONAL_GPIOLIB

arch/x86/kernel/fpu/init.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <asm/fpu/internal.h>
55
#include <asm/tlbflush.h>
66

7+
#include <linux/sched.h>
8+
79
/*
810
* Initialize the TS bit in CR0 according to the style of context-switches
911
* we are using:
@@ -136,16 +138,14 @@ static void __init fpu__init_system_generic(void)
136138
unsigned int xstate_size;
137139
EXPORT_SYMBOL_GPL(xstate_size);
138140

139-
#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
140-
BUILD_BUG_ON((sizeof(TYPE) - \
141-
offsetof(TYPE, MEMBER) - \
142-
sizeof(((TYPE *)0)->MEMBER)) > \
143-
0) \
141+
/* Enforce that 'MEMBER' is the last field of 'TYPE': */
142+
#define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
143+
BUILD_BUG_ON(sizeof(TYPE) != offsetofend(TYPE, MEMBER))
144144

145145
/*
146-
* We append the 'struct fpu' to the task_struct.
146+
* We append the 'struct fpu' to the task_struct:
147147
*/
148-
int __weak arch_task_struct_size(void)
148+
static void __init fpu__init_task_struct_size(void)
149149
{
150150
int task_size = sizeof(struct task_struct);
151151

@@ -172,7 +172,7 @@ int __weak arch_task_struct_size(void)
172172
CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu);
173173
CHECK_MEMBER_AT_END_OF(struct task_struct, thread);
174174

175-
return task_size;
175+
arch_task_struct_size = task_size;
176176
}
177177

178178
/*
@@ -326,6 +326,7 @@ void __init fpu__init_system(struct cpuinfo_x86 *c)
326326
fpu__init_system_generic();
327327
fpu__init_system_xstate_size_legacy();
328328
fpu__init_system_xstate();
329+
fpu__init_task_struct_size();
329330

330331
fpu__init_system_ctx_switch();
331332
}

arch/x86/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
8181
*/
8282
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
8383
{
84-
memcpy(dst, src, arch_task_struct_size());
84+
memcpy(dst, src, arch_task_struct_size);
8585

8686
return fpu__copy(&dst->thread.fpu, &src->thread.fpu);
8787
}

fs/proc/kcore.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen)
9292
roundup(sizeof(CORE_STR), 4)) +
9393
roundup(sizeof(struct elf_prstatus), 4) +
9494
roundup(sizeof(struct elf_prpsinfo), 4) +
95-
roundup(arch_task_struct_size(), 4);
95+
roundup(arch_task_struct_size, 4);
9696
*elf_buflen = PAGE_ALIGN(*elf_buflen);
9797
return size + *elf_buflen;
9898
}
@@ -415,7 +415,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff)
415415
/* set up the task structure */
416416
notes[2].name = CORE_STR;
417417
notes[2].type = NT_TASKSTRUCT;
418-
notes[2].datasz = arch_task_struct_size();
418+
notes[2].datasz = arch_task_struct_size;
419419
notes[2].data = current;
420420

421421
nhdr->p_filesz += notesize(&notes[2]);

include/linux/sched.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,11 @@ struct task_struct {
17861786
*/
17871787
};
17881788

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
17901794

17911795
/* Future-safe accessor for struct task_struct's cpus_allowed. */
17921796
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)

kernel/fork.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,21 +287,20 @@ static void set_max_threads(unsigned int max_threads_suggested)
287287
max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
288288
}
289289

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
294294

295295
void __init fork_init(void)
296296
{
297-
int task_struct_size = arch_task_struct_size();
298297
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
299298
#ifndef ARCH_MIN_TASKALIGN
300299
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
301300
#endif
302301
/* create a slab on which task_structs can be allocated */
303302
task_struct_cachep =
304-
kmem_cache_create("task_struct", task_struct_size,
303+
kmem_cache_create("task_struct", arch_task_struct_size,
305304
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
306305
#endif
307306

0 commit comments

Comments
 (0)