Skip to content

Commit 5462009

Browse files
Michal Hockohnaz
authored andcommitted
lib/show_mem.c: teach show_mem to work with the given nodemask
show_mem() allows to filter out node specific data which is irrelevant to the allocation request via SHOW_MEM_FILTER_NODES. The filtering is done in skip_free_areas_node which skips all nodes which are not in the mems_allowed of the current process. This works most of the time as expected because the nodemask shouldn't be outside of the allocating task but there are some exceptions. E.g. memory hotplug might want to request allocations from outside of the allowed nodes (see new_node_page). Get rid of this hardcoded behavior and push the allocation mask down the show_mem path and use it instead of cpuset_current_mems_allowed. NULL nodemask is interpreted as cpuset_current_mems_allowed. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Michal Hocko <[email protected]> Acked-by: Mel Gorman <[email protected]> Cc: Hillf Danton <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: David Rientjes <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 0ead3d5 commit 5462009

File tree

10 files changed

+32
-33
lines changed

10 files changed

+32
-33
lines changed

arch/powerpc/xmon/xmon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ cmds(struct pt_regs *excp)
916916
memzcan();
917917
break;
918918
case 'i':
919-
show_mem(0);
919+
show_mem(0, NULL);
920920
break;
921921
default:
922922
termch = cmd;

arch/sparc/kernel/setup_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static void prom_sync_me(void)
8282
"nop\n\t" : : "r" (&trapbase));
8383

8484
prom_printf("PROM SYNC COMMAND...\n");
85-
show_free_areas(0);
85+
show_free_areas(0, NULL);
8686
if (!is_idle_task(current)) {
8787
local_irq_enable();
8888
sys_sync();

drivers/net/ethernet/sgi/ioc3-eth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ static void ioc3_alloc_rings(struct net_device *dev)
914914

915915
skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
916916
if (!skb) {
917-
show_free_areas(0);
917+
show_free_areas(0, NULL);
918918
continue;
919919
}
920920

drivers/tty/sysrq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = {
317317

318318
static void sysrq_handle_showmem(int key)
319319
{
320-
show_mem(0);
320+
show_mem(0, NULL);
321321
}
322322
static struct sysrq_key_op sysrq_showmem_op = {
323323
.handler = sysrq_handle_showmem,

drivers/tty/vt/keyboard.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ static void fn_scroll_back(struct vc_data *vc)
572572

573573
static void fn_show_mem(struct vc_data *vc)
574574
{
575-
show_mem(0);
575+
show_mem(0, NULL);
576576
}
577577

578578
static void fn_show_state(struct vc_data *vc)

include/linux/mm.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,7 @@ extern void pagefault_out_of_memory(void);
11481148
*/
11491149
#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */
11501150

1151-
extern void show_free_areas(unsigned int flags);
1152-
extern bool skip_free_areas_node(unsigned int flags, int nid);
1151+
extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);
11531152

11541153
int shmem_zero_setup(struct vm_area_struct *);
11551154
#ifdef CONFIG_SHMEM
@@ -1930,7 +1929,7 @@ extern void setup_per_zone_wmarks(void);
19301929
extern int __meminit init_per_zone_wmark_min(void);
19311930
extern void mem_init(void);
19321931
extern void __init mmap_init(void);
1933-
extern void show_mem(unsigned int flags);
1932+
extern void show_mem(unsigned int flags, nodemask_t *nodemask);
19341933
extern long si_mem_available(void);
19351934
extern void si_meminfo(struct sysinfo * val);
19361935
extern void si_meminfo_node(struct sysinfo *val, int nid);

lib/show_mem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
#include <linux/quicklist.h>
1010
#include <linux/cma.h>
1111

12-
void show_mem(unsigned int filter)
12+
void show_mem(unsigned int filter, nodemask_t *nodemask)
1313
{
1414
pg_data_t *pgdat;
1515
unsigned long total = 0, reserved = 0, highmem = 0;
1616

1717
printk("Mem-Info:\n");
18-
show_free_areas(filter);
18+
show_free_areas(filter, nodemask);
1919

2020
for_each_online_pgdat(pgdat) {
2121
unsigned long flags;

mm/nommu.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ static int do_mmap_private(struct vm_area_struct *vma,
11911191
enomem:
11921192
pr_err("Allocation of length %lu from process %d (%s) failed\n",
11931193
len, current->pid, current->comm);
1194-
show_free_areas(0);
1194+
show_free_areas(0, NULL);
11951195
return -ENOMEM;
11961196
}
11971197

@@ -1412,13 +1412,13 @@ unsigned long do_mmap(struct file *file,
14121412
kmem_cache_free(vm_region_jar, region);
14131413
pr_warn("Allocation of vma for %lu byte allocation from process %d failed\n",
14141414
len, current->pid);
1415-
show_free_areas(0);
1415+
show_free_areas(0, NULL);
14161416
return -ENOMEM;
14171417

14181418
error_getting_region:
14191419
pr_warn("Allocation of vm region for %lu byte allocation from process %d failed\n",
14201420
len, current->pid);
1421-
show_free_areas(0);
1421+
show_free_areas(0, NULL);
14221422
return -ENOMEM;
14231423
}
14241424

mm/oom_kill.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ static void dump_header(struct oom_control *oc, struct task_struct *p)
417417
if (oc->memcg)
418418
mem_cgroup_print_oom_info(oc->memcg, p);
419419
else
420-
show_mem(SHOW_MEM_FILTER_NODES);
420+
show_mem(SHOW_MEM_FILTER_NODES, nm);
421421
if (sysctl_oom_dump_tasks)
422422
dump_tasks(oc->memcg, oc->nodemask);
423423
}

mm/page_alloc.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,7 +3005,7 @@ static inline bool should_suppress_show_mem(void)
30053005
return ret;
30063006
}
30073007

3008-
static void warn_alloc_show_mem(gfp_t gfp_mask)
3008+
static void warn_alloc_show_mem(gfp_t gfp_mask, nodemask_t *nodemask)
30093009
{
30103010
unsigned int filter = SHOW_MEM_FILTER_NODES;
30113011
static DEFINE_RATELIMIT_STATE(show_mem_rs, HZ, 1);
@@ -3025,7 +3025,7 @@ static void warn_alloc_show_mem(gfp_t gfp_mask)
30253025
if (in_interrupt() || !(gfp_mask & __GFP_DIRECT_RECLAIM))
30263026
filter &= ~SHOW_MEM_FILTER_NODES;
30273027

3028-
show_mem(filter);
3028+
show_mem(filter, nodemask);
30293029
}
30303030

30313031
void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...)
@@ -3052,7 +3052,7 @@ void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...)
30523052
cpuset_print_current_mems_allowed();
30533053

