Skip to contentSkip to conversation

mm/sparse: Clean up the obsolete code comment

PATCH Superseded Baoquan He 6 participants 23 messages Mar 20, 2019 – Mar 21, 2019

Subsystems (2)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Baoquan He

author
#0 lore raw

PATCH 1/3 mm/sparse: Clean up the obsolete code comment

The code comment above sparse_add_one_section() is obsolete and incorrect, clean it up and write new one.

---
 mm/sparse.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
mm/sparse.c +6 -3
index 77a0554fa5bd..0a0f82c5d969 100644
@@ -674,9 +674,12 @@ static void free_map_bootmem(struct page *memmap)
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 /*
- * returns the number of sections whose mem_maps were properly
- * set.  If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid:	The node to add section on
+ * @start_pfn:	start pfn of the memory range
+ * @altmap:	device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise.
  */
 int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 				     struct vmem_altmap *altmap)
Signature · 1 line
2.17.2
author
#1 lore raw

PATCH 2/3 mm/sparse: Optimize sparse_add_one_section()

Reorder the allocation of usemap and memmap since usemap allocation is much smaller and simpler. Otherwise hard work is done to make memmap ready, then have to rollback just because of usemap allocation failure.

---
 mm/sparse.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
mm/sparse.c +7 -6
index 0a0f82c5d969..054b99f74181 100644
@@ -697,16 +697,17 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	ret = sparse_index_init(section_nr, nid);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	ret = 0;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
-	if (!memmap)
-		return -ENOMEM;
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
+	if (!usemap)
+		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		kfree(usemap);
 		return -ENOMEM;
 	}
 
+	ret = 0;
 	ms = __pfn_to_section(start_pfn);
 	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
 		ret = -EEXIST;
Signature · 1 line
2.17.2
#2 lore raw

Re: [PATCH 2/3] mm/sparse: Optimize sparse_add_one_section()

Quoted 21 lines · Baoquan He

Reorder the allocation of usemap and memmap since usemap allocation is much smaller and simpler. Otherwise hard work is done to make memmap ready, then have to rollback just because of usemap allocation failure.

---
 mm/sparse.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
mm/sparse.c +0 -3
index 0a0f82c5d969..054b99f74181 100644
@@ -697,16 +697,17 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	ret = sparse_index_init(section_nr, nid);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	ret = 0;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
-	if (!memmap)

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn, · line 706

Quoted 10 lines
mm/sparse.c +6 -3
-		return -ENOMEM;
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
+	if (!usemap)
+		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		kfree(usemap);

If you are anyway changing this why not to switch to goto's for error handling?

Quoted 10 lines
mm/sparse.c +1 -0
 		return -ENOMEM;
 	}
 
+	ret = 0;
 	ms = __pfn_to_section(start_pfn);
 	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
 		ret = -EEXIST;
Signature · 1 line
2.17.2
Signature · 2 lines
Sincerely yours,
Mike.
author
#3 lore raw

Re: [PATCH 2/3] mm/sparse: Optimize sparse_add_one_section()

Quoted 16 lines · Mike Rapoport
Quoted 16 lines
mm/sparse.c +1 -6
index 0a0f82c5d969..054b99f74181 100644
@@ -697,16 +697,17 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	ret = sparse_index_init(section_nr, nid);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	ret = 0;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
-	if (!memmap)
-		return -ENOMEM;
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
Quoted 8 lines

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn, · line 706

Quoted 5 lines
mm/sparse.c +5 -0
+	if (!usemap)
+		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		kfree(usemap);

If you are anyway changing this why not to switch to goto's for error handling?

OK, I am fine to switch to 'goto'. Will update and repost. Thanks.

Quoted 16 lines
Quoted 11 lines
mm/sparse.c +1 -0
 		return -ENOMEM;
 	}
 
+	ret = 0;
 	ms = __pfn_to_section(start_pfn);
 	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
 		ret = -EEXIST;
Signature · 1 line
2.17.2
Signature · 2 lines
Sincerely yours,
Mike.
author
#4 lore raw

Re: [PATCH 2/3] mm/sparse: Optimize sparse_add_one_section()

In reply to Mike Rapoport

Hi Mike,

