Skip to contentSkip to conversation

mm: simplify node/zone name printing

PATCH In review Michal Hocko 4 participants 9 messages Dec 16, 2016 – Dec 19, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mm: simplify node/zone name printing

From: Michal Hocko <[email protected]>

show_node currently only prints Node id while it is always followed by printing zone->name. As the node information is conditional to CONFIG_NUMA we have to be careful to always terminate the previous continuation line before printing the zone name. This is quite ugly and easy to mess up. Let's rename show_node to show_zone_node and make sure that it will always start at a new line. We can drop the ugly printk(KERN_CONT "\n") from show_free_areas.

---
Hi,
this has been sitting in my tree since oct and I completely forgot about it. Does this look like a reasonable clean up to you?

 mm/page_alloc.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
mm/page_alloc.c +6 -8
index 3f2c9e535f7f..5324efa8b9d0 100644
@@ -4120,10 +4120,12 @@ unsigned long nr_free_pagecache_pages(void)
 	return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER_MOVABLE));
 }
 
-static inline void show_node(struct zone *zone)
+static inline void show_zone_node(struct zone *zone)
 {
 	if (IS_ENABLED(CONFIG_NUMA))
-		printk("Node %d ", zone_to_nid(zone));
+		printk("Node %d %s", zone_to_nid(zone), zone->name);
+	else
+		printk("%s: ", zone->name);
 }
 
 long si_mem_available(void)
@@ -4371,9 +4373,8 @@ void show_free_areas(unsigned int filter)
 		for_each_online_cpu(cpu)
 			free_pcp += per_cpu_ptr(zone->pageset, cpu)->pcp.count;
 
-		show_node(zone);
+		show_zone_node(zone);
 		printk(KERN_CONT
-			"%s"
 			" free:%lukB"
 			" min:%lukB"
 			" low:%lukB"
@@ -4396,7 +4397,6 @@ void show_free_areas(unsigned int filter)
 			" local_pcp:%ukB"
 			" free_cma:%lukB"
 			"\n",
-			zone->name,
 			K(zone_page_state(zone, NR_FREE_PAGES)),
 			K(min_wmark_pages(zone)),
 			K(low_wmark_pages(zone)),
@@ -4421,7 +4421,6 @@ void show_free_areas(unsigned int filter)
 		printk("lowmem_reserve[]:");
 		for (i = 0; i < MAX_NR_ZONES; i++)
 			printk(KERN_CONT " %ld", zone->lowmem_reserve[i]);
-		printk(KERN_CONT "\n");
 	}
 
 	for_each_populated_zone(zone) {
@@ -4431,8 +4430,7 @@ void show_free_areas(unsigned int filter)
 
 		if (skip_free_areas_node(filter, zone_to_nid(zone)))
 			continue;
-		show_node(zone);
-		printk(KERN_CONT "%s: ", zone->name);
+		show_zone_node(zone);
 
 		spin_lock_irqsave(&zone->lock, flags);
 		for (order = 0; order < MAX_ORDER; order++) {
Signature · 7 lines
2.10.2

--
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>
Acked-by on v1 1/1
#1 lore raw
Quoted 11 lines · Michal Hocko

From: Michal Hocko <[email protected]>

show_node currently only prints Node id while it is always followed by printing zone->name. As the node information is conditional to CONFIG_NUMA we have to be careful to always terminate the previous continuation line before printing the zone name. This is quite ugly and easy to mess up. Let's rename show_node to show_zone_node and make sure that it will always start at a new line. We can drop the ugly printk(KERN_CONT "\n") from show_free_areas.

Just a question below... (CC printk experts)

Quoted 4 lines

---
Hi,
this has been sitting in my tree since oct and I completely forgot about it. Does this look like a reasonable clean up to you?

Yeah, even besides the removed line, which my question is about....

Quoted 42 lines
 mm/page_alloc.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
mm/page_alloc.c +5 -5
index 3f2c9e535f7f..5324efa8b9d0 100644
@@ -4120,10 +4120,12 @@ unsigned long nr_free_pagecache_pages(void)
 	return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER_MOVABLE));
 }
 
