s390/mm,tlb: optimize TLB flushing for zEC12
The zEC12 machines introduced the local-clearing control for the IDTE and IPTE instruction. If the control is set only the TLB of the local CPU is cleared of entries, either all entries of a single address space for IDTE, or the entry for a single page-table entry for IPTE. Without the local-clearing control the TLB flush is broadcasted to all CPUs in the configuration, which is expensive. The reset of the bit mask of the CPUs that need flushing after a non-local IDTE is tricky. As TLB entries for an address space remain in the TLB even if the address space is detached a new bit field is required to keep track of attached CPUs vs. CPUs in the need of a flush. After a non-local flush with IDTE the bit-field of attached CPUs is copied to the bit-field of CPUs in need of a flush. The ordering of operations on cpu_attach_mask, attach_count and mm_cpumask(mm) is such that an underindication in mm_cpumask(mm) is prevented but an overindication in mm_cpumask(mm) is possible. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
@@ -200,7 +200,7 @@ static int gmap_unlink_segment(struct gmap *gmap, unsigned long *table)
|
||||
static void gmap_flush_tlb(struct gmap *gmap)
|
||||
{
|
||||
if (MACHINE_HAS_IDTE)
|
||||
__tlb_flush_idte((unsigned long) gmap->table |
|
||||
__tlb_flush_asce(gmap->mm, (unsigned long) gmap->table |
|
||||
_ASCE_TYPE_REGION1);
|
||||
else
|
||||
__tlb_flush_global();
|
||||
@@ -219,7 +219,7 @@ void gmap_free(struct gmap *gmap)
|
||||
|
||||
/* Flush tlb. */
|
||||
if (MACHINE_HAS_IDTE)
|
||||
__tlb_flush_idte((unsigned long) gmap->table |
|
||||
__tlb_flush_asce(gmap->mm, (unsigned long) gmap->table |
|
||||
_ASCE_TYPE_REGION1);
|
||||
else
|
||||
__tlb_flush_global();
|
||||
|
Reference in New Issue
Block a user