Quoted 12 lines · Mike Rapoport
(quoted diff) +0 -0
@@ -697,16 +697,17 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 >  	ret = sparse_index_init(section_nr, nid);
 >  	if (ret < 0 && ret != -EEXIST)
 >  		return ret;
 > -	ret = 0;
 > -	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
 > -	if (!memmap)
 > -		return -ENOMEM;
Quoted 4 lines
(quoted diff) +1 -2
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+	if (!usemap)
+		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		kfree(usemap);

If you are anyway changing this why not to switch to goto's for error handling?

I update code change as below, could you check if it's OK to you?

Thanks
Baoquan

From 39b679b6f34f6acbc05351be8569d23bae3c0458 Mon Sep 17 00:00:00 2001
From: Baoquan He <[email protected]>
Date: Fri, 15 Mar 2019 16:03:52 +0800
Subject: [PATCH] mm/sparse: Optimize sparse_add_one_section()

Reorder the allocation of usemap and memmap since usemap allocation is much smaller and simpler. Otherwise hard work is done to make memmap ready, then have to rollback just because of usemap allocation failure.

Meanwhile update the error handler to cover usemap allocation failure too.

---
 mm/sparse.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)
mm/sparse.c +12 -11
index a99e0b253927..0e842b924be6 100644
@@ -699,20 +699,21 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	ret = sparse_index_init(section_nr, nid);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	ret = 0;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
-	if (!memmap)
-		return -ENOMEM;
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
+	if (!usemap)
 		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		ret = -ENOMEM;
+		goto out2;
 	}
 
+	ret = 0;
 	ms = __pfn_to_section(start_pfn);
 	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
 		ret = -EEXIST;
-		goto out;
+		goto out2;
 	}
 
 	/*
@@ -724,11 +725,11 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	section_mark_present(ms);
 	sparse_init_one_section(ms, section_nr, memmap, usemap);
 
+	return ret;
 out:
-	if (ret < 0) {
-		kfree(usemap);
-		__kfree_section_memmap(memmap, altmap);
-	}
+	__kfree_section_memmap(memmap, altmap);
+out2:
+	kfree(usemap);
 	return ret;
 }
 
Signature · 1 line
2.17.2
#5 lore raw

Re: [PATCH 2/3] mm/sparse: Optimize sparse_add_one_section()

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn, · line 709

Quoted 3 lines · Baoquan He
mm/sparse.c +3 -0
+	if (!memmap) {
+		ret = -ENOMEM;
+		goto out2;

Documentation/process/coding-style:

Choose label names which say what the goto does or why the goto exists. An example of a good name could be ``out_free_buffer:`` if the goto frees ``buffer``. Avoid using GW-BASIC names like ``err1:`` and ``err2:``, as you would have to renumber them if you ever add or remove exit paths, and they make correctness difficult to verify anyway.

#6 lore raw

Re: [PATCH 2/3] mm/sparse: Optimize sparse_add_one_section()

In reply to Baoquan He
Quoted 59 lines · Baoquan He

Hi Mike,

Quoted 12 lines · Mike Rapoport
(quoted diff) +0 -0
@@ -697,16 +697,17 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 >  	ret = sparse_index_init(section_nr, nid);
 >  	if (ret < 0 && ret != -EEXIST)
 >  		return ret;
 > -	ret = 0;
 > -	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
 > -	if (!memmap)
 > -		return -ENOMEM;
Quoted 4 lines
mm/sparse.c +1 -2
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
Quoted 8 lines

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,

Quoted 5 lines
mm/sparse.c +5 -0
+	if (!usemap)
+		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		kfree(usemap);

If you are anyway changing this why not to switch to goto's for error handling?

I update code change as below, could you check if it's OK to you?

Thanks
Baoquan

From 39b679b6f34f6acbc05351be8569d23bae3c0458 Mon Sep 17 00:00:00 2001
From: Baoquan He <[email protected]>
Date: Fri, 15 Mar 2019 16:03:52 +0800
Subject: [PATCH] mm/sparse: Optimize sparse_add_one_section()

Reorder the allocation of usemap and memmap since usemap allocation is much smaller and simpler. Otherwise hard work is done to make memmap ready, then have to rollback just because of usemap allocation failure.

Meanwhile update the error handler to cover usemap allocation failure too.

---
 mm/sparse.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)
mm/sparse.c +0 -4
index a99e0b253927..0e842b924be6 100644
@@ -699,20 +699,21 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	ret = sparse_index_init(section_nr, nid);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	ret = 0;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
-	if (!memmap)
-		return -ENOMEM;

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn, · line 709

Quoted 10 lines
mm/sparse.c +6 -2
+
 	usemap = __kmalloc_section_usemap();
-	if (!usemap) {
-		__kfree_section_memmap(memmap, altmap);
+	if (!usemap)
 		return -ENOMEM;
+	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	if (!memmap) {
+		ret = -ENOMEM;
+		goto out2;

I'd name the label out_free_usemap.

mm/sparse.c int __meminit sparse_add_one_section(int nid, unsigned long start_pfn, · line 717

Quoted 9 lines
mm/sparse.c +2 -1
 	}
 
+	ret = 0;
 	ms = __pfn_to_section(start_pfn);
 	if (ms->section_mem_map & SECTION_MARKED_PRESENT) {
 		ret = -EEXIST;
-		goto out;
+		goto out2;
 	}

I've missed this previously, but it seems that this check can be moved before the allocations, which simplifies the code a bit more.

Quoted 21 lines
mm/sparse.c +4 -4
 	/*
@@ -724,11 +725,11 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	section_mark_present(ms);
 	sparse_init_one_section(ms, section_nr, memmap, usemap);
 
+	return ret;
 out:
-	if (ret < 0) {
-		kfree(usemap);
-		__kfree_section_memmap(memmap, altmap);
-	}
+	__kfree_section_memmap(memmap, altmap);
+out2:
+	kfree(usemap);
 	return ret;
 }
 
Signature · 1 line
2.17.2
Signature · 2 lines
Sincerely yours,
Mike.
author
#7 lore raw

PATCH 3/3 mm/sparse: Rename function related to section memmap allocation/free

In reply to Baoquan He

These functions are used allocate/free section memmap, have nothing to do with kmalloc/free during the handling. Rename them to remove the confusion.

---
 mm/sparse.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
mm/sparse.c +9 -9
index 054b99f74181..374206212d01 100644
@@ -579,13 +579,13 @@ void offline_mem_sections(unsigned long start_pfn, unsigned long end_pfn)
 #endif
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+static inline struct page *alloc_section_memmap(unsigned long pnum, int nid,
 		struct vmem_altmap *altmap)
 {
 	/* This will make the necessary allocations eventually. */
 	return sparse_mem_map_populate(pnum, nid, altmap);
 }
