[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 6/8] common/grant_table: batch flush I/O TLB
On 07.09.2020 09:40, Paul Durrant wrote: > --- a/xen/common/grant_table.c > +++ b/xen/common/grant_table.c > @@ -241,7 +241,13 @@ struct gnttab_unmap_common { > grant_ref_t ref; > }; > > -/* Number of unmap operations that are done between each tlb flush */ > +/* Number of map operations that are done between each pre-emption check */ > +#define GNTTAB_MAP_BATCH_SIZE 32 > + > +/* > + * Number of unmap operations that are done between each tlb flush and > + * pre-emption check. > + */ > #define GNTTAB_UNMAP_BATCH_SIZE 32 Interesting - I don't think I've ever seen preemption spelled like this (with a hyphen). In the interest of grep-ability, would you mind changing to the more "conventional" spelling? Albeit I now notice we have two such spellings in the tree already ... > @@ -979,7 +985,7 @@ static unsigned int mapkind( > > static void > map_grant_ref( > - struct gnttab_map_grant_ref *op) > + struct gnttab_map_grant_ref *op, bool do_flush, unsigned int > *flush_flags) Why two parameters? Simply pass NULL for singletons instead? Although, you'd need another local variable then, which maybe isn't overly much nicer. > @@ -1319,29 +1324,60 @@ static long > gnttab_map_grant_ref( > XEN_GUEST_HANDLE_PARAM(gnttab_map_grant_ref_t) uop, unsigned int count) > { > - int i; > - struct gnttab_map_grant_ref op; > + struct domain *currd = current->domain; Is this a worthwhile variable to have in this case? It's used exactly once, granted in the loop body, but still not the inner one. > + unsigned int done = 0; > + int rc = 0; > > - for ( i = 0; i < count; i++ ) > + while ( count ) > { > - if ( i && hypercall_preempt_check() ) > - return i; > + unsigned int i, c = min_t(unsigned int, count, > GNTTAB_MAP_BATCH_SIZE); > + unsigned int flush_flags = 0; > > - if ( unlikely(__copy_from_guest_offset(&op, uop, i, 1)) ) > - return -EFAULT; > + for ( i = 0; i < c; i++ ) > + { > + struct gnttab_map_grant_ref op; > > - map_grant_ref(&op); > + if ( unlikely(__copy_from_guest(&op, uop, 1)) ) > + { > + rc = -EFAULT; > + break; > + } > > - if ( unlikely(__copy_to_guest_offset(uop, i, &op, 1)) ) > - return -EFAULT; > + map_grant_ref(&op, c == 1, &flush_flags); > + > + if ( unlikely(__copy_to_guest(uop, &op, 1)) ) > + { > + rc = -EFAULT; > + break; > + } > + > + guest_handle_add_offset(uop, 1); > + } > + > + if ( c > 1 ) > + { > + int err = iommu_iotlb_flush_all(currd, flush_flags); There's still some double flushing involved in the error case here. Trying to eliminate this (by having map_grant_ref() write zero into *flush_flags) may not be overly important, but I thought I'd still mention it. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |