Skip to contentSkip to conversation

mm/page_alloc: replace local_lock with normal spinlock -fix -fix

PATCH In review Mel Gorman 2 participants 3 messages Jul 8, 2022

Subsystems (2)
lore
Share & tools
lore

Mel Gorman

author
#0 lore raw

PATCH 1/1 mm/page_alloc: replace local_lock with normal spinlock -fix -fix

pcpu_spin_unlock and pcpu_spin_unlock_irqrestore both unlock pcp->lock and then enable preemption. This lacks symmetry against both the pcpu_spin helpers and differs from how local_unlock_* is implemented. While this is harmless, it's unnecessary and it's generally better to unwind locks and preemption state in the reverse order as they were acquired.

This is a fix on top of the mm-unstable patch mm-page_alloc-replace-local_lock-with-normal-spinlock-fix.patch

---
 mm/page_alloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
index 934d1b5a5449..d0141e51e613 100644
@@ -192,14 +192,14 @@ static DEFINE_MUTEX(pcp_batch_high_lock);
 
 #define pcpu_spin_unlock(member, ptr)					\
 ({									\
-	spin_unlock(&ptr->member);					\
 	pcpu_task_unpin();						\
+	spin_unlock(&ptr->member);					\
 })
 
 #define pcpu_spin_unlock_irqrestore(member, ptr, flags)			\
 ({									\
-	spin_unlock_irqrestore(&ptr->member, flags);			\
 	pcpu_task_unpin();						\
+	spin_unlock_irqrestore(&ptr->member, flags);			\
 })
 
 /* struct per_cpu_pages specific helpers. */
#1 lore raw
Quoted 6 lines · Mel Gorman

pcpu_spin_unlock and pcpu_spin_unlock_irqrestore both unlock pcp->lock and then enable preemption. This lacks symmetry against both the pcpu_spin helpers and differs from how local_unlock_* is implemented. While this is harmless, it's unnecessary and it's generally better to unwind locks and preemption state in the reverse order as they were acquired.

Hm I'm confused, it seems it's done in reverse order (which I agree with) before this -fix-fix, but not after it?

before, pcpu_spin_lock() (and variants) do pcpu_task_pin() and then spin_lock() (or variant), and pcpu_spin_unlock() does spin_unlock() and then pcpu_task_unpin(). That seems symmetrical, i.e. reverse order to me? And seems to match what local_lock family does too.

Quoted 29 lines

This is a fix on top of the mm-unstable patch mm-page_alloc-replace-local_lock-with-normal-spinlock-fix.patch

---
 mm/page_alloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page_alloc.c +2 -2
index 934d1b5a5449..d0141e51e613 100644
@@ -192,14 +192,14 @@ static DEFINE_MUTEX(pcp_batch_high_lock);
 
 #define pcpu_spin_unlock(member, ptr)					\
 ({									\
-	spin_unlock(&ptr->member);					\
 	pcpu_task_unpin();						\
+	spin_unlock(&ptr->member);					\
 })
 
 #define pcpu_spin_unlock_irqrestore(member, ptr, flags)			\
 ({									\
-	spin_unlock_irqrestore(&ptr->member, flags);			\
 	pcpu_task_unpin();						\
+	spin_unlock_irqrestore(&ptr->member, flags);			\
 })
 
 /* struct per_cpu_pages specific helpers. */
author
#2 lore raw
Quoted 8 lines · Vlastimil Babka
Quoted 6 lines · Mel Gorman

pcpu_spin_unlock and pcpu_spin_unlock_irqrestore both unlock pcp->lock and then enable preemption. This lacks symmetry against both the pcpu_spin helpers and differs from how local_unlock_* is implemented. While this is harmless, it's unnecessary and it's generally better to unwind locks and preemption state in the reverse order as they were acquired.

Quoted 8 lines

Hm I'm confused, it seems it's done in reverse order (which I agree with) before this -fix-fix, but not after it?

before, pcpu_spin_lock() (and variants) do pcpu_task_pin() and then spin_lock() (or variant), and pcpu_spin_unlock() does spin_unlock() and then pcpu_task_unpin(). That seems symmetrical, i.e. reverse order to me? And seems to match what local_lock family does too.

You're not confused, I am. The patch and the changelog are outright brain damage from excessive context switching and a sign that it's time for the weekend to start.

Sorry for this absolute misfortune.

Signature · 2 lines
Mel Gorman
SUSE Labs