-static void __kfree_section_memmap(struct page *memmap,
+static void __free_section_memmap(struct page *memmap,
 		struct vmem_altmap *altmap)
 {
 	unsigned long start = (unsigned long)memmap;
@@ -603,7 +603,7 @@ static void free_map_bootmem(struct page *memmap)
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 #else
-static struct page *__kmalloc_section_memmap(void)
+static struct page *__alloc_section_memmap(void)
 {
 	struct page *page, *ret;
 	unsigned long memmap_size = sizeof(struct page) * PAGES_PER_SECTION;
@@ -624,13 +624,13 @@ static struct page *__kmalloc_section_memmap(void)
 	return ret;
 }
 
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+static inline struct page *alloc_section_memmap(unsigned long pnum, int nid,
 		struct vmem_altmap *altmap)
 {
-	return __kmalloc_section_memmap();
+	return __alloc_section_memmap();
 }
 
-static void __kfree_section_memmap(struct page *memmap,
+static void __free_section_memmap(struct page *memmap,
 		struct vmem_altmap *altmap)
 {
 	if (is_vmalloc_addr(memmap))
@@ -701,7 +701,7 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 	usemap = __kmalloc_section_usemap();
 	if (!usemap)
 		return -ENOMEM;
-	memmap = kmalloc_section_memmap(section_nr, nid, altmap);
+	memmap = alloc_section_memmap(section_nr, nid, altmap);
 	if (!memmap) {
 		kfree(usemap);
 		return -ENOMEM;
@@ -726,7 +726,7 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 out:
 	if (ret < 0) {
 		kfree(usemap);
-		__kfree_section_memmap(memmap, altmap);
+		__free_section_memmap(memmap, altmap);
 	}
 	return ret;
 }
@@ -777,7 +777,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap,
 	if (PageSlab(usemap_page) || PageCompound(usemap_page)) {
 		kfree(usemap);
 		if (memmap)
-			__kfree_section_memmap(memmap, altmap);
+			__free_section_memmap(memmap, altmap);
 		return;
 	}
 
Signature · 1 line
2.17.2
#8 lore raw
In reply to Baoquan He

Hi,

Quoted 13 lines · Baoquan He

The code comment above sparse_add_one_section() is obsolete and incorrect, clean it up and write new one.

---
 mm/sparse.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
mm/sparse.c +0 -0
index 77a0554fa5bd..0a0f82c5d969 100644

mm/sparse.c static void free_map_bootmem(struct page *memmap) · line 677

Quoted 7 lines
mm/sparse.c +1 -3
@@ -674,9 +674,12 @@ static void free_map_bootmem(struct page *memmap)
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 /*
- * returns the number of sections whose mem_maps were properly
- * set.  If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section

Please mention that this is only intended for memory hotplug

mm/sparse.c static void free_map_bootmem(struct page *memmap) · line 682

Quoted 5 lines
mm/sparse.c +5 -0
+ * @nid:	The node to add section on
+ * @start_pfn:	start pfn of the memory range
+ * @altmap:	device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise.

s/Return/Return:/ please

Quoted 6 lines
mm/sparse.c +0 -0
  */
 int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 				     struct vmem_altmap *altmap)
Signature · 1 line
2.17.2
Signature · 2 lines
Sincerely yours,
Mike.
author
#9 lore raw
Quoted 18 lines · Mike Rapoport

Hi,

Quoted 15 lines · Baoquan He

The code comment above sparse_add_one_section() is obsolete and incorrect, clean it up and write new one.

---
 mm/sparse.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
mm/sparse.c +0 -0
index 77a0554fa5bd..0a0f82c5d969 100644
@@ -674,9 +674,12 @@ static void free_map_bootmem(struct page *memmap)
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
Quoted 7 lines

mm/sparse.c static void free_map_bootmem(struct page *memmap) · line 677

Quoted 5 lines
mm/sparse.c +1 -3
 /*
- * returns the number of sections whose mem_maps were properly
- * set.  If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section

Please mention that this is only intended for memory hotplug

Will do. Thanks for reviewing.

Quoted 8 lines

mm/sparse.c static void free_map_bootmem(struct page *memmap) · line 682

Quoted 6 lines
mm/sparse.c +5 -0
+ * @nid:	The node to add section on
+ * @start_pfn:	start pfn of the memory range
+ * @altmap:	device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise.

s/Return/Return:/ please

Thanks, will change.

Quoted 12 lines
Quoted 7 lines
mm/sparse.c +0 -0
  */
 int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
 				     struct vmem_altmap *altmap)
Signature · 1 line
2.17.2
Signature · 2 lines
Sincerely yours,
Mike.
#10 lore raw
In reply to Baoquan He
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy
author
#11 lore raw
Quoted 19 lines · Matthew Wilcox
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

Quoted 8 lines
$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy

OK, will update per your comments. Thanks.

Quoted 1 line
#12 lore raw
In reply to Matthew Wilcox
Quoted 19 lines · Matthew Wilcox
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

Quoted 8 lines
$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy

We return -EEXIST in case the section we are trying to add is already there, and that error is being caught by __add_pages(), which ignores the error in case is -EXIST and keeps going with further sections.

Sure we can change that for -EBUSY, but I think -EEXIST makes more sense, plus that kind of error is never handed back to userspace.

Signature · 2 lines
Oscar Salvador
SUSE L3
#13 lore raw
Quoted 29 lines · Oscar Salvador
Quoted 19 lines · Matthew Wilcox
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

Quoted 8 lines
$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy
Quoted 6 lines

We return -EEXIST in case the section we are trying to add is already there, and that error is being caught by __add_pages(), which ignores the error in case is -EXIST and keeps going with further sections.

Sure we can change that for -EBUSY, but I think -EEXIST makes more sense, plus that kind of error is never handed back to userspace.

Not returned to userspace today. It's also bad precedent for other parts of the kernel where errnos do get returned to userspace.

#14 lore raw
Quoted 34 lines · Matthew Wilcox
Quoted 33 lines · Oscar Salvador
Quoted 19 lines · Matthew Wilcox
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

Quoted 8 lines
$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy

We return -EEXIST in case the section we are trying to add is already there, and that error is being caught by __add_pages(), which ignores the error in case is -EXIST and keeps going with further sections.

Quoted 5 lines
Quoted 2 lines

Sure we can change that for -EBUSY, but I think -EEXIST makes more sense, plus that kind of error is never handed back to userspace.

Not returned to userspace today. It's also bad precedent for other parts of the kernel where errnos do get returned to userspace.

There are more than a thousand -EEXIST in the kernel, I really doubt all of them mean "File exists" ;-)

Signature · 2 lines
Sincerely yours,
Mike.
#15 lore raw
Quoted 2 lines · Mike Rapoport

There are more than a thousand -EEXIST in the kernel, I really doubt all of them mean "File exists" ;-)

