Message ID | 20190627205633.1143-8-matthew.auld@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce memory region concept (including device local memory) | expand |
Quoting Matthew Auld (2019-06-27 21:56:03) > We currently define LMEM, or local memory, as just another memory > region, like system memory or stolen, which we can expose to userspace > and can be mapped to the CPU via some BAR. > > Signed-off-by: Matthew Auld <matthew.auld@intel.com> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> > Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.h | 5 ++ > drivers/gpu/drm/i915/intel_region_lmem.c | 66 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_region_lmem.h | 16 +++++ You missed the mm/ vibes I was trying to send? ;) -Chris
Quoting Matthew Auld (2019-06-27 21:56:03) > We currently define LMEM, or local memory, as just another memory > region, like system memory or stolen, which we can expose to userspace > and can be mapped to the CPU via some BAR. > > Signed-off-by: Matthew Auld <matthew.auld@intel.com> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> > Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.h | 5 ++ > drivers/gpu/drm/i915/intel_region_lmem.c | 66 +++++++++++++++++++ > drivers/gpu/drm/i915/intel_region_lmem.h | 16 +++++ > .../drm/i915/selftests/i915_live_selftests.h | 1 + > .../drm/i915/selftests/intel_memory_region.c | 43 ++++++++++++ > 6 files changed, 132 insertions(+) > create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c > create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 28fac19f7b04..e782f7d10524 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -132,6 +132,7 @@ i915-y += \ > i915_scheduler.o \ > i915_trace_points.o \ > i915_vma.o \ > + intel_region_lmem.o \ > intel_wopcm.o > > # general-purpose microcontroller (GuC) support > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 838a796d9c55..7cbdffe3f129 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -93,6 +93,8 @@ > #include "gt/intel_timeline.h" > #include "i915_vma.h" > > +#include "intel_region_lmem.h" > + > #include "intel_gvt.h" > > /* General customization: > @@ -1341,6 +1343,8 @@ struct drm_i915_private { > */ > resource_size_t stolen_usable_size; /* Total size minus reserved ranges */ > > + struct intel_memory_region *regions[ARRAY_SIZE(intel_region_map)]; > + > struct intel_uncore uncore; > > struct i915_virtual_gpu vgpu; > @@ -2289,6 +2293,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, > #define HAS_IPC(dev_priv) (INTEL_INFO(dev_priv)->display.has_ipc) > > #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i)) > +#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM) > > /* > * For now, anything with a GuC requires uCode loading, and then supports > diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c > new file mode 100644 > index 000000000000..c4b5a88627a3 > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_region_lmem.c > @@ -0,0 +1,66 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright © 2019 Intel Corporation > + */ > + > +#include "i915_drv.h" > +#include "intel_memory_region.h" > +#include "intel_region_lmem.h" > + > +static const struct drm_i915_gem_object_ops region_lmem_obj_ops = { > + .get_pages = i915_memory_region_get_pages_buddy, > + .put_pages = i915_memory_region_put_pages_buddy, > + .release = i915_gem_object_release_memory_region, > +}; > + > +static struct drm_i915_gem_object * > +lmem_create_object(struct intel_memory_region *mem, > + resource_size_t size, > + unsigned int flags) > +{ > + struct drm_i915_private *i915 = mem->i915; > + struct drm_i915_gem_object *obj; > + unsigned int cache_level; > + > + if (flags & I915_BO_ALLOC_CONTIGUOUS) > + size = roundup_pow_of_two(size); That should not be required. Seems like a missed opportunity to pass the flag down to the allocator. > + if (size > BIT(mem->mm.max_order) * mem->mm.min_size) > + return ERR_PTR(-E2BIG); > + > + obj = i915_gem_object_alloc(); > + if (!obj) > + return ERR_PTR(-ENOMEM); > + > + drm_gem_private_object_init(&i915->drm, &obj->base, size); > + i915_gem_object_init(obj, ®ion_lmem_obj_ops); > + obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; > + cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; > + i915_gem_object_set_cache_coherency(obj, cache_level); That seems a little optimistic. I would strongly suggest pulling that information from the intel_memory_region. -Chris
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 28fac19f7b04..e782f7d10524 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -132,6 +132,7 @@ i915-y += \ i915_scheduler.o \ i915_trace_points.o \ i915_vma.o \ + intel_region_lmem.o \ intel_wopcm.o # general-purpose microcontroller (GuC) support diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 838a796d9c55..7cbdffe3f129 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -93,6 +93,8 @@ #include "gt/intel_timeline.h" #include "i915_vma.h" +#include "intel_region_lmem.h" + #include "intel_gvt.h" /* General customization: @@ -1341,6 +1343,8 @@ struct drm_i915_private { */ resource_size_t stolen_usable_size; /* Total size minus reserved ranges */ + struct intel_memory_region *regions[ARRAY_SIZE(intel_region_map)]; + struct intel_uncore uncore; struct i915_virtual_gpu vgpu; @@ -2289,6 +2293,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_IPC(dev_priv) (INTEL_INFO(dev_priv)->display.has_ipc) #define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i)) +#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM) /* * For now, anything with a GuC requires uCode loading, and then supports diff --git a/drivers/gpu/drm/i915/intel_region_lmem.c b/drivers/gpu/drm/i915/intel_region_lmem.c new file mode 100644 index 000000000000..c4b5a88627a3 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_region_lmem.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2019 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_memory_region.h" +#include "intel_region_lmem.h" + +static const struct drm_i915_gem_object_ops region_lmem_obj_ops = { + .get_pages = i915_memory_region_get_pages_buddy, + .put_pages = i915_memory_region_put_pages_buddy, + .release = i915_gem_object_release_memory_region, +}; + +static struct drm_i915_gem_object * +lmem_create_object(struct intel_memory_region *mem, + resource_size_t size, + unsigned int flags) +{ + struct drm_i915_private *i915 = mem->i915; + struct drm_i915_gem_object *obj; + unsigned int cache_level; + + if (flags & I915_BO_ALLOC_CONTIGUOUS) + size = roundup_pow_of_two(size); + + if (size > BIT(mem->mm.max_order) * mem->mm.min_size) + return ERR_PTR(-E2BIG); + + obj = i915_gem_object_alloc(); + if (!obj) + return ERR_PTR(-ENOMEM); + + drm_gem_private_object_init(&i915->drm, &obj->base, size); + i915_gem_object_init(obj, ®ion_lmem_obj_ops); + + obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT; + + cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; + i915_gem_object_set_cache_coherency(obj, cache_level); + + return obj; +} + +static const struct intel_memory_region_ops region_lmem_ops = { + .init = i915_memory_region_init_buddy, + .release = i915_memory_region_release_buddy, + .create_object = lmem_create_object, +}; + +bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj) +{ + struct intel_memory_region *region = obj->memory_region; + + return region && region->type == INTEL_LMEM; +} + +struct drm_i915_gem_object * +i915_gem_object_create_lmem(struct drm_i915_private *i915, + resource_size_t size, + unsigned int flags) +{ + return i915_gem_object_create_region(i915->regions[INTEL_MEMORY_LMEM], + size, flags); +} diff --git a/drivers/gpu/drm/i915/intel_region_lmem.h b/drivers/gpu/drm/i915/intel_region_lmem.h new file mode 100644 index 000000000000..0f0a6249d5b9 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_region_lmem.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_REGION_LMEM_H +#define __INTEL_REGION_LMEM_H + +bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj); + +struct drm_i915_gem_object * +i915_gem_object_create_lmem(struct drm_i915_private *i915, + resource_size_t size, + unsigned int flags); + +#endif /* !__INTEL_REGION_LMEM_H */ diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index 2b31a4ee0b4c..1b76c2c12ca9 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -28,6 +28,7 @@ selftest(contexts, i915_gem_context_live_selftests) selftest(blt, i915_gem_object_blt_live_selftests) selftest(client, i915_gem_client_blt_live_selftests) selftest(reset, intel_reset_live_selftests) +selftest(memory_region, intel_memory_region_live_selftests) selftest(hangcheck, intel_hangcheck_live_selftests) selftest(execlists, intel_execlists_live_selftests) selftest(guc, intel_guc_live_selftest) diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index bdf044e4781d..3ac320b28ef1 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -344,6 +344,27 @@ static int igt_mock_volatile(void *arg) return err; } +static int igt_lmem_create(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_object *obj; + int err = 0; + + obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, 0); + if (IS_ERR(obj)) + return PTR_ERR(obj); + + err = i915_gem_object_pin_pages(obj); + if (err) + goto out_put; + + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + + return err; +} + int intel_memory_region_mock_selftests(void) { static const struct i915_subtest tests[] = { @@ -380,3 +401,25 @@ int intel_memory_region_mock_selftests(void) return err; } + +int intel_memory_region_live_selftests(struct drm_i915_private *i915) +{ + static const struct i915_subtest tests[] = { + SUBTEST(igt_lmem_create), + }; + int err; + + if (!HAS_LMEM(i915)) { + pr_info("device lacks LMEM support, skipping\n"); + return 0; + } + + if (i915_terminally_wedged(i915)) + return 0; + + mutex_lock(&i915->drm.struct_mutex); + err = i915_subtests(tests, i915); + mutex_unlock(&i915->drm.struct_mutex); + + return err; +}
We currently define LMEM, or local memory, as just another memory region, like system memory or stolen, which we can expose to userspace and can be mapped to the CPU via some BAR. Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 5 ++ drivers/gpu/drm/i915/intel_region_lmem.c | 66 +++++++++++++++++++ drivers/gpu/drm/i915/intel_region_lmem.h | 16 +++++ .../drm/i915/selftests/i915_live_selftests.h | 1 + .../drm/i915/selftests/intel_memory_region.c | 43 ++++++++++++ 6 files changed, 132 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.c create mode 100644 drivers/gpu/drm/i915/intel_region_lmem.h