Virtually mapped stack prep for -mm
Subsystems (11)
cover Virtually mapped stack prep for -mm
Hi akpm-
We're delaying virtually mapped stacks to 4.9. These four patches are simple and seem like -mm material. Could you apply them for 4.8 so we can get the easy core bits in place?
Thanks,
Andy
Andy Lutomirski (4):
mm: Track NR_KERNEL_STACK in KiB instead of number of stacks
mm: Fix memcg stack accounting for sub-page stacks
kdb: Use task_cpu() instead of task_thread_info()->cpu
printk: When dumping regs, show the stack, not thread_info
drivers/base/node.c | 3 +-- fs/proc/meminfo.c | 2 +- include/linux/kdb.h | 2 +- include/linux/memcontrol.h | 2 +- include/linux/mmzone.h | 2 +- kernel/fork.c | 20 +++++++++----------- kernel/printk/printk.c | 5 ++--- mm/memcontrol.c | 2 +- mm/page_alloc.c | 3 +-- 9 files changed, 18 insertions(+), 23 deletions(-)
Signature · 1 line
2.7.4
PATCH 1/4 mm: Track NR_KERNEL_STACK in KiB instead of number of stacks
Currently, NR_KERNEL_STACK tracks the number of kernel stacks in a zone. This only makes sense if each kernel stack exists entirely in one zone, and allowing vmapped stacks could break this assumption.
Since frv has THREAD_SIZE < PAGE_SIZE, we need to track kernel stack allocations in a unit that divides both THREAD_SIZE and PAGE_SIZE on all architectures. Keep it simple and use KiB.
--- drivers/base/node.c | 3 +-- fs/proc/meminfo.c | 2 +- include/linux/mmzone.h | 2 +- kernel/fork.c | 3 ++- mm/page_alloc.c | 3 +-- 5 files changed, 6 insertions(+), 7 deletions(-)
drivers/base/node.c +1 -2
@@ -121,8 +121,7 @@ static ssize_t node_read_meminfo(struct device *dev, nid,K (node_page_state (nid,NR_FILE_MAPPED )), nid,K (node_page_state (nid,NR_ANON_PAGES )), nid,K (i.sharedram), - nid,node_page_state (nid,NR_KERNEL_STACK ) * -THREAD_SIZE /1024 , + nid,node_page_state (nid,NR_KERNEL_STACK_KB ), nid,K (node_page_state (nid,NR_PAGETABLE )), nid,K (node_page_state (nid,NR_UNSTABLE_NFS )), nid, K(node_page_state(nid, NR_BOUNCE)),
fs/proc/meminfo.c +1 -1
@@ -145,7 +145,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) global_page_state(NR_SLAB_UNRECLAIMABLE)),K (global_page_state (NR_SLAB_RECLAIMABLE )),K (global_page_state (NR_SLAB_UNRECLAIMABLE )), -global_page_state (NR_KERNEL_STACK ) *THREAD_SIZE /1024 , +global_page_state (NR_KERNEL_STACK_KB ),K (global_page_state (NR_PAGETABLE )), #ifdef CONFIG_QUICKLIST K(quicklist_total_size()),
include/linux/mmzone.h +1 -1
@@ -127,7 +127,7 @@ enum zone_stat_item {NR_SLAB_RECLAIMABLE ,NR_SLAB_UNRECLAIMABLE ,NR_PAGETABLE ,/* used for pagetables */ -NR_KERNEL_STACK , +NR_KERNEL_STACK_KB ,/* measured in KiB */ /* Second 128 byte cacheline */ NR_UNSTABLE_NFS ,/* NFS unstable pages */ NR_BOUNCE,
kernel/fork.c +2 -1
@@ -225,7 +225,8 @@ static void account_kernel_stack(unsigned long *stack, int account) {struct zone *zone =page_zone (virt_to_page (stack)); -mod_zone_page_state (zone,NR_KERNEL_STACK , account); +mod_zone_page_state (zone,NR_KERNEL_STACK_KB , +THREAD_SIZE /1024 * account); }void free_task (struct task_struct *tsk)
mm/page_alloc.c +1 -2
@@ -4457,8 +4457,7 @@ void show_free_areas(unsigned int filter)K (zone_page_state (zone,NR_SHMEM )),K (zone_page_state (zone,NR_SLAB_RECLAIMABLE )),K (zone_page_state (zone,NR_SLAB_UNRECLAIMABLE )), -zone_page_state (zone,NR_KERNEL_STACK ) * -THREAD_SIZE /1024 , +zone_page_state (zone,NR_KERNEL_STACK_KB ),K (zone_page_state (zone,NR_PAGETABLE )),K (zone_page_state (zone,NR_UNSTABLE_NFS )), K(zone_page_state(zone, NR_BOUNCE)),
Signature · 7 lines
2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/4] mm: Track NR_KERNEL_STACK in KiB instead of number of stacks
Quoted 8 lines · Andy Lutomirski
Currently,
NR_KERNEL_STACKtracks the number of kernel stacks in a zone. This only makes sense if each kernel stack exists entirely in one zone, and allowing vmapped stacks could break this assumption.Since frv has
THREAD_SIZE<PAGE_SIZE, we need to track kernel stack allocations in a unit that divides bothTHREAD_SIZEandPAGE_SIZEon all architectures. Keep it simple and use KiB.
Quoted 8 lines
Cc Vladimir Davydov <[email protected]>Cc Johannes Weiner <[email protected]>Cc Michal Hocko <[email protected]>Reviewed-by Josh Poimboeuf <[email protected]>Reviewed-by Vladimir Davydov <[email protected]>Acked-by Michal Hocko <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>
PATCH 2/4 mm: Fix memcg stack accounting for sub-page stacks
In reply to Andy LutomirskiWe should account for stacks regardless of stack size, and we need to account in sub-page units if THREAD_SIZE < PAGE_SIZE. Change the units to kilobytes and Move it into account_kernel_stack().
--- include/linux/memcontrol.h | 2 +- kernel/fork.c | 19 ++++++++----------- mm/memcontrol.c | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-)
include/linux/memcontrol.h +1 -1
@@ -52,7 +52,7 @@ enum mem_cgroup_stat_index {MEM_CGROUP_STAT_SWAP ,/* # of pages, swapped out */ MEM_CGROUP_STAT_NSTATS ,/* default hierarchy stats */ -MEMCG_KERNEL_STACK =MEM_CGROUP_STAT_NSTATS , +MEMCG_KERNEL_STACK_KB =MEM_CGROUP_STAT_NSTATS ,MEMCG_SLAB_RECLAIMABLE ,MEMCG_SLAB_UNRECLAIMABLE , MEMCG_SOCK,
kernel/fork.c +8 -11
@@ -165,20 +165,12 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,struct page *page =alloc_kmem_pages_node (node,THREADINFO_GFP ,THREAD_SIZE_ORDER ); -if (page) -memcg_kmem_update_page_stat (page,MEMCG_KERNEL_STACK , -1 <<THREAD_SIZE_ORDER ); - return page ? page_address(page) : NULL; }static inline void free_thread_stack (unsigned long *stack) { -struct page *page =virt_to_page (stack); - -memcg_kmem_update_page_stat (page,MEMCG_KERNEL_STACK , - -(1 <<THREAD_SIZE_ORDER )); -__free_kmem_pages (page,THREAD_SIZE_ORDER ); +free_kmem_pages ((unsigned long )stack,THREAD_SIZE_ORDER ); }# else static struct kmem_cache *thread_stack_cache;
@@ -223,10 +215,15 @@ static struct kmem_cache *mm_cachep;static void account_kernel_stack (unsigned long *stack,int account) { -struct zone *zone =page_zone (virt_to_page (stack)); +/* All stack pages are in the same zone and belong to the same memcg. */ +struct page *first_page =virt_to_page (stack); -mod_zone_page_state (zone,NR_KERNEL_STACK_KB , +mod_zone_page_state (page_zone (first_page),NR_KERNEL_STACK_KB ,THREAD_SIZE /1024 * account); + +memcg_kmem_update_page_stat ( + first_page,MEMCG_KERNEL_STACK_KB , + account * (THREAD_SIZE /1024 )); }void free_task (struct task_struct *tsk)
mm/memcontrol.c +1 -1
@@ -5133,7 +5133,7 @@ static int memory_stat_show(struct seq_file *m, void *v)seq_printf (m,"file %llu\n" , (u64 )stat[MEM_CGROUP_STAT_CACHE ] *PAGE_SIZE );seq_printf (m,"kernel_stack %llu\n" , - (u64 )stat[MEMCG_KERNEL_STACK ] *PAGE_SIZE ); + (u64 )stat[MEMCG_KERNEL_STACK_KB ] *1024 );seq_printf (m,"slab %llu\n" , (u64)(stat[MEMCG_SLAB_RECLAIMABLE ] + stat[MEMCG_SLAB_UNRECLAIMABLE ]) *PAGE_SIZE );
Signature · 7 lines
2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/4] mm: Fix memcg stack accounting for sub-page stacks
Quoted 4 lines · Andy Lutomirski
We should account for stacks regardless of stack size, and we need to account in sub-page units if
THREAD_SIZE<PAGE_SIZE. Change the units to kilobytes and Move it intoaccount_kernel_stack().
Quoted 9 lines
Fixes 12580e4b54ba8 ("mm: memcontrol: report kernel stack usage in cgroup2 memory.stat")Cc Vladimir Davydov <[email protected]>Cc Johannes Weiner <[email protected]>Cc Michal Hocko <[email protected]>Reviewed-by Josh Poimboeuf <[email protected]>Reviewed-by Vladimir Davydov <[email protected]>Acked-by Michal Hocko <[email protected]>Signed-off-by Andy Lutomirski <[email protected]>
Andrew Morton
maintainerRe: [PATCH 2/4] mm: Fix memcg stack accounting for sub-page stacks
In reply to Andy LutomirskiQuoted 3 lines · On Thu, 14 Jul 2016 12:14:11 -0700 Andy Lutomirski <[email protected]> wrote:
We should account for stacks regardless of stack size, and we need to account in sub-page units if
THREAD_SIZE<PAGE_SIZE. Change the units to kilobytes and Move it intoaccount_kernel_stack().
I queued this patch after
http://ozlabs.org/~akpm/mmotm/broken-out/mm-charge-uncharge-kmemcg-from-generic-page-allocator-paths.patch
so some changes are needed. (patching mainline when we're at -rc7 was optimistic!)
Quoted 12 lines
kernel/fork.c +0
-4@@ -165,20 +165,12 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,struct page *page =alloc_kmem_pages_node (node,THREADINFO_GFP ,THREAD_SIZE_ORDER ); -if (page) -memcg_kmem_update_page_stat (page,MEMCG_KERNEL_STACK , -1 <<THREAD_SIZE_ORDER ); -return page ?page_address (page) :NULL ; }
kernel/fork.c static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, · line 174
Quoted 10 lines
kernel/fork.c +1
-5static inline void free_thread_stack (unsigned long *stack) { -struct page *page =virt_to_page (stack); - -memcg_kmem_update_page_stat (page,MEMCG_KERNEL_STACK , - -(1 <<THREAD_SIZE_ORDER )); -__free_kmem_pages (page,THREAD_SIZE_ORDER ); +free_kmem_pages ((unsigned long )stack,THREAD_SIZE_ORDER ); }
Here's what I ended up with:
static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
int node)
{
struct page *page = alloc_pages_node(node, THREADINFO_GFP,
THREAD_SIZE_ORDER);
return page ? page_address(page) : NULL;
}static inline void free_thread_stack(unsigned long *stack)
{
__free_pages(virt_to_page(stack), THREAD_SIZE_ORDER);
}--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/4 kdb: Use task_cpu() instead of task_thread_info()->cpu
In reply to Andy LutomirskiWe'll need this cleanup to make the cpu field in thread_info be optional.
--- include/linux/kdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/kdb.h +1 -1
@@ -177,7 +177,7 @@ extern int kdb_get_kbd_char(void);static inline int kdb_process_cpu (const struct task_struct *p) { -unsigned int cpu =task_thread_info (p)->cpu; +unsigned int cpu =task_cpu (p);if (cpu >num_possible_cpus ()) cpu =0 ;return cpu;
Signature · 1 line
2.7.4
PATCH 4/4 printk: When dumping regs, show the stack, not thread_info
In reply to Andy LutomirskiWe currently show:
task: <current> ti: <current_thread_info()> task.ti: <task_thread_info(current)>"
"ti" and "task.ti" are redundant, and neither is actually what we want to show, which the the base of the thread stack. Change the display to show the stack pointer explicitly.
--- kernel/printk/printk.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/printk/printk.c +2 -3
@@ -3177,9 +3177,8 @@ void show_regs_print_info(const char *log_lvl) {dump_stack_print_info (log_lvl); -printk ("%stask: %p ti: %p task.ti: %p\n" , - log_lvl, current,current_thread_info (), -task_thread_info (current)); +printk ("%stask: %p task.stack: %p\n" , + log_lvl, current,task_stack_page (current)); }#endif
Signature · 1 line
2.7.4