Date: Fri, 22 Sep 2006 07:46:58 +1000 From: "Jan Mikkelsen" <janm@transactionware.com> To: <freebsd-stable@freebsd.org> Subject: Patch: sym(4) "VTOBUS FAILED" panics on amd64, amd64/89550 Message-ID: <002d01c6ddc7$76d10cc0$0202a8c0@transactzbkv04>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. ------=_NextPart_000_002E_01C6DE1B.487D1CC0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, I posted this to freebsd-amd64, but I've had no replies. This fixes the sym "VTOBUS FAILED" panics that I got consistently on 6.1-RELEASE/amd64; see the PR amd64/89550 for dmesg, other reports, etc. Quick summary: sym(4) assumes on amd64 that virtual addresses provided by bus_dmamem_alloc() have the same alignment as the physical addresses (in this case, 2*PAGE_SIZE). They don't, and stuff breaks. This patch works around that. I'm looking for someone to take a quick look at it and make sure that the approach is reasonable. I would be nice if a fix was committed (not necessarily mine). sym(4) is listed as supported in the 6.1/amd64 hardware guide, but it doesn't seem to be working at all. For 6.2, I either suggest putting in a fix so that it is supported, or having a note in the hardware guide. Sorry about coming along so late in the release cycle, but I first encountered the problem on Monday. Thanks, Jan Mikkelsen ------=_NextPart_000_002E_01C6DE1B.487D1CC0 Content-Type: application/octet-stream; name="sym_hipd.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="sym_hipd.diff" *** FreeBSD/src/sys/dev/sym/sym_hipd.c Tue Aug 8 00:43:31 2006=0A= --- /home/janm/sym_hipd.c Tue Sep 19 15:27:55 2006=0A= ***************=0A= *** 439,445 ****=0A= #define free_pages(p) free((p), M_DEVBUF)=0A= #else=0A= #define get_pages() contigmalloc(MEMO_CLUSTER_SIZE, M_DEVBUF, \=0A= ! 0, 0, 1LL << 32, PAGE_SIZE, 1LL << 32)=0A= #define free_pages(p) contigfree((p), MEMO_CLUSTER_SIZE, M_DEVBUF)=0A= #endif=0A= =0A= --- 439,446 ----=0A= #define free_pages(p) free((p), M_DEVBUF)=0A= #else=0A= #define get_pages() contigmalloc(MEMO_CLUSTER_SIZE, M_DEVBUF, \=0A= ! 0, 0, 1LL << 32, PAGE_SIZE, \=0A= ! MEMO_CLUSTER_SIZE)=0A= #define free_pages(p) contigfree((p), MEMO_CLUSTER_SIZE, M_DEVBUF)=0A= #endif=0A= =0A= ***************=0A= *** 453,458 ****=0A= --- 454,462 ----=0A= struct m_vtob *next;=0A= bus_dmamap_t dmamap; /* Map for this chunk */=0A= m_addr_t vaddr; /* Virtual address */=0A= + #if PAGE_SIZE < MEMO_CLUSTER_SIZE=0A= + m_addr_t adjusted_vaddr; /* Virtual address adjusted for buddy */=0A= + #endif=0A= m_addr_t baddr; /* Bus physical address */=0A= } m_vtob_s;=0A= /* Hash this stuff a bit to speed up translations */=0A= ***************=0A= *** 674,685 ****=0A= if (bus_dmamem_alloc(mp->dmat, &vaddr,=0A= BUS_DMA_NOWAIT, &vbp->dmamap))=0A= goto out_err;=0A= bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,=0A= MEMO_CLUSTER_SIZE, getbaddrcb, &baddr, 0);=0A= if (baddr) {=0A= ! int hc =3D VTOB_HASH_CODE(vaddr);=0A= vbp->vaddr =3D (m_addr_t) vaddr;=0A= vbp->baddr =3D (m_addr_t) baddr;=0A= vbp->next =3D mp->vtob[hc];=0A= mp->vtob[hc] =3D vbp;=0A= ++mp->nump;=0A= --- 678,711 ----=0A= if (bus_dmamem_alloc(mp->dmat, &vaddr,=0A= BUS_DMA_NOWAIT, &vbp->dmamap))=0A= goto out_err;=0A= + #if PAGE_SIZE < MEMO_CLUSTER_SIZE=0A= + bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,=0A= + MEMO_CLUSTER_SIZE * 2, getbaddrcb, &baddr, 0);=0A= + #else=0A= bus_dmamap_load(mp->dmat, vbp->dmamap, vaddr,=0A= MEMO_CLUSTER_SIZE, getbaddrcb, &baddr, 0);=0A= + #endif=0A= if (baddr) {=0A= ! int hc;=0A= ! =0A= vbp->vaddr =3D (m_addr_t) vaddr;=0A= vbp->baddr =3D (m_addr_t) baddr;=0A= + #if PAGE_SIZE < MEMO_CLUSTER_SIZE=0A= + /*=0A= + * Adjusting vaddr is OK here because we do not error out.=0A= + * If that changes, the bus_dmamem_free() call below would=0A= + * need to be fixed.=0A= + *=0A= + * This code assumes that we will be at most one page away=0A= + * from having things aligned the way we want.=0A= + */=0A= + =0A= + if (((m_addr_t) vaddr & ~MEMO_CLUSTER_MASK) !=3D (m_addr_t) vaddr)=0A= + vaddr =3D (void*) ((m_addr_t) vaddr + PAGE_SIZE);=0A= + =0A= + vbp->adjusted_vaddr =3D (m_addr_t) vaddr;=0A= + #endif=0A= + hc =3D VTOB_HASH_CODE(vaddr);=0A= vbp->next =3D mp->vtob[hc];=0A= mp->vtob[hc] =3D vbp;=0A= ++mp->nump;=0A= ***************=0A= *** 733,744 ****=0A= mp =3D __sym_calloc(&mp0, sizeof(*mp), "MPOOL");=0A= if (mp) {=0A= mp->dev_dmat =3D dev_dmat;=0A= ! if (!bus_dma_tag_create(dev_dmat, 1, MEMO_CLUSTER_SIZE,=0A= BUS_SPACE_MAXADDR_32BIT,=0A= BUS_SPACE_MAXADDR_32BIT,=0A= NULL, NULL, MEMO_CLUSTER_SIZE, 1,=0A= MEMO_CLUSTER_SIZE, 0,=0A= busdma_lock_mutex, &Giant, &mp->dmat)) {=0A= mp->getp =3D ___dma_getp;=0A= #ifdef MEMO_FREE_UNUSED=0A= mp->freep =3D ___dma_freep;=0A= --- 759,779 ----=0A= mp =3D __sym_calloc(&mp0, sizeof(*mp), "MPOOL");=0A= if (mp) {=0A= mp->dev_dmat =3D dev_dmat;=0A= ! #if PAGE_SIZE < MEMO_CLUSTER_SIZE=0A= ! if (!bus_dma_tag_create(dev_dmat, 1, MEMO_CLUSTER_SIZE * 2,=0A= BUS_SPACE_MAXADDR_32BIT,=0A= + BUS_SPACE_MAXADDR,=0A= + NULL, NULL, MEMO_CLUSTER_SIZE * 2, 1,=0A= + MEMO_CLUSTER_SIZE * 2, 0,=0A= + busdma_lock_mutex, &Giant, &mp->dmat)) {=0A= + #else=0A= + if (!bus_dma_tag_create(dev_dmat, 1, MEMO_CLUSTER_SIZE,=0A= BUS_SPACE_MAXADDR_32BIT,=0A= + BUS_SPACE_MAXADDR,=0A= NULL, NULL, MEMO_CLUSTER_SIZE, 1,=0A= MEMO_CLUSTER_SIZE, 0,=0A= busdma_lock_mutex, &Giant, &mp->dmat)) {=0A= + #endif=0A= mp->getp =3D ___dma_getp;=0A= #ifdef MEMO_FREE_UNUSED=0A= mp->freep =3D ___dma_freep;=0A= ***************=0A= *** 815,827 ****=0A= mp =3D ___get_dma_pool(dev_dmat);=0A= if (mp) {=0A= vp =3D mp->vtob[hc];=0A= while (vp && (m_addr_t) vp->vaddr !=3D a)=0A= vp =3D vp->next;=0A= }=0A= /* Unlock */=0A= if (!vp)=0A= panic("sym: VTOBUS FAILED!\n");=0A= ! return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;=0A= }=0A= =0A= =0A= --- 850,872 ----=0A= mp =3D ___get_dma_pool(dev_dmat);=0A= if (mp) {=0A= vp =3D mp->vtob[hc];=0A= + #if (PAGE_SIZE < MEMO_CLUSTER_SIZE)=0A= + while (vp && (m_addr_t) vp->adjusted_vaddr !=3D a)=0A= + #else=0A= while (vp && (m_addr_t) vp->vaddr !=3D a)=0A= + #endif=0A= vp =3D vp->next;=0A= }=0A= + =0A= /* Unlock */=0A= if (!vp)=0A= panic("sym: VTOBUS FAILED!\n");=0A= ! #if (PAGE_SIZE < MEMO_CLUSTER_SIZE)=0A= ! return vp->baddr + (((m_addr_t) m) - a) +=0A= ! (vp->adjusted_vaddr - vp->vaddr);=0A= ! #else=0A= ! return vp->baddr + (((m_addr_t) m) - a);=0A= ! #endif=0A= }=0A= =0A= =0A= ------=_NextPart_000_002E_01C6DE1B.487D1CC0--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?002d01c6ddc7$76d10cc0$0202a8c0>