From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tvrtko Ursulin Subject: Re: [PATCH 1/2] drm/i915: Allow overlapping userptr objects Date: Thu, 10 Jul 2014 13:26:53 +0100 Message-ID: <53BE868D.8080301@linux.intel.com> References: <1404984104-27169-1-git-send-email-chris@chris-wilson.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id E8A326E1A9 for ; Thu, 10 Jul 2014 05:26:56 -0700 (PDT) In-Reply-To: <1404984104-27169-1-git-send-email-chris@chris-wilson.co.uk> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Chris Wilson , intel-gfx@lists.freedesktop.org Cc: Akash Goel List-Id: intel-gfx@lists.freedesktop.org On 07/10/2014 10:21 AM, Chris Wilson wrote: > Whilst I strongly advise against doing so for the implicit coherency > issues between the multiple buffer objects accessing the same backing > store, it nevertheless is a valid use case, akin to mmaping the same > file multiple times. > > The reason why we forbade it earlier was that our use of the interval > tree for fast invalidation upon vma changes excluded overlapping > objects. So in the case where the user wishes to create such pairs of > overlapping objects, we degrade the range invalidation to walkin the > linear list of objects associated with the mm. > > v2: Compile for mmu-notifiers after tweaking [snip] > +static void invalidate_range__linear(struct i915_mmu_notifier *mn, > + struct mm_struct *mm, > + unsigned long start, > + unsigned long end) > +{ > + struct i915_mmu_object *mmu; > + unsigned long serial; > + > +restart: > + serial = mn->serial; > + list_for_each_entry(mmu, &mn->linear, link) { > + struct drm_i915_gem_object *obj; > + > + if (mmu->it.last < start || mmu->it.start > end) > + continue; > + > + obj = mmu->obj; > + drm_gem_object_reference(&obj->base); > + spin_unlock(&mn->lock); > + > + cancel_userptr(obj); > + > + spin_lock(&mn->lock); > + if (serial != mn->serial) > + goto restart; > + } > + > + spin_unlock(&mn->lock); > +} > + > static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, > struct mm_struct *mm, > unsigned long start, > @@ -60,16 +128,19 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, > { > struct i915_mmu_notifier *mn = container_of(_mn, struct i915_mmu_notifier, mn); > struct interval_tree_node *it = NULL; > + unsigned long next = start; > unsigned long serial = 0; > > end--; /* interval ranges are inclusive, but invalidate range is exclusive */ > - while (start < end) { > + while (next < end) { > struct drm_i915_gem_object *obj; > > obj = NULL; > spin_lock(&mn->lock); > + if (mn->is_linear) > + return invalidate_range__linear(mn, mm, start, end); Too bad that on first overlapping object the whole process goes into "slow mode". I wonder what would benchmarking say to that. Perhaps we could still use interval tree but add another layer of indirection where ranges would be merged for overlapping objects and contain a linear list of them only there? Tvrtko