And yet that's what the user will see if it's ever printed with perror() or similar. We're pretty bad at choosing errnos; look how abused ENOSPC is:

$ errno ENOSPC
ENOSPC 28 No space left on device

net/sunrpc/auth_gss/gss_rpc_xdr.c: return -ENOSPC;

... that's an authentication failure, not "I've run out of disc space".

author
#16 lore raw

Hi all,

Quoted 7 lines · Matthew Wilcox
Quoted 2 lines · Mike Rapoport

There are more than a thousand -EEXIST in the kernel, I really doubt all of them mean "File exists" ;-)

And yet that's what the user will see if it's ever printed with perror() or similar. We're pretty bad at choosing errnos; look how abused ENOSPC is:

When I tried to change -EEXIST to -EBUSY, seems the returned value will return back over the whole path. And -EEXIST is checked explicitly several times during the path.

acpi_memory_enable_device -> __add_pages .. -> __add_section -> sparse_add_one_section

Only look into hotplug path triggered by ACPI event, there are also device memory and ballon memory paths I haven't checked carefully because not familiar with them.

So from the checking, I tend to agree with Oscar and Mike. There have been so many places to use '-EEXIST' to indicate that stuffs checked have been existing. We can't deny it's inconsistent with term explanation text. While the defense is that -EEXIST is more precise to indicate a static instance has been present when we want to create it, but -EBUSY is a little blizarre. I would rather see -EBUSY is used on a device. When want to stop it or destroy it, need check if it's busy or not.

