From 5e9a8cb7144f7dfe4e2eac71f767c6327e4af8b2 Mon Sep 17 00:00:00 2001 From: Sai Harshini Nimmala Date: Fri, 13 Sep 2024 14:53:12 -0700 Subject: [PATCH] ANDROID: GKI: Add to task_struct size via cmdline To reduce the size of vendor data allocated in the task_struct, from 512 bytes to a significantly lower 48 bytes, the move to a dynamically sized task_struct is being made. As part of this effort, provide means for vendors to pass a size value via kernel cmdline. Use the passed value to dynamically add to the task_struct size to accommodate vendor data. The cmdline parameter to be used is 'android_task_struct_vendor_size'. For eg., vendors can add the following to the bootargs section of their devicetree to add an extra 512 bytes to the task_struct: "android_task_struct_vendor_size=512" To access this additional memory, use the android_task_vendor_data function provided. Bug: 233921394 Change-Id: I6d5ab92080b82f29bbe9735d40f7d0b1e5bb5913 Signed-off-by: Sai Harshini Nimmala --- arch/x86/kernel/fpu/init.c | 4 ++++ kernel/fork.c | 18 ++++++++++++++++++ kernel/sched/sched.h | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 998a08f17e33..2eff8b3c5515 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -173,6 +173,10 @@ static void __init fpu__init_task_struct_size(void) CHECK_MEMBER_AT_END_OF(struct thread_struct, fpu); CHECK_MEMBER_AT_END_OF(struct task_struct, thread); + if (arch_task_struct_size > sizeof(struct task_struct)) { + pr_warn("WARNING: Extra space requested by android_arch_task_struct_size overwritten by %s\n", + __func__); + } arch_task_struct_size = task_size; } diff --git a/kernel/fork.c b/kernel/fork.c index 786eb6f8cf47..34f2ebdd8969 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1034,6 +1034,24 @@ static void __init set_max_threads(unsigned int max_threads_suggested) #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT /* Initialized by the architecture: */ int arch_task_struct_size __read_mostly; + +static int __init arch_task_struct_size_setup(char *str) +{ + u64 size; + + if (!str) + return -EINVAL; + + size = memparse(str, &str); + + if (size < 0 || size > CONFIG_GKI_TASK_STRUCT_VENDOR_SIZE_MAX) + return -EINVAL; + + arch_task_struct_size = sizeof(struct task_struct) + size; + + return 0; +} +early_param("android_task_struct_vendor_size", arch_task_struct_size_setup); #endif static void __init task_struct_whitelist(unsigned long *offset, unsigned long *size) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 07a204e3413b..32ece39e4d70 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -3865,4 +3865,12 @@ void sched_enq_and_set_task(struct sched_enq_and_set_ctx *ctx); #include "ext.h" +static inline void *android_task_vendor_data(struct task_struct *p) +{ + if (p == &init_task) + return &vendor_data_pad[0]; + + return p + 1; +} + #endif /* _KERNEL_SCHED_SCHED_H */