ia64/xen-unstable

changeset 10790:33aca302b610

[LINUX] Improve single-page contiguous region creation/destruction

Batch page table updates and fold TLB flush into last one, reducing
number of hypercalls made from ((# of pages) + 1) to just 1.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Tue Jul 25 15:58:35 2006 +0100 (2006-07-25)
parents 10fb002727ef
children 110c1e853c53
files linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Tue Jul 25 15:50:04 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Tue Jul 25 15:58:35 2006 +0100
     1.3 @@ -266,6 +266,7 @@ static void contiguous_bitmap_clear(
     1.4  /* Protected by balloon_lock. */
     1.5  #define MAX_CONTIG_ORDER 9 /* 2MB */
     1.6  static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
     1.7 +static multicall_entry_t cr_mcl[1<<MAX_CONTIG_ORDER];
     1.8  
     1.9  /* Ensure multi-page extents are contiguous in machine memory. */
    1.10  int xen_create_contiguous_region(
    1.11 @@ -310,12 +311,13 @@ int xen_create_contiguous_region(
    1.12  	/* 1. Zap current PTEs, remembering MFNs. */
    1.13  	for (i = 0; i < (1UL<<order); i++) {
    1.14  		in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
    1.15 -		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    1.16 -						 __pte_ma(0), 0))
    1.17 -			BUG();
    1.18 +		MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
    1.19 +					__pte_ma(0), 0);
    1.20  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
    1.21  			INVALID_P2M_ENTRY);
    1.22  	}
    1.23 +	if (HYPERVISOR_multicall(cr_mcl, i))
    1.24 +		BUG();
    1.25  
    1.26  	/* 2. Get a new contiguous memory extent. */
    1.27  	out_frame = __pa(vstart) >> PAGE_SHIFT;
    1.28 @@ -343,15 +345,16 @@ int xen_create_contiguous_region(
    1.29  	/* 3. Map the new extent in place of old pages. */
    1.30  	for (i = 0; i < (1UL<<order); i++) {
    1.31  		frame = success ? (out_frame + i) : in_frames[i];
    1.32 -		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    1.33 -						 pfn_pte_ma(frame,
    1.34 -							    PAGE_KERNEL),
    1.35 -						 0))
    1.36 -			BUG();
    1.37 +		MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
    1.38 +					pfn_pte_ma(frame, PAGE_KERNEL), 0);
    1.39  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
    1.40  	}
    1.41  
    1.42 -	flush_tlb_all();
    1.43 +	cr_mcl[i - 1].args[MULTI_UVMFLAGS_INDEX] = order
    1.44 +						   ? UVMF_TLB_FLUSH|UVMF_ALL
    1.45 +						   : UVMF_INVLPG|UVMF_ALL;
    1.46 +	if (HYPERVISOR_multicall(cr_mcl, i))
    1.47 +		BUG();
    1.48  
    1.49  	if (success)
    1.50  		contiguous_bitmap_set(__pa(vstart) >> PAGE_SHIFT,
    1.51 @@ -402,13 +405,14 @@ void xen_destroy_contiguous_region(unsig
    1.52  
    1.53  	/* 2. Zap current PTEs. */
    1.54  	for (i = 0; i < (1UL<<order); i++) {
    1.55 -		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    1.56 -						 __pte_ma(0), 0))
    1.57 -			BUG();
    1.58 +		MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
    1.59 +					__pte_ma(0), 0);
    1.60  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
    1.61  			INVALID_P2M_ENTRY);
    1.62  		out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
    1.63  	}
    1.64 +	if (HYPERVISOR_multicall(cr_mcl, i))
    1.65 +		BUG();
    1.66  
    1.67  	/* 3. Do the exchange for non-contiguous MFNs. */
    1.68  	rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
    1.69 @@ -429,15 +433,16 @@ void xen_destroy_contiguous_region(unsig
    1.70  	/* 4. Map new pages in place of old pages. */
    1.71  	for (i = 0; i < (1UL<<order); i++) {
    1.72  		frame = success ? out_frames[i] : (in_frame + i);
    1.73 -		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
    1.74 -						 pfn_pte_ma(frame,
    1.75 -							    PAGE_KERNEL),
    1.76 -						 0))
    1.77 -			BUG();
    1.78 +		MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
    1.79 +					pfn_pte_ma(frame, PAGE_KERNEL), 0);
    1.80  		set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
    1.81  	}
    1.82  
    1.83 -	flush_tlb_all();
    1.84 +	cr_mcl[i - 1].args[MULTI_UVMFLAGS_INDEX] = order
    1.85 +						   ? UVMF_TLB_FLUSH|UVMF_ALL
    1.86 +						   : UVMF_INVLPG|UVMF_ALL;
    1.87 +	if (HYPERVISOR_multicall(cr_mcl, i))
    1.88 +		BUG();
    1.89  
    1.90  	balloon_unlock(flags);
    1.91  }