Message ID | 20210928084446.22580-2-tzimmermann@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/gma500: Refactor GEM code | expand |
On Tue, Sep 28, 2021 at 10:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote: > > Allocation and pinning helpers for struct gtt_range are GEM functions, > so move them to gem.c. No functional changes. > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > --- > drivers/gpu/drm/gma500/framebuffer.c | 1 - > drivers/gpu/drm/gma500/gem.c | 133 +++++++++++++-- > drivers/gpu/drm/gma500/gem.h | 8 + > drivers/gpu/drm/gma500/gma_display.c | 1 + > drivers/gpu/drm/gma500/gtt.c | 190 +-------------------- > drivers/gpu/drm/gma500/gtt.h | 11 +- > drivers/gpu/drm/gma500/psb_intel_display.c | 1 + > 7 files changed, 136 insertions(+), 209 deletions(-) > > diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c > index 321e416489a9..ce92d11bd20f 100644 > --- a/drivers/gpu/drm/gma500/framebuffer.c > +++ b/drivers/gpu/drm/gma500/framebuffer.c > @@ -25,7 +25,6 @@ > > #include "framebuffer.h" > #include "gem.h" > -#include "gtt.h" > #include "psb_drv.h" > #include "psb_intel_drv.h" > #include "psb_intel_reg.h" > diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c > index 5ae54c9d2819..734bcb7a80c8 100644 > --- a/drivers/gpu/drm/gma500/gem.c > +++ b/drivers/gpu/drm/gma500/gem.c > @@ -19,6 +19,89 @@ > #include "gem.h" > #include "psb_drv.h" > > +static int psb_gtt_attach_pages(struct gtt_range *gt) > +{ > + struct page **pages; > + > + WARN_ON(gt->pages); > + > + pages = drm_gem_get_pages(>->gem); > + if (IS_ERR(pages)) > + return PTR_ERR(pages); > + > + gt->npage = gt->gem.size / PAGE_SIZE; > + gt->pages = pages; > + > + return 0; > +} > + > +static void psb_gtt_detach_pages(struct gtt_range *gt) > +{ > + drm_gem_put_pages(>->gem, gt->pages, true, false); > + gt->pages = NULL; > +} > + > +int psb_gtt_pin(struct gtt_range *gt) > +{ > + int ret = 0; > + struct drm_device *dev = gt->gem.dev; > + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > + u32 gpu_base = dev_priv->gtt.gatt_start; > + > + mutex_lock(&dev_priv->gtt_mutex); > + > + if (gt->in_gart == 0 && gt->stolen == 0) { > + ret = psb_gtt_attach_pages(gt); > + if (ret < 0) > + goto out; > + ret = psb_gtt_insert(dev, gt, 0); > + if (ret < 0) { > + psb_gtt_detach_pages(gt); > + goto out; > + } > + psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), > + gt->pages, (gpu_base + gt->offset), > + gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); > + } > + gt->in_gart++; > +out: > + mutex_unlock(&dev_priv->gtt_mutex); > + return ret; > +} > + > +void psb_gtt_unpin(struct gtt_range *gt) > +{ > + struct drm_device *dev = gt->gem.dev; > + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > + u32 gpu_base = dev_priv->gtt.gatt_start; > + > + mutex_lock(&dev_priv->gtt_mutex); > + > + WARN_ON(!gt->in_gart); > + > + gt->in_gart--; > + if (gt->in_gart == 0 && gt->stolen == 0) { > + psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), > + (gpu_base + gt->offset), gt->npage, 0, 0); > + psb_gtt_remove(dev, gt); > + psb_gtt_detach_pages(gt); > + } > + > + mutex_unlock(&dev_priv->gtt_mutex); > +} > + > +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) > +{ > + /* Undo the mmap pin if we are destroying the object */ > + if (gt->mmapping) { > + psb_gtt_unpin(gt); > + gt->mmapping = 0; > + } > + WARN_ON(gt->in_gart && !gt->stolen); > + release_resource(>->resource); > + kfree(gt); > +} > + > static vm_fault_t psb_gem_fault(struct vm_fault *vmf); > > static void psb_gem_free_object(struct drm_gem_object *obj) > @@ -44,19 +127,43 @@ const struct drm_gem_object_funcs psb_gem_object_funcs = { > .vm_ops = &psb_gem_vm_ops, > }; > > -/** > - * psb_gem_create - create a mappable object > - * @file: the DRM file of the client > - * @dev: our device > - * @size: the size requested > - * @handlep: returned handle (opaque number) > - * @stolen: unused > - * @align: unused > - * > - * Create a GEM object, fill in the boilerplate and attach a handle to > - * it so that userspace can speak about it. This does the core work > - * for the various methods that do/will create GEM objects for things > - */ > +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, > + const char *name, int backed, u32 align) > +{ > + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > + struct gtt_range *gt; > + struct resource *r = dev_priv->gtt_mem; > + int ret; > + unsigned long start, end; > + > + if (backed) { > + /* The start of the GTT is the stolen pages */ > + start = r->start; > + end = r->start + dev_priv->gtt.stolen_size - 1; > + } else { > + /* The rest we will use for GEM backed objects */ > + start = r->start + dev_priv->gtt.stolen_size; > + end = r->end; > + } > + > + gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); > + if (gt == NULL) > + return NULL; > + gt->resource.name = name; > + gt->stolen = backed; > + gt->in_gart = backed; > + /* Ensure this is set for non GEM objects */ > + gt->gem.dev = dev; > + ret = allocate_resource(dev_priv->gtt_mem, >->resource, > + len, start, end, align, NULL, NULL); Not something for this patch but I think we're missing locking around resource alloc and release. > + if (ret == 0) { > + gt->offset = gt->resource.start - r->start; > + return gt; > + } > + kfree(gt); > + return NULL; > +} > + > int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, > u32 *handlep, int stolen, u32 align) > { > diff --git a/drivers/gpu/drm/gma500/gem.h b/drivers/gpu/drm/gma500/gem.h > index bae6454ead29..275494aedd4c 100644 > --- a/drivers/gpu/drm/gma500/gem.h > +++ b/drivers/gpu/drm/gma500/gem.h > @@ -8,6 +8,8 @@ > #ifndef _GEM_H > #define _GEM_H > > +#include <drm/drm_gem.h> > + > struct drm_device; > > extern const struct drm_gem_object_funcs psb_gem_object_funcs; > @@ -15,4 +17,10 @@ extern const struct drm_gem_object_funcs psb_gem_object_funcs; > extern int psb_gem_create(struct drm_file *file, struct drm_device *dev, > u64 size, u32 *handlep, int stolen, u32 align); > > +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, const char *name, > + int backed, u32 align); > +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); > +int psb_gtt_pin(struct gtt_range *gt); > +void psb_gtt_unpin(struct gtt_range *gt); > + > #endif > diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c > index cbcecbaa041b..ecf8153416ac 100644 > --- a/drivers/gpu/drm/gma500/gma_display.c > +++ b/drivers/gpu/drm/gma500/gma_display.c > @@ -15,6 +15,7 @@ > #include <drm/drm_vblank.h> > > #include "framebuffer.h" > +#include "gem.h" > #include "gma_display.h" > #include "psb_drv.h" > #include "psb_intel_drv.h" > diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c > index 55a2a6919533..0aacf7122e32 100644 > --- a/drivers/gpu/drm/gma500/gtt.c > +++ b/drivers/gpu/drm/gma500/gtt.c > @@ -71,8 +71,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) > * the GTT. This is protected via the gtt mutex which the caller > * must hold. > */ > -static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, > - int resume) > +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume) > { > u32 __iomem *gtt_slot; > u32 pte; > @@ -116,7 +115,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, > * page table entries with the dummy page. This is protected via the gtt > * mutex which the caller must hold. > */ > -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) > +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) > { > struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > u32 __iomem *gtt_slot; > @@ -135,191 +134,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) > set_pages_array_wb(r->pages, r->npage); > } > > -/** > - * psb_gtt_attach_pages - attach and pin GEM pages > - * @gt: the gtt range > - * > - * Pin and build an in kernel list of the pages that back our GEM object. > - * While we hold this the pages cannot be swapped out. This is protected > - * via the gtt mutex which the caller must hold. > - */ The documentation about locking is still relevant. I'm not a big fan of documenting the obvious but locking is an exception. > -static int psb_gtt_attach_pages(struct gtt_range *gt) > -{ > - struct page **pages; > - > - WARN_ON(gt->pages); > - > - pages = drm_gem_get_pages(>->gem); > - if (IS_ERR(pages)) > - return PTR_ERR(pages); > - > - gt->npage = gt->gem.size / PAGE_SIZE; > - gt->pages = pages; > - > - return 0; > -} > - > -/** > - * psb_gtt_detach_pages - attach and pin GEM pages > - * @gt: the gtt range > - * > - * Undo the effect of psb_gtt_attach_pages. At this point the pages > - * must have been removed from the GTT as they could now be paged out > - * and move bus address. This is protected via the gtt mutex which the > - * caller must hold. > - */ Same thing about locking here > -static void psb_gtt_detach_pages(struct gtt_range *gt) > -{ > - drm_gem_put_pages(>->gem, gt->pages, true, false); > - gt->pages = NULL; > -} > - > -/** > - * psb_gtt_pin - pin pages into the GTT > - * @gt: range to pin > - * > - * Pin a set of pages into the GTT. The pins are refcounted so that > - * multiple pins need multiple unpins to undo. > - * > - * Non GEM backed objects treat this as a no-op as they are always GTT > - * backed objects. > - */ > -int psb_gtt_pin(struct gtt_range *gt) > -{ > - int ret = 0; > - struct drm_device *dev = gt->gem.dev; > - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > - u32 gpu_base = dev_priv->gtt.gatt_start; > - > - mutex_lock(&dev_priv->gtt_mutex); > - > - if (gt->in_gart == 0 && gt->stolen == 0) { > - ret = psb_gtt_attach_pages(gt); > - if (ret < 0) > - goto out; > - ret = psb_gtt_insert(dev, gt, 0); > - if (ret < 0) { > - psb_gtt_detach_pages(gt); > - goto out; > - } > - psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), > - gt->pages, (gpu_base + gt->offset), > - gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); > - } > - gt->in_gart++; > -out: > - mutex_unlock(&dev_priv->gtt_mutex); > - return ret; > -} > - > -/** > - * psb_gtt_unpin - Drop a GTT pin requirement > - * @gt: range to pin > - * > - * Undoes the effect of psb_gtt_pin. On the last drop the GEM object > - * will be removed from the GTT which will also drop the page references > - * and allow the VM to clean up or page stuff. > - * > - * Non GEM backed objects treat this as a no-op as they are always GTT > - * backed objects. > - */ > -void psb_gtt_unpin(struct gtt_range *gt) > -{ > - struct drm_device *dev = gt->gem.dev; > - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > - u32 gpu_base = dev_priv->gtt.gatt_start; > - > - mutex_lock(&dev_priv->gtt_mutex); > - > - WARN_ON(!gt->in_gart); > - > - gt->in_gart--; > - if (gt->in_gart == 0 && gt->stolen == 0) { > - psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), > - (gpu_base + gt->offset), gt->npage, 0, 0); > - psb_gtt_remove(dev, gt); > - psb_gtt_detach_pages(gt); > - } > - > - mutex_unlock(&dev_priv->gtt_mutex); > -} > - > -/* > - * GTT resource allocator - allocate and manage GTT address space > - */ > - > -/** > - * psb_gtt_alloc_range - allocate GTT address space > - * @dev: Our DRM device > - * @len: length (bytes) of address space required > - * @name: resource name > - * @backed: resource should be backed by stolen pages > - * @align: requested alignment > - * > - * Ask the kernel core to find us a suitable range of addresses > - * to use for a GTT mapping. > - * > - * Returns a gtt_range structure describing the object, or NULL on > - * error. On successful return the resource is both allocated and marked > - * as in use. > - */ > -struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, > - const char *name, int backed, u32 align) > -{ > - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > - struct gtt_range *gt; > - struct resource *r = dev_priv->gtt_mem; > - int ret; > - unsigned long start, end; > - > - if (backed) { > - /* The start of the GTT is the stolen pages */ > - start = r->start; > - end = r->start + dev_priv->gtt.stolen_size - 1; > - } else { > - /* The rest we will use for GEM backed objects */ > - start = r->start + dev_priv->gtt.stolen_size; > - end = r->end; > - } > - > - gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); > - if (gt == NULL) > - return NULL; > - gt->resource.name = name; > - gt->stolen = backed; > - gt->in_gart = backed; > - /* Ensure this is set for non GEM objects */ > - gt->gem.dev = dev; > - ret = allocate_resource(dev_priv->gtt_mem, >->resource, > - len, start, end, align, NULL, NULL); > - if (ret == 0) { > - gt->offset = gt->resource.start - r->start; > - return gt; > - } > - kfree(gt); > - return NULL; > -} > - > -/** > - * psb_gtt_free_range - release GTT address space > - * @dev: our DRM device > - * @gt: a mapping created with psb_gtt_alloc_range > - * > - * Release a resource that was allocated with psb_gtt_alloc_range. If the > - * object has been pinned by mmap users we clean this up here currently. > - */ > -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) > -{ > - /* Undo the mmap pin if we are destroying the object */ > - if (gt->mmapping) { > - psb_gtt_unpin(gt); > - gt->mmapping = 0; > - } > - WARN_ON(gt->in_gart && !gt->stolen); > - release_resource(>->resource); > - kfree(gt); > -} > - > static void psb_gtt_alloc(struct drm_device *dev) > { > struct drm_psb_private *dev_priv = to_drm_psb_private(dev); > diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h > index 2bf165849ebe..36162b545570 100644 > --- a/drivers/gpu/drm/gma500/gtt.h > +++ b/drivers/gpu/drm/gma500/gtt.h > @@ -41,12 +41,9 @@ struct gtt_range { > > #define to_gtt_range(x) container_of(x, struct gtt_range, gem) > > -extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, > - const char *name, int backed, > - u32 align); > -extern void psb_gtt_kref_put(struct gtt_range *gt); > -extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); > -extern int psb_gtt_pin(struct gtt_range *gt); > -extern void psb_gtt_unpin(struct gtt_range *gt); > extern int psb_gtt_restore(struct drm_device *dev); > + > +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume); > +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r); > + > #endif > diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c > index f5f259fde88e..18d5f7e5889e 100644 > --- a/drivers/gpu/drm/gma500/psb_intel_display.c > +++ b/drivers/gpu/drm/gma500/psb_intel_display.c > @@ -12,6 +12,7 @@ > #include <drm/drm_plane_helper.h> > > #include "framebuffer.h" > +#include "gem.h" > #include "gma_display.h" > #include "power.h" > #include "psb_drv.h" > -- > 2.33.0 >
Hi Am 03.10.21 um 00:13 schrieb Patrik Jakobsson: > On Tue, Sep 28, 2021 at 10:44 AM Thomas Zimmermann <tzimmermann@suse.de> wrote: >> >> Allocation and pinning helpers for struct gtt_range are GEM functions, >> so move them to gem.c. No functional changes. >> >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >> --- >> drivers/gpu/drm/gma500/framebuffer.c | 1 - >> drivers/gpu/drm/gma500/gem.c | 133 +++++++++++++-- >> drivers/gpu/drm/gma500/gem.h | 8 + >> drivers/gpu/drm/gma500/gma_display.c | 1 + >> drivers/gpu/drm/gma500/gtt.c | 190 +-------------------- >> drivers/gpu/drm/gma500/gtt.h | 11 +- >> drivers/gpu/drm/gma500/psb_intel_display.c | 1 + >> 7 files changed, 136 insertions(+), 209 deletions(-) >> >> diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c >> index 321e416489a9..ce92d11bd20f 100644 >> --- a/drivers/gpu/drm/gma500/framebuffer.c >> +++ b/drivers/gpu/drm/gma500/framebuffer.c >> @@ -25,7 +25,6 @@ >> >> #include "framebuffer.h" >> #include "gem.h" >> -#include "gtt.h" >> #include "psb_drv.h" >> #include "psb_intel_drv.h" >> #include "psb_intel_reg.h" >> diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c >> index 5ae54c9d2819..734bcb7a80c8 100644 >> --- a/drivers/gpu/drm/gma500/gem.c >> +++ b/drivers/gpu/drm/gma500/gem.c >> @@ -19,6 +19,89 @@ >> #include "gem.h" >> #include "psb_drv.h" >> >> +static int psb_gtt_attach_pages(struct gtt_range *gt) >> +{ >> + struct page **pages; >> + >> + WARN_ON(gt->pages); >> + >> + pages = drm_gem_get_pages(>->gem); >> + if (IS_ERR(pages)) >> + return PTR_ERR(pages); >> + >> + gt->npage = gt->gem.size / PAGE_SIZE; >> + gt->pages = pages; >> + >> + return 0; >> +} >> + >> +static void psb_gtt_detach_pages(struct gtt_range *gt) >> +{ >> + drm_gem_put_pages(>->gem, gt->pages, true, false); >> + gt->pages = NULL; >> +} >> + >> +int psb_gtt_pin(struct gtt_range *gt) >> +{ >> + int ret = 0; >> + struct drm_device *dev = gt->gem.dev; >> + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> + u32 gpu_base = dev_priv->gtt.gatt_start; >> + >> + mutex_lock(&dev_priv->gtt_mutex); >> + >> + if (gt->in_gart == 0 && gt->stolen == 0) { >> + ret = psb_gtt_attach_pages(gt); >> + if (ret < 0) >> + goto out; >> + ret = psb_gtt_insert(dev, gt, 0); >> + if (ret < 0) { >> + psb_gtt_detach_pages(gt); >> + goto out; >> + } >> + psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), >> + gt->pages, (gpu_base + gt->offset), >> + gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); >> + } >> + gt->in_gart++; >> +out: >> + mutex_unlock(&dev_priv->gtt_mutex); >> + return ret; >> +} >> + >> +void psb_gtt_unpin(struct gtt_range *gt) >> +{ >> + struct drm_device *dev = gt->gem.dev; >> + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> + u32 gpu_base = dev_priv->gtt.gatt_start; >> + >> + mutex_lock(&dev_priv->gtt_mutex); >> + >> + WARN_ON(!gt->in_gart); >> + >> + gt->in_gart--; >> + if (gt->in_gart == 0 && gt->stolen == 0) { >> + psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), >> + (gpu_base + gt->offset), gt->npage, 0, 0); >> + psb_gtt_remove(dev, gt); >> + psb_gtt_detach_pages(gt); >> + } >> + >> + mutex_unlock(&dev_priv->gtt_mutex); >> +} >> + >> +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) >> +{ >> + /* Undo the mmap pin if we are destroying the object */ >> + if (gt->mmapping) { >> + psb_gtt_unpin(gt); >> + gt->mmapping = 0; >> + } >> + WARN_ON(gt->in_gart && !gt->stolen); >> + release_resource(>->resource); >> + kfree(gt); >> +} >> + >> static vm_fault_t psb_gem_fault(struct vm_fault *vmf); >> >> static void psb_gem_free_object(struct drm_gem_object *obj) >> @@ -44,19 +127,43 @@ const struct drm_gem_object_funcs psb_gem_object_funcs = { >> .vm_ops = &psb_gem_vm_ops, >> }; >> >> -/** >> - * psb_gem_create - create a mappable object >> - * @file: the DRM file of the client >> - * @dev: our device >> - * @size: the size requested >> - * @handlep: returned handle (opaque number) >> - * @stolen: unused >> - * @align: unused >> - * >> - * Create a GEM object, fill in the boilerplate and attach a handle to >> - * it so that userspace can speak about it. This does the core work >> - * for the various methods that do/will create GEM objects for things >> - */ >> +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, >> + const char *name, int backed, u32 align) >> +{ >> + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> + struct gtt_range *gt; >> + struct resource *r = dev_priv->gtt_mem; >> + int ret; >> + unsigned long start, end; >> + >> + if (backed) { >> + /* The start of the GTT is the stolen pages */ >> + start = r->start; >> + end = r->start + dev_priv->gtt.stolen_size - 1; >> + } else { >> + /* The rest we will use for GEM backed objects */ >> + start = r->start + dev_priv->gtt.stolen_size; >> + end = r->end; >> + } >> + >> + gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); >> + if (gt == NULL) >> + return NULL; >> + gt->resource.name = name; >> + gt->stolen = backed; >> + gt->in_gart = backed; >> + /* Ensure this is set for non GEM objects */ >> + gt->gem.dev = dev; >> + ret = allocate_resource(dev_priv->gtt_mem, >->resource, >> + len, start, end, align, NULL, NULL); > > Not something for this patch but I think we're missing locking around > resource alloc and release. There's a lock being taken within the function. [1] > >> + if (ret == 0) { >> + gt->offset = gt->resource.start - r->start; >> + return gt; >> + } >> + kfree(gt); >> + return NULL; >> +} >> + >> int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, >> u32 *handlep, int stolen, u32 align) >> { >> diff --git a/drivers/gpu/drm/gma500/gem.h b/drivers/gpu/drm/gma500/gem.h >> index bae6454ead29..275494aedd4c 100644 >> --- a/drivers/gpu/drm/gma500/gem.h >> +++ b/drivers/gpu/drm/gma500/gem.h >> @@ -8,6 +8,8 @@ >> #ifndef _GEM_H >> #define _GEM_H >> >> +#include <drm/drm_gem.h> >> + >> struct drm_device; >> >> extern const struct drm_gem_object_funcs psb_gem_object_funcs; >> @@ -15,4 +17,10 @@ extern const struct drm_gem_object_funcs psb_gem_object_funcs; >> extern int psb_gem_create(struct drm_file *file, struct drm_device *dev, >> u64 size, u32 *handlep, int stolen, u32 align); >> >> +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, const char *name, >> + int backed, u32 align); >> +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); >> +int psb_gtt_pin(struct gtt_range *gt); >> +void psb_gtt_unpin(struct gtt_range *gt); >> + >> #endif >> diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c >> index cbcecbaa041b..ecf8153416ac 100644 >> --- a/drivers/gpu/drm/gma500/gma_display.c >> +++ b/drivers/gpu/drm/gma500/gma_display.c >> @@ -15,6 +15,7 @@ >> #include <drm/drm_vblank.h> >> >> #include "framebuffer.h" >> +#include "gem.h" >> #include "gma_display.h" >> #include "psb_drv.h" >> #include "psb_intel_drv.h" >> diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c >> index 55a2a6919533..0aacf7122e32 100644 >> --- a/drivers/gpu/drm/gma500/gtt.c >> +++ b/drivers/gpu/drm/gma500/gtt.c >> @@ -71,8 +71,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) >> * the GTT. This is protected via the gtt mutex which the caller >> * must hold. >> */ >> -static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, >> - int resume) >> +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume) >> { >> u32 __iomem *gtt_slot; >> u32 pte; >> @@ -116,7 +115,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, >> * page table entries with the dummy page. This is protected via the gtt >> * mutex which the caller must hold. >> */ >> -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) >> +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) >> { >> struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> u32 __iomem *gtt_slot; >> @@ -135,191 +134,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) >> set_pages_array_wb(r->pages, r->npage); >> } >> >> -/** >> - * psb_gtt_attach_pages - attach and pin GEM pages >> - * @gt: the gtt range >> - * >> - * Pin and build an in kernel list of the pages that back our GEM object. >> - * While we hold this the pages cannot be swapped out. This is protected >> - * via the gtt mutex which the caller must hold. >> - */ > > The documentation about locking is still relevant. I'm not a big fan > of documenting the obvious but locking is an exception. Make sense. I'll reduce the kerneldoc comment to the notes on locking. Best regards Thomas [1] https://elixir.bootlin.com/linux/latest/source/kernel/resource.c#L745 > >> -static int psb_gtt_attach_pages(struct gtt_range *gt) >> -{ >> - struct page **pages; >> - >> - WARN_ON(gt->pages); >> - >> - pages = drm_gem_get_pages(>->gem); >> - if (IS_ERR(pages)) >> - return PTR_ERR(pages); >> - >> - gt->npage = gt->gem.size / PAGE_SIZE; >> - gt->pages = pages; >> - >> - return 0; >> -} >> - >> -/** >> - * psb_gtt_detach_pages - attach and pin GEM pages >> - * @gt: the gtt range >> - * >> - * Undo the effect of psb_gtt_attach_pages. At this point the pages >> - * must have been removed from the GTT as they could now be paged out >> - * and move bus address. This is protected via the gtt mutex which the >> - * caller must hold. >> - */ > > Same thing about locking here > > >> -static void psb_gtt_detach_pages(struct gtt_range *gt) >> -{ >> - drm_gem_put_pages(>->gem, gt->pages, true, false); >> - gt->pages = NULL; >> -} >> - >> -/** >> - * psb_gtt_pin - pin pages into the GTT >> - * @gt: range to pin >> - * >> - * Pin a set of pages into the GTT. The pins are refcounted so that >> - * multiple pins need multiple unpins to undo. >> - * >> - * Non GEM backed objects treat this as a no-op as they are always GTT >> - * backed objects. >> - */ >> -int psb_gtt_pin(struct gtt_range *gt) >> -{ >> - int ret = 0; >> - struct drm_device *dev = gt->gem.dev; >> - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> - u32 gpu_base = dev_priv->gtt.gatt_start; >> - >> - mutex_lock(&dev_priv->gtt_mutex); >> - >> - if (gt->in_gart == 0 && gt->stolen == 0) { >> - ret = psb_gtt_attach_pages(gt); >> - if (ret < 0) >> - goto out; >> - ret = psb_gtt_insert(dev, gt, 0); >> - if (ret < 0) { >> - psb_gtt_detach_pages(gt); >> - goto out; >> - } >> - psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), >> - gt->pages, (gpu_base + gt->offset), >> - gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); >> - } >> - gt->in_gart++; >> -out: >> - mutex_unlock(&dev_priv->gtt_mutex); >> - return ret; >> -} >> - >> -/** >> - * psb_gtt_unpin - Drop a GTT pin requirement >> - * @gt: range to pin >> - * >> - * Undoes the effect of psb_gtt_pin. On the last drop the GEM object >> - * will be removed from the GTT which will also drop the page references >> - * and allow the VM to clean up or page stuff. >> - * >> - * Non GEM backed objects treat this as a no-op as they are always GTT >> - * backed objects. >> - */ >> -void psb_gtt_unpin(struct gtt_range *gt) >> -{ >> - struct drm_device *dev = gt->gem.dev; >> - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> - u32 gpu_base = dev_priv->gtt.gatt_start; >> - >> - mutex_lock(&dev_priv->gtt_mutex); >> - >> - WARN_ON(!gt->in_gart); >> - >> - gt->in_gart--; >> - if (gt->in_gart == 0 && gt->stolen == 0) { >> - psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), >> - (gpu_base + gt->offset), gt->npage, 0, 0); >> - psb_gtt_remove(dev, gt); >> - psb_gtt_detach_pages(gt); >> - } >> - >> - mutex_unlock(&dev_priv->gtt_mutex); >> -} >> - >> -/* >> - * GTT resource allocator - allocate and manage GTT address space >> - */ >> - >> -/** >> - * psb_gtt_alloc_range - allocate GTT address space >> - * @dev: Our DRM device >> - * @len: length (bytes) of address space required >> - * @name: resource name >> - * @backed: resource should be backed by stolen pages >> - * @align: requested alignment >> - * >> - * Ask the kernel core to find us a suitable range of addresses >> - * to use for a GTT mapping. >> - * >> - * Returns a gtt_range structure describing the object, or NULL on >> - * error. On successful return the resource is both allocated and marked >> - * as in use. >> - */ >> -struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, >> - const char *name, int backed, u32 align) >> -{ >> - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> - struct gtt_range *gt; >> - struct resource *r = dev_priv->gtt_mem; >> - int ret; >> - unsigned long start, end; >> - >> - if (backed) { >> - /* The start of the GTT is the stolen pages */ >> - start = r->start; >> - end = r->start + dev_priv->gtt.stolen_size - 1; >> - } else { >> - /* The rest we will use for GEM backed objects */ >> - start = r->start + dev_priv->gtt.stolen_size; >> - end = r->end; >> - } >> - >> - gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); >> - if (gt == NULL) >> - return NULL; >> - gt->resource.name = name; >> - gt->stolen = backed; >> - gt->in_gart = backed; >> - /* Ensure this is set for non GEM objects */ >> - gt->gem.dev = dev; >> - ret = allocate_resource(dev_priv->gtt_mem, >->resource, >> - len, start, end, align, NULL, NULL); >> - if (ret == 0) { >> - gt->offset = gt->resource.start - r->start; >> - return gt; >> - } >> - kfree(gt); >> - return NULL; >> -} >> - >> -/** >> - * psb_gtt_free_range - release GTT address space >> - * @dev: our DRM device >> - * @gt: a mapping created with psb_gtt_alloc_range >> - * >> - * Release a resource that was allocated with psb_gtt_alloc_range. If the >> - * object has been pinned by mmap users we clean this up here currently. >> - */ >> -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) >> -{ >> - /* Undo the mmap pin if we are destroying the object */ >> - if (gt->mmapping) { >> - psb_gtt_unpin(gt); >> - gt->mmapping = 0; >> - } >> - WARN_ON(gt->in_gart && !gt->stolen); >> - release_resource(>->resource); >> - kfree(gt); >> -} >> - >> static void psb_gtt_alloc(struct drm_device *dev) >> { >> struct drm_psb_private *dev_priv = to_drm_psb_private(dev); >> diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h >> index 2bf165849ebe..36162b545570 100644 >> --- a/drivers/gpu/drm/gma500/gtt.h >> +++ b/drivers/gpu/drm/gma500/gtt.h >> @@ -41,12 +41,9 @@ struct gtt_range { >> >> #define to_gtt_range(x) container_of(x, struct gtt_range, gem) >> >> -extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, >> - const char *name, int backed, >> - u32 align); >> -extern void psb_gtt_kref_put(struct gtt_range *gt); >> -extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); >> -extern int psb_gtt_pin(struct gtt_range *gt); >> -extern void psb_gtt_unpin(struct gtt_range *gt); >> extern int psb_gtt_restore(struct drm_device *dev); >> + >> +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume); >> +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r); >> + >> #endif >> diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c >> index f5f259fde88e..18d5f7e5889e 100644 >> --- a/drivers/gpu/drm/gma500/psb_intel_display.c >> +++ b/drivers/gpu/drm/gma500/psb_intel_display.c >> @@ -12,6 +12,7 @@ >> #include <drm/drm_plane_helper.h> >> >> #include "framebuffer.h" >> +#include "gem.h" >> #include "gma_display.h" >> #include "power.h" >> #include "psb_drv.h" >> -- >> 2.33.0 >>
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 321e416489a9..ce92d11bd20f 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -25,7 +25,6 @@ #include "framebuffer.h" #include "gem.h" -#include "gtt.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 5ae54c9d2819..734bcb7a80c8 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -19,6 +19,89 @@ #include "gem.h" #include "psb_drv.h" +static int psb_gtt_attach_pages(struct gtt_range *gt) +{ + struct page **pages; + + WARN_ON(gt->pages); + + pages = drm_gem_get_pages(>->gem); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + gt->npage = gt->gem.size / PAGE_SIZE; + gt->pages = pages; + + return 0; +} + +static void psb_gtt_detach_pages(struct gtt_range *gt) +{ + drm_gem_put_pages(>->gem, gt->pages, true, false); + gt->pages = NULL; +} + +int psb_gtt_pin(struct gtt_range *gt) +{ + int ret = 0; + struct drm_device *dev = gt->gem.dev; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + u32 gpu_base = dev_priv->gtt.gatt_start; + + mutex_lock(&dev_priv->gtt_mutex); + + if (gt->in_gart == 0 && gt->stolen == 0) { + ret = psb_gtt_attach_pages(gt); + if (ret < 0) + goto out; + ret = psb_gtt_insert(dev, gt, 0); + if (ret < 0) { + psb_gtt_detach_pages(gt); + goto out; + } + psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), + gt->pages, (gpu_base + gt->offset), + gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); + } + gt->in_gart++; +out: + mutex_unlock(&dev_priv->gtt_mutex); + return ret; +} + +void psb_gtt_unpin(struct gtt_range *gt) +{ + struct drm_device *dev = gt->gem.dev; + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + u32 gpu_base = dev_priv->gtt.gatt_start; + + mutex_lock(&dev_priv->gtt_mutex); + + WARN_ON(!gt->in_gart); + + gt->in_gart--; + if (gt->in_gart == 0 && gt->stolen == 0) { + psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), + (gpu_base + gt->offset), gt->npage, 0, 0); + psb_gtt_remove(dev, gt); + psb_gtt_detach_pages(gt); + } + + mutex_unlock(&dev_priv->gtt_mutex); +} + +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) +{ + /* Undo the mmap pin if we are destroying the object */ + if (gt->mmapping) { + psb_gtt_unpin(gt); + gt->mmapping = 0; + } + WARN_ON(gt->in_gart && !gt->stolen); + release_resource(>->resource); + kfree(gt); +} + static vm_fault_t psb_gem_fault(struct vm_fault *vmf); static void psb_gem_free_object(struct drm_gem_object *obj) @@ -44,19 +127,43 @@ const struct drm_gem_object_funcs psb_gem_object_funcs = { .vm_ops = &psb_gem_vm_ops, }; -/** - * psb_gem_create - create a mappable object - * @file: the DRM file of the client - * @dev: our device - * @size: the size requested - * @handlep: returned handle (opaque number) - * @stolen: unused - * @align: unused - * - * Create a GEM object, fill in the boilerplate and attach a handle to - * it so that userspace can speak about it. This does the core work - * for the various methods that do/will create GEM objects for things - */ +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, + const char *name, int backed, u32 align) +{ + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct gtt_range *gt; + struct resource *r = dev_priv->gtt_mem; + int ret; + unsigned long start, end; + + if (backed) { + /* The start of the GTT is the stolen pages */ + start = r->start; + end = r->start + dev_priv->gtt.stolen_size - 1; + } else { + /* The rest we will use for GEM backed objects */ + start = r->start + dev_priv->gtt.stolen_size; + end = r->end; + } + + gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); + if (gt == NULL) + return NULL; + gt->resource.name = name; + gt->stolen = backed; + gt->in_gart = backed; + /* Ensure this is set for non GEM objects */ + gt->gem.dev = dev; + ret = allocate_resource(dev_priv->gtt_mem, >->resource, + len, start, end, align, NULL, NULL); + if (ret == 0) { + gt->offset = gt->resource.start - r->start; + return gt; + } + kfree(gt); + return NULL; +} + int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, u32 *handlep, int stolen, u32 align) { diff --git a/drivers/gpu/drm/gma500/gem.h b/drivers/gpu/drm/gma500/gem.h index bae6454ead29..275494aedd4c 100644 --- a/drivers/gpu/drm/gma500/gem.h +++ b/drivers/gpu/drm/gma500/gem.h @@ -8,6 +8,8 @@ #ifndef _GEM_H #define _GEM_H +#include <drm/drm_gem.h> + struct drm_device; extern const struct drm_gem_object_funcs psb_gem_object_funcs; @@ -15,4 +17,10 @@ extern const struct drm_gem_object_funcs psb_gem_object_funcs; extern int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size, u32 *handlep, int stolen, u32 align); +struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, const char *name, + int backed, u32 align); +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); +int psb_gtt_pin(struct gtt_range *gt); +void psb_gtt_unpin(struct gtt_range *gt); + #endif diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index cbcecbaa041b..ecf8153416ac 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -15,6 +15,7 @@ #include <drm/drm_vblank.h> #include "framebuffer.h" +#include "gem.h" #include "gma_display.h" #include "psb_drv.h" #include "psb_intel_drv.h" diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 55a2a6919533..0aacf7122e32 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -71,8 +71,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) * the GTT. This is protected via the gtt mutex which the caller * must hold. */ -static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, - int resume) +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume) { u32 __iomem *gtt_slot; u32 pte; @@ -116,7 +115,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, * page table entries with the dummy page. This is protected via the gtt * mutex which the caller must hold. */ -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); u32 __iomem *gtt_slot; @@ -135,191 +134,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) set_pages_array_wb(r->pages, r->npage); } -/** - * psb_gtt_attach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Pin and build an in kernel list of the pages that back our GEM object. - * While we hold this the pages cannot be swapped out. This is protected - * via the gtt mutex which the caller must hold. - */ -static int psb_gtt_attach_pages(struct gtt_range *gt) -{ - struct page **pages; - - WARN_ON(gt->pages); - - pages = drm_gem_get_pages(>->gem); - if (IS_ERR(pages)) - return PTR_ERR(pages); - - gt->npage = gt->gem.size / PAGE_SIZE; - gt->pages = pages; - - return 0; -} - -/** - * psb_gtt_detach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Undo the effect of psb_gtt_attach_pages. At this point the pages - * must have been removed from the GTT as they could now be paged out - * and move bus address. This is protected via the gtt mutex which the - * caller must hold. - */ -static void psb_gtt_detach_pages(struct gtt_range *gt) -{ - drm_gem_put_pages(>->gem, gt->pages, true, false); - gt->pages = NULL; -} - -/** - * psb_gtt_pin - pin pages into the GTT - * @gt: range to pin - * - * Pin a set of pages into the GTT. The pins are refcounted so that - * multiple pins need multiple unpins to undo. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -int psb_gtt_pin(struct gtt_range *gt) -{ - int ret = 0; - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - u32 gpu_base = dev_priv->gtt.gatt_start; - - mutex_lock(&dev_priv->gtt_mutex); - - if (gt->in_gart == 0 && gt->stolen == 0) { - ret = psb_gtt_attach_pages(gt); - if (ret < 0) - goto out; - ret = psb_gtt_insert(dev, gt, 0); - if (ret < 0) { - psb_gtt_detach_pages(gt); - goto out; - } - psb_mmu_insert_pages(psb_mmu_get_default_pd(dev_priv->mmu), - gt->pages, (gpu_base + gt->offset), - gt->npage, 0, 0, PSB_MMU_CACHED_MEMORY); - } - gt->in_gart++; -out: - mutex_unlock(&dev_priv->gtt_mutex); - return ret; -} - -/** - * psb_gtt_unpin - Drop a GTT pin requirement - * @gt: range to pin - * - * Undoes the effect of psb_gtt_pin. On the last drop the GEM object - * will be removed from the GTT which will also drop the page references - * and allow the VM to clean up or page stuff. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -void psb_gtt_unpin(struct gtt_range *gt) -{ - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - u32 gpu_base = dev_priv->gtt.gatt_start; - - mutex_lock(&dev_priv->gtt_mutex); - - WARN_ON(!gt->in_gart); - - gt->in_gart--; - if (gt->in_gart == 0 && gt->stolen == 0) { - psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), - (gpu_base + gt->offset), gt->npage, 0, 0); - psb_gtt_remove(dev, gt); - psb_gtt_detach_pages(gt); - } - - mutex_unlock(&dev_priv->gtt_mutex); -} - -/* - * GTT resource allocator - allocate and manage GTT address space - */ - -/** - * psb_gtt_alloc_range - allocate GTT address space - * @dev: Our DRM device - * @len: length (bytes) of address space required - * @name: resource name - * @backed: resource should be backed by stolen pages - * @align: requested alignment - * - * Ask the kernel core to find us a suitable range of addresses - * to use for a GTT mapping. - * - * Returns a gtt_range structure describing the object, or NULL on - * error. On successful return the resource is both allocated and marked - * as in use. - */ -struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed, u32 align) -{ - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - struct gtt_range *gt; - struct resource *r = dev_priv->gtt_mem; - int ret; - unsigned long start, end; - - if (backed) { - /* The start of the GTT is the stolen pages */ - start = r->start; - end = r->start + dev_priv->gtt.stolen_size - 1; - } else { - /* The rest we will use for GEM backed objects */ - start = r->start + dev_priv->gtt.stolen_size; - end = r->end; - } - - gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); - if (gt == NULL) - return NULL; - gt->resource.name = name; - gt->stolen = backed; - gt->in_gart = backed; - /* Ensure this is set for non GEM objects */ - gt->gem.dev = dev; - ret = allocate_resource(dev_priv->gtt_mem, >->resource, - len, start, end, align, NULL, NULL); - if (ret == 0) { - gt->offset = gt->resource.start - r->start; - return gt; - } - kfree(gt); - return NULL; -} - -/** - * psb_gtt_free_range - release GTT address space - * @dev: our DRM device - * @gt: a mapping created with psb_gtt_alloc_range - * - * Release a resource that was allocated with psb_gtt_alloc_range. If the - * object has been pinned by mmap users we clean this up here currently. - */ -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) -{ - /* Undo the mmap pin if we are destroying the object */ - if (gt->mmapping) { - psb_gtt_unpin(gt); - gt->mmapping = 0; - } - WARN_ON(gt->in_gart && !gt->stolen); - release_resource(>->resource); - kfree(gt); -} - static void psb_gtt_alloc(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h index 2bf165849ebe..36162b545570 100644 --- a/drivers/gpu/drm/gma500/gtt.h +++ b/drivers/gpu/drm/gma500/gtt.h @@ -41,12 +41,9 @@ struct gtt_range { #define to_gtt_range(x) container_of(x, struct gtt_range, gem) -extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed, - u32 align); -extern void psb_gtt_kref_put(struct gtt_range *gt); -extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); -extern int psb_gtt_pin(struct gtt_range *gt); -extern void psb_gtt_unpin(struct gtt_range *gt); extern int psb_gtt_restore(struct drm_device *dev); + +int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r, int resume); +void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r); + #endif diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index f5f259fde88e..18d5f7e5889e 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -12,6 +12,7 @@ #include <drm/drm_plane_helper.h> #include "framebuffer.h" +#include "gem.h" #include "gma_display.h" #include "power.h" #include "psb_drv.h"
Allocation and pinning helpers for struct gtt_range are GEM functions, so move them to gem.c. No functional changes. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/gma500/framebuffer.c | 1 - drivers/gpu/drm/gma500/gem.c | 133 +++++++++++++-- drivers/gpu/drm/gma500/gem.h | 8 + drivers/gpu/drm/gma500/gma_display.c | 1 + drivers/gpu/drm/gma500/gtt.c | 190 +-------------------- drivers/gpu/drm/gma500/gtt.h | 11 +- drivers/gpu/drm/gma500/psb_intel_display.c | 1 + 7 files changed, 136 insertions(+), 209 deletions(-)