NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/57833: kernel panic on xorg exit



Can you also try the attached patch, instead of the other one, to see
what happens?

(This might break things more spectacularly -- I haven't thought about
whether it makes a lot of sense -- but it should at least prevent the
particular crash you observed, if we ever get that far with it.)
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c
index 8e592f008ef7..276ebbdbc234 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c
@@ -677,6 +677,8 @@ void i915_gem_object_release_mmap_offset(struct drm_i915_gem_object *obj)
 		return;
 	for (i = 0; i < obj->base.size >> PAGE_SHIFT; i++) {
 		page = obj->mm.pages->sgl->sg_pgs[i];
+		if (page == NULL)
+			continue;
 		vm_page = &page->p_vmp;
 		pmap_page_protect(vm_page, VM_PROT_NONE);
 	}
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c
index 3f68276eea5f..29772bdbd8d9 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c
@@ -83,8 +83,14 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 	if (!st)
 		goto err_pci;
 
+#ifdef __NetBSD__
+	if (sg_alloc_table_from_bus_dmamem(st, dmat, &obj->mm.u.phys.seg, 1,
+		GFP_KERNEL))
+		goto err_st;
+#else
 	if (sg_alloc_table(st, 1, GFP_KERNEL))
 		goto err_st;
+#endif
 
 	sg = st->sgl;
 #ifdef __NetBSD__
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_region.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_region.c
index 1a928988bd5f..5e8232b9634f 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_region.c
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_region.c
@@ -85,7 +85,15 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 		segs[i].ds_addr = mem->region.start + offset;
 		segs[i].ds_len = block_size;
+		i++;
 	}
+	KASSERT(i == nsegs);
+
+	/* XXX errno NetBSD->Linux */
+	ret = -bus_dmamem_export_pages(dmat, segs, nsegs, sg->sg_pgs,
+	    sg->sg_npgs);
+	if (ret)
+		goto err;
 
 	/* XXX errno NetBSD->Linux */
 	ret = -bus_dmamap_create(dmat, size, nsegs, size, 0, BUS_DMA_WAITOK,
diff --git a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c
index b53d543fa894..08cf7f0001bf 100644
--- a/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c
+++ b/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c
@@ -506,14 +506,13 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 {
 	struct drm_i915_private *i915 = to_i915(dev);
 	struct sg_table *st;
+	struct scatterlist *sg;
 #ifdef __NetBSD__
 	bus_dma_tag_t dmat = i915->drm.dmat;
 	bus_dma_segment_t *seg = NULL;
 	int nseg = 0, i;
 	bool loaded = false;
 	int ret;
-#else
-	struct scatterlist *sg;
 #endif
 
 	GEM_BUG_ON(range_overflows(offset, size, resource_size(&i915->dsm)));
@@ -532,6 +531,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 		return ERR_PTR(-ENOMEM);
 	}
 
+	sg = st->sgl;
 #ifdef __NetBSD__
 	KASSERT((size % PAGE_SIZE) == 0);
 	nseg = size / PAGE_SIZE;
@@ -548,19 +548,25 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 		seg[i].ds_len = PAGE_SIZE;
 	}
 
+	/* XXX errno NetBSD->Linux */
+	ret = -bus_dmamem_export_pages(dmat, seg, nseg, sg->sg_pgs,
+	    sg->sg_npgs);
+	if (ret)
+		goto err;
+
 	/* XXX errno NetBSD->Linux */
 	ret = -bus_dmamap_create(dmat, size, nseg, PAGE_SIZE, 0,
-	    BUS_DMA_WAITOK, &st->sgl->sg_dmamap);
+	    BUS_DMA_WAITOK, &sg->sg_dmamap);
 	if (ret) {
 		DRM_ERROR("failed to create DMA map for stolen object: %d\n",
 		    ret);
-		st->sgl->sg_dmamap = NULL;
+		sg->sg_dmamap = NULL;
 		goto out;
 	}
-	st->sgl->sg_dmat = dmat;
+	sg->sg_dmat = dmat;
 
 	/* XXX errno NetBSD->Liux */
-	ret = -bus_dmamap_load_raw(dmat, st->sgl->sg_dmamap, seg, nseg, size,
+	ret = -bus_dmamap_load_raw(dmat, sg->sg_dmamap, seg, nseg, size,
 	    BUS_DMA_WAITOK);
 	if (ret) {
 		DRM_ERROR("failed to load DMA map for stolen object: %d\n",
@@ -571,13 +577,12 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 
 out:	if (ret) {
 		if (loaded)
-			bus_dmamap_unload(dmat, st->sgl->sg_dmamap);
+			bus_dmamap_unload(dmat, sg->sg_dmamap);
 		sg_free_table(st);
 		kfree(st);
 		return ERR_PTR(ret);
 	}
 #else
-	sg = st->sgl;
 	sg->offset = 0;
 	sg->length = size;
 


Home | Main Index | Thread Index | Old Index