#define EBUSY           16      /* Device or resource busy */
#define EEXIST          17      /* File exists */

Obviously saying resource busy or not, it violates semanics in any language. So many people use EEXIST instead, isn't it the obsolete text's fault?

Personal opinion.

Thanks
Baoquan

Quoted 7 lines
$ errno ENOSPC
ENOSPC 28 No space left on device

net/sunrpc/auth_gss/gss_rpc_xdr.c: return -ENOSPC;

... that's an authentication failure, not "I've run out of disc space".

author
#17 lore raw
Quoted 29 lines · Baoquan He

Hi all,

Quoted 7 lines · Matthew Wilcox
Quoted 2 lines · Mike Rapoport

There are more than a thousand -EEXIST in the kernel, I really doubt all of them mean "File exists" ;-)

And yet that's what the user will see if it's ever printed with perror() or similar. We're pretty bad at choosing errnos; look how abused ENOSPC is:

When I tried to change -EEXIST to -EBUSY, seems the returned value will return back over the whole path. And -EEXIST is checked explicitly several times during the path.

acpi_memory_enable_device -> __add_pages .. -> __add_section -> sparse_add_one_section

Only look into hotplug path triggered by ACPI event, there are also device memory and ballon memory paths I haven't checked carefully because not familiar with them.

So from the checking, I tend to agree with Oscar and Mike. There have been so many places to use '-EEXIST' to indicate that stuffs checked have been existing. We can't deny it's inconsistent with term explanation text. While the defense is that -EEXIST is more precise to indicate a static instance has been present when we want to create it, but -EBUSY is a little blizarre. I would rather see -EBUSY is used on a device. When want to stop it or destroy it, need check if it's busy or not.

Quoted 5 lines
#define EBUSY           16      /* Device or resource busy */
#define EEXIST          17      /* File exists */

Obviously saying resource busy or not, it violates semanics in any language. So many people use EEXIST instead, isn't it the obsolete

Surely when we require a lock which is protecting resource, we can also return -EBUSY since someone is busy on this resource. For creating one instance, just check if the instance exists already, no matter what the code comment of the errno is saying, IMHO, it really should not be -EBUSY.

Thanks
Baoquan

