From: Jonathan Gray Subject: Re: [PATCH 0/4] i915 dg2 patches To: kisekinopureya Cc: tech@openbsd.org Date: Fri, 11 Sep 2026 15:59:39 +1000 On Thu, Sep 10, 2026 at 10:13:48PM +0300, kisekinopureya wrote: > This patch series adds necessary changes to i915 for Intel Arc (DG2). > I've been using it for a week on -current and haven't observed any > panic/crashes yet. I don't have an integrated gpu, i can't confirm > whether the changes broke integrated gpus. > > This is my first patch to the mailing list, please let me know > if I need to adjust anything. > > dmesg > ... > inteldrm0: msi, DG2, gen 12 > inteldrm0: 1920x1080, 32bpp > wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0 > inteldrm0 at pci3 dev 0 function 0 "Intel Arc A770" rev 0x08 > drm0 at inteldrm0 > ... > > glxinfo -B > ... > direct rendering: Yes > Extended renderer info (GLX_MESA_query_renderer): > Vendor: Intel (0x8086) > Device: Mesa Intel(R) Arc(tm) A770 Graphics (DG2) (0x56a0) > Version: 25.0.7 > Accelerated: yes > ... > > > kisekinopureya (4): > remove force_probe for dg2 > unstub intel_slicemask_from_xehp_dssmask > disable huc for dg2 > port gem and ttm memory management to uvm Disabling HuC to avoid MEI is interesting. For comparison, here is a diff from one of my dg2 branches from a few months ago. I don't remember the state, I suspect there were problems initialising GuC or with MEI. Needs dma_tag_lookup() change I committed earlier today. diff --git sys/dev/pci/drm/drm_linux.c sys/dev/pci/drm/drm_linux.c index 53a6efd90e2..3405463a620 100644 --- sys/dev/pci/drm/drm_linux.c +++ sys/dev/pci/drm/drm_linux.c @@ -3487,6 +3487,37 @@ dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size, STUB(); } +int +dma_map_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs) +{ + bus_dma_tag_t dmat = dma_tag_lookup(dev); + bus_dma_segment_t seg; + int error, i; + struct scatterlist *sg; + + error = bus_dmamap_create(dmat, sgt->sgl->length, sgt->nents, + sgt->sgl->length, 0, BUS_DMA_WAITOK, &sgt->dmamap); + if (error) + return -ENOMEM; + + sgt->dmamap->dm_mapsize = 0; + sgt->dmamap->dm_nsegs = 0; + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + sgt->dmamap->dm_segs[i].ds_addr = VM_PAGE_TO_PHYS(sg->__page); + sgt->dmamap->dm_segs[i].ds_len = sgt->sgl->length; + sgt->dmamap->dm_nsegs++; + sgt->dmamap->dm_mapsize += sgt->sgl->length; + } + sgt->dmamap->dm_nsegs = sgt->nents; + error = bus_dmamap_load_raw(dmat, sgt->dmamap, sgt->dmamap->dm_segs, + sgt->dmamap->dm_nsegs, sgt->dmamap->dm_mapsize, BUS_DMA_WAITOK); + if (error) + return -ENOMEM; + + return 0; +} + #ifdef BUS_DMA_FIXED #include diff --git sys/dev/pci/drm/i915/gem/i915_gem_object.h sys/dev/pci/drm/i915/gem/i915_gem_object.h index b266814d3fb..0fb18d0aa43 100644 --- sys/dev/pci/drm/i915/gem/i915_gem_object.h +++ sys/dev/pci/drm/i915/gem/i915_gem_object.h @@ -855,10 +855,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, size_t size, struct intel_memory_region *mr, struct address_space *mapping, unsigned int max_segment, - struct drm_i915_gem_object *obj); + struct uvm_object *); void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping, bool dirty, bool backup, - struct drm_i915_gem_object *obj); + struct uvm_object *, size_t); #endif void __shmem_writeback(size_t size, struct address_space *mapping); diff --git sys/dev/pci/drm/i915/gem/i915_gem_shmem.c sys/dev/pci/drm/i915/gem/i915_gem_shmem.c index ee8034c9c63..970b47f8fd6 100644 --- sys/dev/pci/drm/i915/gem/i915_gem_shmem.c +++ sys/dev/pci/drm/i915/gem/i915_gem_shmem.c @@ -34,7 +34,7 @@ static void check_release_folio_batch(struct folio_batch *fbatch) void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping, bool dirty, bool backup, - struct drm_i915_gem_object *obj) + struct uvm_object *uao, size_t uao_size) { struct sgt_iter sgt_iter; struct folio_batch fbatch; @@ -69,7 +69,7 @@ void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping, if (fbatch.nr) check_release_folio_batch(&fbatch); #else - uvm_obj_unwire(obj->base.uao, 0, obj->base.size); + uvm_obj_unwire(uao, 0, uao_size); #endif sg_free_table(st); @@ -79,7 +79,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, size_t size, struct intel_memory_region *mr, struct address_space *mapping, unsigned int max_segment, - struct drm_i915_gem_object *obj) + struct uvm_object *uao) { unsigned int page_count; /* restricted by sg_alloc_table */ unsigned long i; @@ -201,7 +201,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, st->nents = 0; TAILQ_INIT(&plist); - if (uvm_obj_wire(obj->base.uao, 0, obj->base.size, &plist)) { + if (uvm_obj_wire(uao, 0, size, &plist)) { ret = -ENOMEM; goto err_sg; } @@ -225,7 +225,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, err_sg: sg_mark_end(sg); if (sg != st->sgl) { - shmem_sg_free_table(st, mapping, false, false, obj); + shmem_sg_free_table(st, mapping, false, false, uao, size); } else { mapping_clear_unevictable(mapping); sg_free_table(st); @@ -275,7 +275,7 @@ rebuild_st: max_segment); #else ret = shmem_sg_alloc_table(i915, st, obj->base.size, mem, NULL, - max_segment, obj); + max_segment, obj->base.uao); #endif if (ret) goto err_st; @@ -291,7 +291,7 @@ rebuild_st: #ifdef __linux__ shmem_sg_free_table(st, mapping, false, false); #else - shmem_sg_free_table(st, NULL, false, false, obj); + shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size); #endif sg_free_table(st); kfree(st); @@ -320,7 +320,7 @@ err_pages: #ifdef __linux__ shmem_sg_free_table(st, mapping, false, false); #else - shmem_sg_free_table(st, NULL, false, false, obj); + shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size); #endif /* * shmemfs first checks if there is enough memory to allocate the page @@ -459,7 +459,8 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_ obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED); #else shmem_sg_free_table(pages, NULL, - obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED, obj); + obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED, + obj->base.uao, obj->base.size); #endif kfree(pages); obj->mm.dirty = false; diff --git sys/dev/pci/drm/i915/gem/i915_gem_ttm.c sys/dev/pci/drm/i915/gem/i915_gem_ttm.c index 570d0971fd4..00c4b9768b4 100644 --- sys/dev/pci/drm/i915/gem/i915_gem_ttm.c +++ sys/dev/pci/drm/i915/gem/i915_gem_ttm.c @@ -53,7 +53,11 @@ struct i915_ttm_tt { struct i915_refct_sgt cached_rsgt; bool is_shmem; +#ifdef __linux__ struct file *filp; +#else + struct uvm_object *filp; +#endif }; static const struct ttm_place sys_placement_flags = { @@ -179,13 +183,11 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj, placement->placement = places; } +#ifdef __linux__ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) { - STUB(); - return -ENOSYS; -#ifdef notyet struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev); struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM]; struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm); @@ -239,8 +241,58 @@ err_free_st: shmem_sg_free_table(st, filp->f_mapping, false, false); return err; -#endif } +#else /* !__linux__ */ +static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, + struct ttm_tt *ttm, + struct ttm_operation_ctx *ctx) +{ + struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev); + struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM]; + struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm); + const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); + const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT; + struct uvm_object *uao = i915_tt->filp; + struct sgt_iter sgt_iter; + struct sg_table *st; + struct vm_page *page; + unsigned long i; + int err; + + if (!uao) { + uao = uao_create(size, 0); + if (uao == NULL) + return -ENOMEM; + + i915_tt->filp = uao; + } + + st = &i915_tt->cached_rsgt.table; + err = shmem_sg_alloc_table(i915, st, size, mr, /*filp->f_mapping*/NULL, + max_segment, uao); + if (err) + return err; + + err = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL, + DMA_ATTR_SKIP_CPU_SYNC); + if (err) + goto err_free_st; + + i = 0; + for_each_sgt_page(page, sgt_iter, st) + ttm->pages[i++] = page; + + if (ttm->page_flags & TTM_TT_FLAG_SWAPPED) + ttm->page_flags &= ~TTM_TT_FLAG_SWAPPED; + + return 0; + +err_free_st: + shmem_sg_free_table(st, NULL, false, false, uao, size); + + return err; +} +#endif /* !__linux__ */ static void i915_ttm_tt_shmem_unpopulate(struct ttm_tt *ttm) { @@ -356,7 +408,11 @@ static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm) struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm); if (i915_tt->filp) +#ifdef __linux__ fput(i915_tt->filp); +#else + uao_detach(i915_tt->filp); +#endif ttm_tt_fini(ttm); i915_refct_sgt_put(&i915_tt->cached_rsgt); @@ -456,13 +512,14 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj) #ifdef __linux__ shmem_truncate_range(file_inode(i915_tt->filp), 0, (loff_t)-1); + fput(fetch_and_zero(&i915_tt->filp)); #else rw_enter(obj->base.uao->vmobjlock, RW_WRITE); obj->base.uao->pgops->pgo_flush(obj->base.uao, 0, obj->base.size, PGO_ALLPAGES | PGO_FREE); rw_exit(obj->base.uao->vmobjlock); + uao_detach(fetch_and_zero(&i915_tt->filp)); #endif - fput(fetch_and_zero(&i915_tt->filp)); } } diff --git sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c index b1bda1b84f0..7847c374690 100644 --- sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c +++ sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c @@ -158,7 +158,7 @@ static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, bool #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) #define GUC_LOAD_RETRY_LIMIT 20 #else -#define GUC_LOAD_RETRY_LIMIT 3 +#define GUC_LOAD_RETRY_LIMIT 20 #endif static int guc_wait_ucode(struct intel_guc *guc) diff --git sys/dev/pci/drm/i915/i915_pci.c sys/dev/pci/drm/i915/i915_pci.c index 2f30756ac4a..ce56d2ea89f 100644 --- sys/dev/pci/drm/i915/i915_pci.c +++ sys/dev/pci/drm/i915/i915_pci.c @@ -738,7 +738,6 @@ static const struct intel_device_info adl_p_info = { static const struct intel_device_info dg2_info = { DG2_FEATURES, - .require_force_probe = 1, }; static const struct intel_device_info ats_m_info = {