mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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__ */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user