[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 2/2] gnttab: refactor locking for scalability
>>> On 10.02.15 at 13:51, <chegger@xxxxxxxxx> wrote: > @@ -188,6 +191,28 @@ nr_active_grant_frames(struct grant_table *gt) > return num_act_frames_from_sha_frames(nr_grant_frames(gt)); > } > > +static inline struct active_grant_entry * > +active_entry_acquire(struct grant_table *t, grant_ref_t e) > +{ > + struct active_grant_entry *act; > + > + /* > + * not perfect, but better than nothing for a debug build > + * sanity check > + */ Better, but still not matching ./CODING_STYLE. > @@ -316,7 +317,10 @@ get_maptrack_handle( > return handle; > } > > -/* Number of grant table entries. Caller must hold d's grant table lock. */ > +/* > + * Number of grant table entries. Caller must hold d's grant table > + * read lock. > + */ > static unsigned int nr_grant_entries(struct grant_table *gt) Doesn't this belong in patch 1? > @@ -505,26 +509,23 @@ static int grant_map_exists(const struct domain *ld, > unsigned long mfn, > unsigned int *ref_count) > { > - const struct active_grant_entry *act; > + struct active_grant_entry *act; > unsigned int ref, max_iter; > > ASSERT(rw_is_locked(&rgt->lock)); > > max_iter = min(*ref_count + (1 << GNTTABOP_CONTINUATION_ARG_SHIFT), > nr_grant_entries(rgt)); > - for ( ref = *ref_count; ref < max_iter; ref++ ) > + for ( ref = *ref_count; ref < max_iter; active_entry_release(act), ref++ > ) > { > - act = &active_entry(rgt, ref); > + act = active_entry_acquire(rgt, ref); > > - if ( !act->pin ) > - continue; > - > - if ( act->domid != ld->domain_id ) > - continue; > - > - if ( act->frame != mfn ) > + if ( !act->pin || > + act->domid != ld->domain_id || > + act->frame != mfn ) > continue; I don't mind this consolidation, but it does grow the patch size without real need. > for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) > { > + struct active_grant_entry *act; > + > map = &maptrack_entry(lgt, handle); > if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) || > map->domid != rd->domain_id ) > continue; > - if ( active_entry(rd->grant_table, map->ref).frame == mfn ) > + act = &_active_entry(rd->grant_table, map->ref); > + if ( act->frame == mfn ) > (map->flags & GNTMAP_readonly) ? (*rdc)++ : (*wrc)++; > } Yet here I don't understand at all what the change is good for - the only thing you appear to need to change is to insert an underscore. > @@ -2601,9 +2637,17 @@ __gnttab_swap_grant_ref(grant_ref_t ref_a, grant_ref_t > ref_b) > { > struct domain *d = rcu_lock_current_domain(); > struct grant_table *gt = d->grant_table; > - struct active_grant_entry *act; > + struct active_grant_entry *act_a = NULL; > + struct active_grant_entry *act_b = NULL; > s16 rc = GNTST_okay; > > + if ( ref_a == ref_b ) > + /* > + * noop, so avoid acquiring the same active entry > + * twice which would case a deadlock. cause > @@ -2953,7 +3001,7 @@ grant_table_create( > struct domain *d) > { > struct grant_table *t; > - int i; > + int i, j; unsigned int > @@ -3195,9 +3244,12 @@ static void gnttab_usage_print(struct domain *rd) > uint16_t status; > uint64_t frame; > > - act = &active_entry(gt, ref); > + act = active_entry_acquire(gt, ref); As (again in a different context) said recently, debug key handlers would better use try-lock variants, skipping the respective printing if the lock is being held. And to come back to a remark on v3 and v4: Considering that you drop double_maptrack_lock() here altogether, is patch 1 really correct/sensible in introducing that function in place of double_gt_lock()? Wouldn't the new functionality want the local maptrack and the remote grant table locked in such cases? I.e. isn't one of the locks taken at least pointless? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |