mm: optimize thread stack usage on ARMv7 [1/1]

PD#SWPL-2681

Problem:
Kernel stack usage is large when running many tasks.

Solution:
Map kernel stack to module space and handle page-fault
for stack fault. This can save about 50% memory of stack
usage

Verify:
p212

Change-Id: Ie894bc8f00cb525ddf8ac63c6d99d9c6e937fdc0
Signed-off-by: tao zeng <tao.zeng@amlogic.com>
This commit is contained in:
tao zeng
2018-11-30 18:01:31 +08:00
committed by Luke Go
parent 4b9ca77d52
commit 003b4e1f9b
19 changed files with 656 additions and 48 deletions

View File

@@ -20,7 +20,18 @@
#define STACK_SHRINK_THRESHOLD (PAGE_SIZE + 1024)
#define STACK_SHRINK_SLEEP (HZ)
#ifdef CONFIG_64BIT
#define VM_STACK_AREA_SIZE SZ_512M
#define VMAP_ADDR_START VMALLOC_START
#define VMAP_ADDR_END VMALLOC_END
#define VMAP_ALIGN VM_STACK_AREA_SIZE
#else
/* currently support max 6144 tasks on 32bit */
#define VM_STACK_AREA_SIZE (SZ_64M - SZ_16M)
#define VMAP_ADDR_START MODULES_VADDR
#define VMAP_ADDR_END MODULES_END
#define VMAP_ALIGN SZ_64M
#endif
#define STACK_TOP_PAGE_OFF (THREAD_SIZE - PAGE_SIZE)
@@ -34,33 +45,28 @@
#define CACHE_MAINTAIN_DELAY (HZ)
struct aml_vmap {
spinlock_t vmap_lock;
unsigned int start_bit;
int cached_pages;
struct vm_struct *root_vm;
unsigned long *bitmap;
struct list_head list;
spinlock_t vmap_lock;
spinlock_t page_lock;
struct delayed_work mwork;
spinlock_t page_lock;
};
extern int handle_vmap_fault(unsigned long addr,
unsigned int esr, struct pt_regs *regs);
extern DEFINE_PER_CPU(unsigned long [THREAD_SIZE/sizeof(long)], vmap_stack);
static inline bool on_vmap_stack(unsigned long sp, int cpu)
{
/* variable names the same as kernel/stacktrace.c */
unsigned long low = (unsigned long)per_cpu(vmap_stack, cpu);
unsigned long high = low + THREAD_START_SP;
return (low <= sp && sp <= high);
}
extern bool on_vmap_stack(unsigned long sp, int cpu);
extern void __setup_vmap_stack(unsigned long off);
extern void update_vmap_stack(int diff);
extern int get_vmap_stack_size(void);
extern int is_vmap_addr(unsigned long addr);
extern void aml_stack_free(struct task_struct *tsk);
extern void *aml_stack_alloc(int node, struct task_struct *tsk);
extern void aml_account_task_stack(struct task_struct *tsk, int account);
#ifdef CONFIG_ARM
extern int on_irq_stack(unsigned long sp, int cpu);
#endif
#endif /* __VMAP_STACK_H__ */

View File

@@ -3331,7 +3331,13 @@ static inline unsigned long *end_of_stack(const struct task_struct *task)
#elif !defined(__HAVE_THREAD_FUNCTIONS)
#ifdef CONFIG_AMLOGIC_VMAP
#define task_thread_info(task) \
((struct thread_info *)(((unsigned long)(task)->stack) + \
THREAD_INFO_OFFSET))
#else
#define task_thread_info(task) ((struct thread_info *)(task)->stack)
#endif
#define task_stack_page(task) ((void *)(task)->stack)
static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
@@ -3351,11 +3357,15 @@ static inline void setup_thread_stack(struct task_struct *p, struct task_struct
*/
static inline unsigned long *end_of_stack(struct task_struct *p)
{
#ifdef CONFIG_AMLOGIC_VMAP
return p->stack;
#else /* CONFIG_AMLOGIC_VMAP */
#ifdef CONFIG_STACK_GROWSUP
return (unsigned long *)((unsigned long)task_thread_info(p) + THREAD_SIZE) - 1;
#else
return (unsigned long *)(task_thread_info(p) + 1);
#endif
#endif /* CONFIG_AMLOGIC_VMAP */
}
#endif