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
The following reply was made to PR kern/57833; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Ramiro Aceves <ea1abz%gmail.com@localhost>
Cc: "David H. Gutteridge" <david%gutteridge.ca@localhost>,
gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost, RVP <rvp%SDF.ORG@localhost>
Subject: Re: kern/57833: kernel panic on xorg exit
Date: Thu, 18 Jan 2024 03:11:09 +0000
This is a multi-part message in MIME format.
--=_yZfuFEUR5sBHB86OQy7idKn1uESPEWyt
OK, that's getting pretty weird. Can you please revert all your local
changes, and apply just the attached patch?
If it crashes, same request as before -- `print *obj', `info locals'
in all frames, dmesg, plus `print segs[0]' in the bus_dmamem_kmap
frame (which was frame 5 in your last reply).
P.S. The pr57833-i915gempages-v5.patch file I gave you earlier is a
git patch series. You can apply it on top of a git repository wit the
`git am' command, and bisect with `git bisect'. If the smaller
i915_gem_phys.patch attached to this message works, we can use that to
try finding which other part of the changes might have broken things.
--=_yZfuFEUR5sBHB86OQy7idKn1uESPEWyt
Content-Type: text/plain; charset="ISO-8859-1"; name="i915_gem_phys"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="i915_gem_phys.patch"
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..375246c43af6 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
@@ -24,6 +24,98 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_phys.c,v 1.8 2021/1=
2/19 12:45:43 riastradh
#include "i915_gem_region.h"
#include "i915_scatterlist.h"
=20
+#ifdef __NetBSD__
+
+#include <uvm/uvm.h>
+#include <uvm/uvm_extern.h>
+
+#include <machine/pmap_private.h> /* kvtopte, pmap_pte_clearbits */
+
+/*
+ * Version of bus_dmamem_map that uses pmap_kenter_pa, not pmap_enter,
+ * so that it isn't affected by pmap_page_protect on the physical
+ * address. Adapted from sys/arch/x86/x86/bus_dma.c.
+ */
+static int
+bus_dmamem_kmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
+ size_t size, void **kvap, int flags)
+{
+ vaddr_t va;
+ bus_addr_t addr;
+ int curseg;
+ const uvm_flag_t kmflags =3D
+ (flags & BUS_DMA_NOWAIT) !=3D 0 ? UVM_KMF_NOWAIT : 0;
+ u_int pmapflags =3D PMAP_WIRED | VM_PROT_READ | VM_PROT_WRITE;
+
+ CTASSERT(PAGE_SIZE =3D=3D 4096);
+ printf("%s: t=3D%p segs=3D%p nsegs=3D%d size=3D0x%zx kvap=3D%p flags=3D0x=
%x\n",
+ __func__, t, segs, nsegs, size, kvap, flags);
+
+ size =3D round_page(size);
+ if (flags & BUS_DMA_NOCACHE)
+ pmapflags |=3D PMAP_NOCACHE;
+
+ va =3D uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
+
+ if (va =3D=3D 0)
+ return ENOMEM;
+
+ printf("%s: va=3D%"PRIxVADDR"\n", __func__, va);
+ *kvap =3D (void *)va;
+
+ for (curseg =3D 0; curseg < nsegs; curseg++) {
+ printf("%s:%d size=3D0x%"PRIxBUSSIZE
+ " curseg=3D%d addr=3D0x%"PRIxBUSADDR" len=3D0x%"PRIxBUSSIZE
+ " end=3D0x%"PRIxBUSADDR"\n",
+ __func__, __LINE__, size,
+ curseg, segs[curseg].ds_addr, segs[curseg].ds_len,
+ segs[curseg].ds_addr + segs[curseg].ds_len);
+ for (addr =3D segs[curseg].ds_addr;
+ addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
+ addr +=3D PAGE_SIZE, va +=3D PAGE_SIZE, size -=3D PAGE_SIZE) {
+ printf("%s:%d: size=3D0x%"PRIxBUSSIZE
+ " addr=3D0x%"PRIxBUSADDR,
+ __func__, __LINE__, size, addr);
+ if (size =3D=3D 0)
+ panic("_bus_dmamem_kmap: size botch");
+ pmap_kenter_pa(va, addr,
+ VM_PROT_READ | VM_PROT_WRITE,
+ pmapflags);
+ }
+ }
+ pmap_update(pmap_kernel());
+
+ return 0;
+}
+
+static void
+bus_dmamem_kunmap(bus_dma_tag_t t, void *kva, size_t size)
+{
+ pt_entry_t *pte, opte;
+ vaddr_t va, sva, eva;
+
+ KASSERTMSG(((uintptr_t)kva & PGOFSET) =3D=3D 0, "kva=3D%p", kva);
+
+ size =3D round_page(size);
+ sva =3D (vaddr_t)kva;
+ eva =3D sva + size;
+
+ /*
+ * mark pages cacheable again.
+ */
+ for (va =3D sva; va < eva; va +=3D PAGE_SIZE) {
+ pte =3D kvtopte(va);
+ opte =3D *pte;
+ if ((opte & PTE_PCD) !=3D 0)
+ pmap_pte_clearbits(pte, PTE_PCD);
+ }
+ pmap_kremove((vaddr_t)kva, size);
+ pmap_update(pmap_kernel());
+ uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY);
+}
+
+#endif
+
#include <linux/nbsd-namespace.h>
=20
static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
@@ -65,7 +157,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i91=
5_gem_object *obj)
if (ret)
return -ENOMEM;
KASSERT(rsegs =3D=3D 1);
- ret =3D -bus_dmamem_map(dmat, &obj->mm.u.phys.seg, 1,
+ ret =3D -bus_dmamem_kmap(dmat, &obj->mm.u.phys.seg, 1,
roundup_pow_of_two(obj->base.size), &vaddr,
BUS_DMA_WAITOK|BUS_DMA_COHERENT);
if (ret)
@@ -83,7 +175,12 @@ static int i915_gem_object_get_pages_phys(struct drm_i9=
15_gem_object *obj)
if (!st)
goto err_pci;
=20
+#ifdef __NetBSD__
+ if (sg_alloc_table_from_bus_dmamem(st, dmat, &obj->mm.u.phys.seg, 1,
+ GFP_KERNEL))
+#else
if (sg_alloc_table(st, 1, GFP_KERNEL))
+#endif
goto err_st;
=20
sg =3D st->sgl;
@@ -151,7 +248,7 @@ err_st:
err_pci:
#ifdef __NetBSD__
if (vaddr) {
- bus_dmamem_unmap(dmat, vaddr,
+ bus_dmamem_kunmap(dmat, vaddr,
roundup_pow_of_two(obj->base.size));
}
obj->mm.u.phys.kva =3D NULL;
@@ -225,7 +322,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_obje=
ct *obj,
kfree(pages);
=20
#ifdef __NetBSD__
- bus_dmamem_unmap(dmat, obj->mm.u.phys.kva,
+ bus_dmamem_kunmap(dmat, obj->mm.u.phys.kva,
roundup_pow_of_two(obj->base.size));
obj->mm.u.phys.kva =3D NULL;
bus_dmamem_free(dmat, &obj->mm.u.phys.seg, 1);
--=_yZfuFEUR5sBHB86OQy7idKn1uESPEWyt--
Home |
Main Index |
Thread Index |
Old Index