[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCHv7 1/3] gnttab: Introduce rwlock to protect updates to grant table state
>>> On 30.04.15 at 15:28, <david.vrabel@xxxxxxxxxx> wrote: > --- a/docs/misc/grant-tables.txt > +++ b/docs/misc/grant-tables.txt > @@ -74,7 +74,33 @@ is complete. > matching map track entry is then removed, as if unmap had been invoked. > These are not used by the transfer mechanism. > map->domid : owner of the mapped frame > - map->ref_and_flags : grant reference, ro/rw, mapped for host or device > access > + map->ref : grant reference > + map->flags : ro/rw, mapped for host or device access > + > +******************************************************************************** > + Locking > + ~~~~~~~ > + Xen uses several locks to serialize access to the internal grant table > state. > + > + grant_table->lock : rwlock used to prevent readers from accessing > + inconsistent grant table state such as current > + version, partially initialized active table > pages, > + etc. > + grant_table->maptrack_lock : spinlock used to protect the maptrack state > + > + The primary lock for the grant table is a read/write spinlock. All > + functions that access members of struct grant_table must acquire a > + read lock around critical sections. Any modification to the members > + of struct grant_table (e.g., nr_status_frames, nr_grant_frames, > + active frames, etc.) must only be made if the write lock is > + held. These elements are read-mostly, and read critical sections can > + be large, which makes a rwlock a good choice. > + > + The maptrack state is protected by its own spinlock. Any access (read > + or write) of struct grant_table members that have a "maptrack_" > + prefix must be made while holding the maptrack lock. The maptrack > + state can be rapidly modified under some workloads, and the critical > + sections are very small, thus we use a spinlock to protect them. Still no word about nesting between the two? > @@ -629,7 +629,7 @@ __gnttab_map_grant_ref( > } > > rgt = rd->grant_table; > - spin_lock(&rgt->lock); > + read_lock(&rgt->lock); > > if ( rgt->gt_version == 0 ) > PIN_FAIL(unlock_out, GNTST_general_error, > @@ -702,8 +702,6 @@ __gnttab_map_grant_ref( > > cache_flags = (shah->flags & (GTF_PAT | GTF_PWT | GTF_PCD) ); > > - spin_unlock(&rgt->lock); > - > /* pg may be set, with a refcount included, from __get_paged_frame */ > if ( !pg ) > { > @@ -778,7 +776,7 @@ __gnttab_map_grant_ref( > goto undo_out; > } > > - double_gt_lock(lgt, rgt); > + double_maptrack_lock(lgt, rgt); So looking just at the patch context here together with the two earlier hunks: You now keep holding the rwlock, but the code following the undo_out label read-locks the lock another time. > @@ -1290,10 +1294,14 @@ gnttab_unpopulate_status_frames(struct domain *d, > struct grant_table *gt) > gt->nr_status_frames = 0; > } > > +/* > + * Grow the grant table. The caller must hold the grant table's > + * write lock before calling this function. > + */ > int > gnttab_grow_table(struct domain *d, unsigned int req_nr_frames) > { > - /* d's grant table lock must be held by the caller */ > + /* d's grant table write lock must be held by the caller */ This comment is now redundant with the one you add ahead of the function. > @@ -3052,7 +3068,8 @@ gnttab_release_mappings( > } > > rgt = rd->grant_table; > - spin_lock(&rgt->lock); > + read_lock(&rgt->lock); > + double_maptrack_lock(gt, rgt); What is it that requires gt's maptrack lock to also be acquired here? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |