Skip to contentSkip to conversation

s390x/mm: avoid taking the table lock in gmap_pmd_op_walk()

PATCH In review David Hildenbrand 2 participants 3 messages Aug 6, 2018 – Aug 7, 2018

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

PATCH 1/1 s390x/mm: avoid taking the table lock in gmap_pmd_op_walk()

Right now we temporarily take the page table lock in gmap_pmd_op_walk() even though we know we won't need it (if we can never have 1mb pages mapped into the gmap).

So let's special case this, so gmap_protect_range()/gmap_sync_dirty_log_pmd() will not take the lock in case huge pages are not allowed.

gmap_protect_range() is called quite frequently for managing shadow page tables in vSIE environments.

---
 arch/s390/mm/gmap.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
arch/s390/mm/gmap.c +8 -2
index bb44990c8212..d4fa0a4514e0 100644
@@ -905,10 +905,16 @@ static inline pmd_t *gmap_pmd_op_walk(struct gmap *gmap, unsigned long gaddr)
 	pmd_t *pmdp;
 
 	BUG_ON(gmap_is_shadow(gmap));
-	spin_lock(&gmap->guest_table_lock);
 	pmdp = (pmd_t *) gmap_table_walk(gmap, gaddr, 1);
+	if (!pmdp)
+		return NULL;
 
-	if (!pmdp || pmd_none(*pmdp)) {
+	/* without huge pages, there is no need to take the table lock */
+	if (!gmap->mm->context.allow_gmap_hpage_1m)
+		return pmd_none(*pmdp) ? NULL : pmdp;
+
+	spin_lock(&gmap->guest_table_lock);
+	if (pmd_none(*pmdp)) {
 		spin_unlock(&gmap->guest_table_lock);
 		return NULL;
 	}
Signature · 1 line
2.17.1
Reviewed-by on v1 1/1
#1 lore raw
Quoted 7 lines · David Hildenbrand

Right now we temporarily take the page table lock in gmap_pmd_op_walk() even though we know we won't need it (if we can never have 1mb pages mapped into the gmap).

So let's special case this, so gmap_protect_range()/gmap_sync_dirty_log_pmd() will not take the lock in case huge pages are not allowed.

So, let's make this a special case

Quoted 5 lines

gmap_protect_range() is called quite frequently for managing shadow page tables in vSIE environments.

If you make the patch title more specific:

I considered getting rid of the last unlock with the !large check, but in theory somebody could run a VM with the HPAGE CAP and 4k pages which would then result in havoc if we wouldn't also adapt gmap_pmd_op_end.

Quoted 28 lines
---
 arch/s390/mm/gmap.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
arch/s390/mm/gmap.c +8 -2
index bb44990c8212..d4fa0a4514e0 100644
@@ -905,10 +905,16 @@ static inline pmd_t *gmap_pmd_op_walk(struct gmap *gmap, unsigned long gaddr)
 	pmd_t *pmdp;
 
 	BUG_ON(gmap_is_shadow(gmap));
-	spin_lock(&gmap->guest_table_lock);
 	pmdp = (pmd_t *) gmap_table_walk(gmap, gaddr, 1);
+	if (!pmdp)
+		return NULL;
 
-	if (!pmdp || pmd_none(*pmdp)) {
+	/* without huge pages, there is no need to take the table lock */
+	if (!gmap->mm->context.allow_gmap_hpage_1m)
+		return pmd_none(*pmdp) ? NULL : pmdp;
+
+	spin_lock(&gmap->guest_table_lock);
+	if (pmd_none(*pmdp)) {
 		spin_unlock(&gmap->guest_table_lock);
 		return NULL;
 	}
#2 lore raw
Quoted 12 lines · Janosch Frank
Quoted 7 lines · David Hildenbrand

Right now we temporarily take the page table lock in gmap_pmd_op_walk() even though we know we won't need it (if we can never have 1mb pages mapped into the gmap).

So let's special case this, so gmap_protect_range()/gmap_sync_dirty_log_pmd() will not take the lock in case huge pages are not allowed.

So, let's make this a special case

Quoted 1 line
Quoted 7 lines
Quoted 4 lines

gmap_protect_range() is called quite frequently for managing shadow page tables in vSIE environments.

If you make the patch title more specific:

"s390/mm: optimize locking without huge pages in gmap_pmd_op_walk()"

Thanks!

Signature · 3 lines
Thanks,

David / dhildenb