-static inline void show_node(struct zone *zone)
+static inline void show_zone_node(struct zone *zone)
 {
 	if (IS_ENABLED(CONFIG_NUMA))
-		printk("Node %d ", zone_to_nid(zone));
+		printk("Node %d %s", zone_to_nid(zone), zone->name);
+	else
+		printk("%s: ", zone->name);
 }
 
 long si_mem_available(void)
@@ -4371,9 +4373,8 @@ void show_free_areas(unsigned int filter)
 		for_each_online_cpu(cpu)
 			free_pcp += per_cpu_ptr(zone->pageset, cpu)->pcp.count;
 
-		show_node(zone);
+		show_zone_node(zone);
 		printk(KERN_CONT
-			"%s"
 			" free:%lukB"
 			" min:%lukB"
 			" low:%lukB"
@@ -4396,7 +4397,6 @@ void show_free_areas(unsigned int filter)
 			" local_pcp:%ukB"
 			" free_cma:%lukB"
 			"\n",
-			zone->name,
 			K(zone_page_state(zone, NR_FREE_PAGES)),
 			K(min_wmark_pages(zone)),
 			K(low_wmark_pages(zone)),

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4424

Quoted 4 lines
mm/page_alloc.c +0 -1
@@ -4421,7 +4421,6 @@ void show_free_areas(unsigned int filter)
 		printk("lowmem_reserve[]:");
 		for (i = 0; i < MAX_NR_ZONES; i++)
 			printk(KERN_CONT " %ld", zone->lowmem_reserve[i]);
-		printk(KERN_CONT "\n");

So there's really no functional difference between terminating line explicitly with "\n", and doing a followup printk() without KERN_CONT? I agree that a KERN_CONT line just to print "\n" is ugly, just want to be sure we are really safe without it, considering how KERN_CONT has been recently changed etc.

Quoted 5 lines
mm/page_alloc.c +0 -0
 	}
 
 	for_each_populated_zone(zone) {

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4436

Quoted 9 lines
mm/page_alloc.c +1 -2
@@ -4431,8 +4430,7 @@ void show_free_areas(unsigned int filter)
 
 		if (skip_free_areas_node(filter, zone_to_nid(zone)))
 			continue;
-		show_node(zone);
-		printk(KERN_CONT "%s: ", zone->name);
+		show_zone_node(zone);
 
 		spin_lock_irqsave(&zone->lock, flags);
 		for (order = 0; order < MAX_ORDER; 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>

#2 lore raw

Hello,

On (12/19/16 08:00), Vlastimil Babka wrote:
[..]

Quoted 11 lines

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4424

Quoted 5 lines
mm/page_alloc.c +0 -1
@@ -4421,7 +4421,6 @@ void show_free_areas(unsigned int filter)
 		printk("lowmem_reserve[]:");
 		for (i = 0; i < MAX_NR_ZONES; i++)
 			printk(KERN_CONT " %ld", zone->lowmem_reserve[i]);
-		printk(KERN_CONT "\n");

So there's really no functional difference between terminating line explicitly with "\n", and doing a followup printk() without KERN_CONT? I agree that a KERN_CONT line just to print "\n" is ugly, just want to be sure we are really safe without it, considering how KERN_CONT has been recently changed etc.

depending on what will follow. if another KERN_CONT printk then without this explicit '\n' printk may assume that we are still in cont printing; if something else -- printk should flush.

kernel/printk/printk.c

	/*
	 * If an earlier line was buffered, and we're a continuation
	 * write from the same process, try to add it to the buffer.
	 */
	if (cont.len) {
		if (cont.owner == current && (lflags & LOG_CONT)) {
			if (cont_add(facility, level, lflags, text, text_len))
				return text_len;
		}
		/* Otherwise, make sure it's flushed */
		cont_flush();
	}

as far as I can tell, now for_each_populated_zone() iterations are split by non-CONT printk() from show_zone_node(), which previously
has been printk(KERN_CONT "%s: ", zone->name), so pr_cont(\n)
between iterations was important, but now that non-CONT printk() should do the trick. it's _a bit_ hacky, though.

	-ss
Quoted 5 lines
Quoted 5 lines
mm/page_alloc.c +0 -0
 	}
 
 	for_each_populated_zone(zone) {
@@ -4431,8 +4430,7 @@ void show_free_areas(unsigned int filter)
 
Quoted 7 lines

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4435

Quoted 7 lines
mm/page_alloc.c +1 -2
 		if (skip_free_areas_node(filter, zone_to_nid(zone)))
 			continue;
-		show_node(zone);
-		printk(KERN_CONT "%s: ", zone->name);
+		show_zone_node(zone);
 
 		spin_lock_irqsave(&zone->lock, flags);

--
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>

#3 lore raw

On Mon 19-12-16 16:32:28, Sergey Senozhatsky wrote:
[...]

Quoted 5 lines

as far as I can tell, now for_each_populated_zone() iterations are split by non-CONT printk() from show_zone_node(), which previously
has been printk(KERN_CONT "%s: ", zone->name), so pr_cont(\n)
between iterations was important, but now that non-CONT printk() should do the trick. it's _a bit_ hacky, though.

Do you consider that more hacky than the original? At least for me, starting with KERN_CONT and relying on an explicit \n sounds more error prone than leaving the last pr_cont without \n and relying on the implicit flushing.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
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>
#4 lore raw
Quoted 9 lines · Michal Hocko

On Mon 19-12-16 16:32:28, Sergey Senozhatsky wrote:
[...]

Quoted 5 lines

as far as I can tell, now for_each_populated_zone() iterations are split by non-CONT printk() from show_zone_node(), which previously
has been printk(KERN_CONT "%s: ", zone->name), so pr_cont(\n)
between iterations was important, but now that non-CONT printk() should do the trick. it's _a bit_ hacky, though.

Do you consider that more hacky than the original?

well, slightly. merely because (to me) implicit always relies on internals, which can change; while explicit does not (ideally). simply because of that.

but I don't have any problems with your patch.

	-ss

--
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>

#5 lore raw
In reply to Michal Hocko
Quoted 8 lines · Michal Hocko

On Mon 19-12-16 16:32:28, Sergey Senozhatsky wrote:
[...]

Quoted 5 lines

as far as I can tell, now for_each_populated_zone() iterations are split by non-CONT printk() from show_zone_node(), which previously
has been printk(KERN_CONT "%s: ", zone->name), so pr_cont(\n)
between iterations was important, but now that non-CONT printk() should do the trick. it's _a bit_ hacky, though.

Quoted 4 lines

Do you consider that more hacky than the original? At least for me, starting with KERN_CONT and relying on an explicit \n sounds more error prone than leaving the last pr_cont without \n and relying on the implicit flushing.

The missing '\n' will cause the string will not be flushed until another printk happens. It is not a problem here because other printk follows. But it might take a while in general.

There was a commit[1] that flushed the cont lines when the log buffer was read via /dev/kmsg or syslog. Also there was a patch[2] that flushed cont lines using a timer. But the commit caused problems and was reverted[3]. Also the patch needs more testing. So, it might take a while until flushing partial cont lines is "guaranteed".

I would personally prefer to keep that pr_cont("\n") call when it was already there. It makes it clear that the line is over. It does not rely on any further printk's or fallbacks.

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=bfd8d3f23b51018388be0411ccbc2d56277fe294
[2]
https://lkml.kernel.org/r/CA+55aFwKYnrMJr_vSE+GfDGszeUGyd=CPUD15-zZ8yWQW61GBA@mail.gmail.com
[3] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f5c9f9c72395c3291c2e35c905dedae2b98475a4

Best Regards,
Petr

--
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>

#6 lore raw
Quoted 18 lines · Petr Mladek
Quoted 8 lines · Michal Hocko

On Mon 19-12-16 16:32:28, Sergey Senozhatsky wrote:
[...]

Quoted 5 lines

as far as I can tell, now for_each_populated_zone() iterations are split by non-CONT printk() from show_zone_node(), which previously
has been printk(KERN_CONT "%s: ", zone->name), so pr_cont(\n)
between iterations was important, but now that non-CONT printk() should do the trick. it's _a bit_ hacky, though.

Quoted 4 lines

Do you consider that more hacky than the original? At least for me, starting with KERN_CONT and relying on an explicit \n sounds more error prone than leaving the last pr_cont without \n and relying on the implicit flushing.

The missing '\n' will cause the string will not be flushed until another printk happens. It is not a problem here because other printk follows. But it might take a while in general.

Quoted 5 lines

There was a commit[1] that flushed the cont lines when the log buffer was read via /dev/kmsg or syslog. Also there was a patch[2] that flushed cont lines using a timer. But the commit caused problems and was reverted[3]. Also the patch needs more testing. So, it might take a while until flushing partial cont lines is "guaranteed".

OK, fair enough. If the flushing partial cont lines is not guaranteed then this cleanup makes less sense. I was under impression this has been solved but as per your list of commits we are not there yet.

So let's just drop this patch and I will try to remember to double check later.

Thanks!

Signature · 8 lines
Michal Hocko
SUSE Labs

--
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>
#7 lore raw
In reply to Vlastimil Babka
Quoted 36 lines · Vlastimil Babka
Quoted 35 lines · Michal Hocko

From: Michal Hocko <[email protected]>

show_node currently only prints Node id while it is always followed by printing zone->name. As the node information is conditional to CONFIG_NUMA we have to be careful to always terminate the previous continuation line before printing the zone name. This is quite ugly and easy to mess up. Let's rename show_node to show_zone_node and make sure that it will always start at a new line. We can drop the ugly printk(KERN_CONT "\n") from show_free_areas.

mm/page_alloc.c +4 -2
index 3f2c9e535f7f..5324efa8b9d0 100644
@@ -4120,10 +4120,12 @@ unsigned long nr_free_pagecache_pages(void)
 	return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER_MOVABLE));
 }
 
