[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCHv6 5/5] gnttab: use per-VCPU maptrack free lists
On 23/04/15 17:11, Jan Beulich wrote: >>>> On 22.04.15 at 18:00, <david.vrabel@xxxxxxxxxx> wrote: >> static inline int >> get_maptrack_handle( >> struct grant_table *lgt) >> { >> + struct vcpu *v = current; >> int i; >> grant_handle_t handle; >> struct grant_mapping *new_mt; >> unsigned int new_mt_limit, nr_frames; >> >> - spin_lock(&lgt->maptrack_lock); >> - >> - while ( unlikely((handle = __get_maptrack_handle(lgt)) == -1) ) >> - { >> - nr_frames = nr_maptrack_frames(lgt); >> - if ( nr_frames >= max_maptrack_frames ) >> - break; >> - >> - new_mt = alloc_xenheap_page(); >> - if ( !new_mt ) >> - break; >> + handle = __get_maptrack_handle(lgt, v); >> + if ( likely(handle != -1) ) >> + return handle; >> >> - clear_page(new_mt); >> + nr_frames = nr_vcpu_maptrack_frames(v); >> + if ( nr_frames >= max_maptrack_frames ) >> + return -1; >> >> - new_mt_limit = lgt->maptrack_limit + MAPTRACK_PER_PAGE; >> + new_mt = alloc_xenheap_page(); >> + if ( !new_mt ) >> + return -1; >> >> - for ( i = 1; i < MAPTRACK_PER_PAGE; i++ ) >> - new_mt[i - 1].ref = lgt->maptrack_limit + i; >> - new_mt[i - 1].ref = lgt->maptrack_head; >> - lgt->maptrack_head = lgt->maptrack_limit; >> + clear_page(new_mt); >> >> - lgt->maptrack[nr_frames] = new_mt; >> - smp_wmb(); >> - lgt->maptrack_limit = new_mt_limit; >> + new_mt_limit = v->maptrack_limit + MAPTRACK_PER_PAGE; >> >> - gdprintk(XENLOG_INFO, "Increased maptrack size to %u frames\n", >> - nr_frames + 1); >> + for ( i = 1; i < MAPTRACK_PER_PAGE; i++ ){ >> + new_mt[i - 1].ref = (lgt->maptrack_pages * MAPTRACK_PER_PAGE) + i; >> + new_mt[i - 1].vcpu = v->vcpu_id; >> + } >> + /* Set last entry vcpu and ref */ >> + new_mt[i - 1].ref = v->maptrack_head; >> + new_mt[i - 1].vcpu = v->vcpu_id; >> + v->maptrack_head = lgt->maptrack_pages * MAPTRACK_PER_PAGE; >> + if (v->maptrack_tail == MAPTRACK_TAIL) >> + { >> + v->maptrack_tail = (lgt->maptrack_pages * MAPTRACK_PER_PAGE) >> + + MAPTRACK_PER_PAGE - 1; >> + new_mt[i - 1].ref = MAPTRACK_TAIL; >> } >> >> + spin_lock(&lgt->maptrack_lock); >> + lgt->maptrack[lgt->maptrack_pages++] = new_mt; >> spin_unlock(&lgt->maptrack_lock); > > The uses of ->maptrack_pages ahead of taking the lock can race > with updates inside the lock. And with locking elsewhere dropped > by the previous patch it looks like you can't update ->maptrack[] > like you do (you'd need a barrier between the pointer store and > the increment, and with that I think the lock would become > superfluous if it was needed only for this update). > > Also note the coding style issues in the changes above^(and also > in code further down). This was a last minute optimisation, this isn't on the hot patch so we'll expand the spin_lock to cover all users of maptrack_pages. Sorry about the coding style problems. > >> - return handle; >> + v->maptrack_limit = new_mt_limit; >> + >> + return __get_maptrack_handle(lgt, v); > > With the lock dropped, nothing guarantees this to succeed, which it > ought to unless the table size reached its allowed maximum. > >> @@ -1422,6 +1448,17 @@ gnttab_setup_table( >> } >> gt->maptrack_pages = 0; >> >> + /* Tracking of mapped foreign frames table */ >> + if ( (gt->maptrack = xzalloc_array(struct grant_mapping *, >> + max_maptrack_frames * d->max_vcpus)) >> == NULL ) >> + goto out2; > > See the comments on the similar misplaced hunk in the previous > patch. > >> --- a/xen/include/xen/grant_table.h >> +++ b/xen/include/xen/grant_table.h >> @@ -60,6 +60,8 @@ struct grant_mapping { >> u32 ref; /* grant ref */ >> u16 flags; /* 0-4: GNTMAP_* ; 5-15: unused */ >> domid_t domid; /* granting domain */ >> + u32 vcpu; /* vcpu which created the grant mapping */ >> + u16 pad[2]; >> }; > > What is this pad[] good for? The pad is to keep the struct power of 2 sized because this allows the compiler to optimise these macro's to right and left shifts: #define MAPTRACK_PER_PAGE (PAGE_SIZE / sizeof(struct grant_mapping)) #define maptrack_entry(t, e) \ ((t)->maptrack[(e)/MAPTRACK_PER_PAGE][(e)%MAPTRACK_PER_PAGE]) Malcolm > > Jan > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |