Skip site navigation (1)Skip section navigation (2)
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>