Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Feb 2013 17:26:19 -0500
From:      Aman Sawrup <aman.sawrup@bluecoat.com>
To:        freebsd-usb@freebsd.org
Subject:   Insufficient memory reserved for xfer->dma_page_ptr?
Message-ID:  <5123FC0B.70009@bluecoat.com>
In-Reply-To: <201302090001.57258.hselasky@c2i.net>
References:  <1360360082956-5785167.post@n5.nabble.com> <201302090001.57258.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Hans,

I think I might have found a bug in usbd_transfer_setup_sub that causes 
insufficient memory allocated for xfer->dma_page_ptr.  The code in 
question is:

#if USB_HAVE_BUSDMA
	if (xfer->flags_int.bdma_enable) {
		/*
		 * Setup "dma_page_ptr".
		 *
		 * Proof for formula below:
		 *
		 * Assume there are three USB frames having length "a", "b" and
		 * "c". These USB frames will at maximum need "z"
		 * "usb_page" structures. "z" is given by:
		 *
		 * z = ((a / USB_PAGE_SIZE) + 2) + ((b / USB_PAGE_SIZE) + 2) +
		 * ((c / USB_PAGE_SIZE) + 2);
		 *
		 * Constraining "a", "b" and "c" like this:
		 *
		 * (a + b + c) <= parm->bufsize
		 *
		 * We know that:
		 *
		 * z <= ((parm->bufsize / USB_PAGE_SIZE) + (3*2));
		 *
		 * Here is the general formula:
		 */
		xfer->dma_page_ptr = parm->dma_page_ptr;
		parm->dma_page_ptr += (2 * n_frbuffers);
		parm->dma_page_ptr += (parm->bufsize / USB_PAGE_SIZE);
	}
#endif

What I observe happening on a 64-bit x86 system is 4608 bytes reserved 
for xfer->dma_page_ptr.  For example, this is what I see:

(gdb) p parm->dma_page_ptr
$75 = (struct usb_page *) 0x6dad46e0

(gdb) p xfer->dma_page_ptr
$76 = (struct usb_page *) 0x6dad34e0

(gdb) p /d 0x6dad46e0 - 0x6dad34e0
$79 = 4608

(gdb) p /d sizeof(struct usb_page)
$74 = 16

(gdb) p /d n_frbuffers
$68 = 128

(gdb) p /d parm->bufsize
$70 = 131072

I believe the amount of memory reserved needs to be much higher.  For 
example, if sizeof(struct usb_page) is 16 bytes, then for n_frbuffers of 
128 and parm->bufsize of 131072, we need the following amount of memory 
reserved:

parm->bufsize / USB_PAGE_SIZE * n_frbuffers * sizeof(struct usb_page)
= 131072 / 4096 * 128 * 16
= 65536

Thanks
Aman




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5123FC0B.70009>