30543054
dump_stack();
3055-
warn_alloc_show_mem(gfp_mask);
3055+
warn_alloc_show_mem(gfp_mask, nm);
30563056
}
30573057

30583058
static inline struct page *
@@ -4274,20 +4274,20 @@ void si_meminfo_node(struct sysinfo *val, int nid)
42744274
* Determine whether the node should be displayed or not, depending on whether
42754275
* SHOW_MEM_FILTER_NODES was passed to show_free_areas().
42764276
*/
4277-
bool skip_free_areas_node(unsigned int flags, int nid)
4277+
static bool show_mem_node_skip(unsigned int flags, int nid, nodemask_t *nodemask)
42784278
{
4279-
bool ret = false;
4280-
unsigned int cpuset_mems_cookie;
4281-
42824279
if (!(flags & SHOW_MEM_FILTER_NODES))
4283-
goto out;
4280+
return false;
42844281

4285-
do {
4286-
cpuset_mems_cookie = read_mems_allowed_begin();
4287-
ret = !node_isset(nid, cpuset_current_mems_allowed);
4288-
} while (read_mems_allowed_retry(cpuset_mems_cookie));
4289-
out:
4290-
return ret;
4282+
/*
4283+
* no node mask - aka implicit memory numa policy. Do not bother with the
4284+
* synchronization - read_mems_allowed_begin - because we do not have to be
4285+
* precise here.
4286+
*/
4287+
if (!nodemask)
4288+
nodemask = &cpuset_current_mems_allowed;
4289+
4290+
return !node_isset(nid, *nodemask);
42914291
}
42924292

42934293
#define K(x) ((x) << (PAGE_SHIFT-10))
@@ -4328,15 +4328,15 @@ static void show_migration_types(unsigned char type)
43284328
* SHOW_MEM_FILTER_NODES: suppress nodes that are not allowed by current's
43294329
* cpuset.
43304330
*/
4331-
void show_free_areas(unsigned int filter)
4331+
void show_free_areas(unsigned int filter, nodemask_t *nodemask)
43324332
{
43334333
unsigned long free_pcp = 0;
43344334
int cpu;
43354335
struct zone *zone;
43364336
pg_data_t *pgdat;
43374337

43384338
for_each_populated_zone(zone) {
4339-
if (skip_free_areas_node(filter, zone_to_nid(zone)))
4339+
if (show_mem_node_skip(filter, zone_to_nid(zone), nodemask))
43404340
continue;
43414341

43424342
for_each_online_cpu(cpu)
@@ -4370,7 +4370,7 @@ void show_free_areas(unsigned int filter)
43704370
global_page_state(NR_FREE_CMA_PAGES));
43714371

43724372
for_each_online_pgdat(pgdat) {
4373-
if (skip_free_areas_node(filter, pgdat->node_id))
4373+
if (show_mem_node_skip(filter, pgdat->node_id, nodemask))
43744374
continue;
43754375

43764376
printk("Node %d"
@@ -4422,7 +4422,7 @@ void show_free_areas(unsigned int filter)
44224422
for_each_populated_zone(zone) {
44234423
int i;
44244424

4425-
if (skip_free_areas_node(filter, zone_to_nid(zone)))
4425+
if (show_mem_node_skip(filter, zone_to_nid(zone), nodemask))
44264426
continue;
44274427

44284428
free_pcp = 0;
@@ -4487,7 +4487,7 @@ void show_free_areas(unsigned int filter)
44874487
unsigned long nr[MAX_ORDER], flags, total = 0;
44884488
unsigned char types[MAX_ORDER];
44894489

4490-
if (skip_free_areas_node(filter, zone_to_nid(zone)))
4490+
if (show_mem_node_skip(filter, zone_to_nid(zone), nodemask))
44914491
continue;
44924492
show_node(zone);
44934493
printk(KERN_CONT "%s: ", zone->name);

0 commit comments

Comments
 (0)