#18 lore raw
Quoted 3 lines · Baoquan He

It appears as is so often the case that the usage has far outpaced the documentation and -EEXIST may be the proper code to return.

The correct answer here may be to modify the documentation to note the additional semantic, though if the usage is solely within the kernel it may be sufficient to explain its use in the header comment for the routine (in this case sparse_add_one_section()).

#19 lore raw
Quoted 11 lines · William Kucharski
Quoted 3 lines · Baoquan He

It appears as is so often the case that the usage has far outpaced the documentation and -EEXIST may be the proper code to return.

The correct answer here may be to modify the documentation to note the additional semantic, though if the usage is solely within the kernel it may be sufficient to explain its use in the header comment for the routine (in this case sparse_add_one_section()).

Is this really worth? It is a well known problem that errno codes are far from sufficient to describe error codes we need. Yet we are stuck with them more or less. I really do not see any point changing this particular path, nor spend a lot of time whether one inappropriate code is any better than another one. The code works as intended AFAICS.

I would stick with all good rule of thumb. It works, do not touch it too much.

I am sorry to be snarky but hasn't this generated way much more email traffic than it really deserves? A simply and trivial clean up in the beginning that was it, right?

Signature · 2 lines
Michal Hocko
SUSE Labs
#20 lore raw
Quoted 7 lines · Michal Hocko

I am sorry to be snarky but hasn't this generated way much more email traffic than it really deserves? A simply and trivial clean up in the beginning that was it, right?

That's rather the point; that it did generate a fair amount of email traffic indicates it's worthy of at least a passing mention in a comment somewhere.

author
#21 lore raw
Quoted 7 lines · William Kucharski
Quoted 7 lines · Michal Hocko

I am sorry to be snarky but hasn't this generated way much more email traffic than it really deserves? A simply and trivial clean up in the beginning that was it, right?

Yeah, I'd like to do like this. Will arrange patch and post a new version. Sorry about the mail bomb to CCed people.

Yet I also would like to hear any suggestion from people who intend to improve. Discussions make me know more the status of errno than before.

Thank you all for sharing.

Quoted 4 lines

That's rather the point; that it did generate a fair amount of email traffic indicates it's worthy of at least a passing mention in a comment somewhere.

We header files to put errno. Only changing in kernel may cause difference between it and userspace. I will list each returned value in code comment and tell what they are meaning in this function, that could be helpful. Thanks.

usr/include/asm-generic/errno-base.h
include/uapi/asm-generic/errno-base.h

#22 lore raw
In reply to Matthew Wilcox
Quoted 34 lines · Matthew Wilcox
Quoted 33 lines · Oscar Salvador
Quoted 19 lines · Matthew Wilcox
Quoted 11 lines · Baoquan He

/*
- * returns the number of sections whose mem_maps were properly
- * set. If this is <=0, then that means that the passed-in
- * map was not consumed and must be freed.
+ * sparse_add_one_section - add a memory section
+ * @nid: The node to add section on
+ * @start_pfn: start pfn of the memory range
+ * @altmap: device page map
+ *
+ * Return 0 on success and an appropriate error code otherwise. */

I think it's worth documenting what those error codes are. Seems to be just -ENOMEM and -EEXIST, but it'd be nice for users to know what they can expect under which circumstances.

Also, -EEXIST is a bad errno to return here:

Quoted 8 lines
$ errno EEXIST
EEXIST 17 File exists

What file? I think we should be using -EBUSY instead in case this errno makes it back to userspace:

$ errno EBUSY
EBUSY 16 Device or resource busy

We return -EEXIST in case the section we are trying to add is already there, and that error is being caught by __add_pages(), which ignores the error in case is -EXIST and keeps going with further sections.

Quoted 5 lines
Quoted 2 lines

Sure we can change that for -EBUSY, but I think -EEXIST makes more sense, plus that kind of error is never handed back to userspace.

Not returned to userspace today. It's also bad precedent for other parts of the kernel where errnos do get returned to userspace.

Yes, I get your point, but I do not really see -EBUSY fitting here. Actually, we do have the same kind of situation when dealing with resources. We return -EEXIST in register_memory_resource() in case the resource we are trying to add conflicts with another one.

I think that -EEXIST is more intuitive in that code path, but I am not going to insist.

Signature · 2 lines
Oscar Salvador
SUSE L3