-static inline void show_node(struct zone *zone)
+static inline void show_zone_node(struct zone *zone)
 {
 	if (IS_ENABLED(CONFIG_NUMA))
-		printk("Node %d ", zone_to_nid(zone));
+		printk("Node %d %s", zone_to_nid(zone), zone->name);
+	else
+		printk("%s: ", zone->name);
 }
 
 long si_mem_available(void)
@@ -4371,9 +4373,8 @@ void show_free_areas(unsigned int filter)
 		for_each_online_cpu(cpu)
 			free_pcp += per_cpu_ptr(zone->pageset, cpu)->pcp.count;
 
Quoted 4 lines

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4376

Quoted 4 lines
mm/page_alloc.c +1 -2
-		show_node(zone);
+		show_zone_node(zone);
 		printk(KERN_CONT
-			"%s"

The new code will printk "%s: " when called with disabled CONFIG_NUMA. Is the added ": " OK?

Best Regards,
Petr

--
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>

#8 lore raw
Quoted 37 lines · Petr Mladek
Quoted 36 lines · Vlastimil Babka
Quoted 35 lines · Michal Hocko

From: Michal Hocko <[email protected]>

show_node currently only prints Node id while it is always followed by printing zone->name. As the node information is conditional to CONFIG_NUMA we have to be careful to always terminate the previous continuation line before printing the zone name. This is quite ugly and easy to mess up. Let's rename show_node to show_zone_node and make sure that it will always start at a new line. We can drop the ugly printk(KERN_CONT "\n") from show_free_areas.

mm/page_alloc.c +4 -2
index 3f2c9e535f7f..5324efa8b9d0 100644
@@ -4120,10 +4120,12 @@ unsigned long nr_free_pagecache_pages(void)
 	return nr_free_zone_pages(gfp_zone(GFP_HIGHUSER_MOVABLE));
 }
 
-static inline void show_node(struct zone *zone)
+static inline void show_zone_node(struct zone *zone)
 {
 	if (IS_ENABLED(CONFIG_NUMA))
-		printk("Node %d ", zone_to_nid(zone));
+		printk("Node %d %s", zone_to_nid(zone), zone->name);
+	else
+		printk("%s: ", zone->name);
 }
 
 long si_mem_available(void)
@@ -4371,9 +4373,8 @@ void show_free_areas(unsigned int filter)
 		for_each_online_cpu(cpu)
 			free_pcp += per_cpu_ptr(zone->pageset, cpu)->pcp.count;
 
Quoted 7 lines
Quoted 4 lines

mm/page_alloc.c void show_free_areas(unsigned int filter) · line 4376

Quoted 4 lines
mm/page_alloc.c +1 -2
-		show_node(zone);
+		show_zone_node(zone);
 		printk(KERN_CONT
-			"%s"

The new code will printk "%s: " when called with disabled CONFIG_NUMA. Is the added ": " OK?

no, that was not intentional. Will drop it.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
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>