PERFORCE change 28578 for review
Peter Wemm
peter at FreeBSD.org
Tue Apr 8 17:22:32 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=28578
Change 28578 by peter at peter_daintree on 2003/04/08 17:21:50
integrate i386_hammer branch
Affected files ...
.. //depot/projects/hammer/sys/x86_64/include/pmap.h#17 integrate
.. //depot/projects/hammer/sys/x86_64/include/vmparam.h#6 integrate
.. //depot/projects/hammer/sys/x86_64/x86_64/busdma_machdep.c#5 integrate
Differences ...
==== //depot/projects/hammer/sys/x86_64/include/pmap.h#17 (text+ko) ====
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/i386/include/pmap.h,v 1.96 2003/04/04 10:09:44 jake Exp $
+ * $FreeBSD: src/sys/i386/include/pmap.h,v 1.98 2003/04/08 18:22:41 jake Exp $
*/
#ifndef _MACHINE_PMAP_H_
==== //depot/projects/hammer/sys/x86_64/include/vmparam.h#6 (text+ko) ====
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)vmparam.h 5.9 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/i386/include/vmparam.h,v 1.34 2003/02/24 20:29:52 jake Exp $
+ * $FreeBSD: src/sys/i386/include/vmparam.h,v 1.35 2003/04/07 14:27:19 jake Exp $
*/
@@ -86,7 +86,7 @@
* messy at times, but hey, we'll do anything to save a page :-)
*/
-#define VM_MAX_KERNEL_ADDRESS VADDR(0, 0, KPTDI+NKPDE, 0)
+#define VM_MAX_KERNEL_ADDRESS VADDR(0, 0, KPTDI+NKPDE-1, NPTEPG-1)
#define VM_MIN_KERNEL_ADDRESS VADDR(0, 0, PTDPTDI, PTDPTDI)
#define KERNBASE VADDR(0, 0, KPTDI, 0)
==== //depot/projects/hammer/sys/x86_64/x86_64/busdma_machdep.c#5 (text+ko) ====
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.38 2003/03/25 00:07:02 jake Exp $
+ * $FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.39 2003/04/07 16:08:32 jake Exp $
*/
#include <sys/param.h>
@@ -46,7 +46,7 @@
#include <machine/bus.h>
#include <machine/md_var.h>
-#define MAX_BPAGES 128
+#define MAX_BPAGES 512
struct bus_dma_tag {
bus_dma_tag_t parent;
@@ -99,7 +99,8 @@
static void init_bounce_pages(void *dummy);
static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
-static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map);
+static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+ int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
vm_offset_t vaddr, bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
@@ -294,9 +295,10 @@
panic("bus_dmamap_create: page reallocation "
"not implemented");
}
- pages = atop(dmat->maxsize);
+ pages = MAX(atop(dmat->maxsize), 1);
pages = MIN(maxpages - total_bpages, pages);
- error = alloc_bounce_pages(dmat, pages);
+ if (alloc_bounce_pages(dmat, pages) < pages)
+ error = ENOMEM;
if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
if (error == 0)
@@ -458,7 +460,7 @@
/* Reserve Necessary Bounce Pages */
if (map->pagesneeded != 0) {
mtx_lock(&bounce_lock);
- if (reserve_bounce_pages(dmat, map) != 0) {
+ if (reserve_bounce_pages(dmat, map, 1) != 0) {
/* Queue us for resources */
map->dmat = dmat;
@@ -531,27 +533,65 @@
*/
static int
_bus_dmamap_load_buffer(bus_dma_tag_t dmat,
+ bus_dmamap_t map,
bus_dma_segment_t segs[],
void *buf, bus_size_t buflen,
struct thread *td,
int flags,
- vm_offset_t *lastaddrp,
+ bus_addr_t *lastaddrp,
int *segp,
int first)
{
bus_size_t sgsize;
bus_addr_t curaddr, lastaddr, baddr, bmask;
- vm_offset_t vaddr = (vm_offset_t)buf;
+ vm_offset_t vaddr;
+ bus_addr_t paddr;
+ int needbounce = 0;
int seg;
pmap_t pmap;
+ if (map == NULL)
+ map = &nobounce_dmamap;
+
if (td != NULL)
pmap = vmspace_pmap(td->td_proc->p_vmspace);
else
pmap = NULL;
+ if (dmat->lowaddr < ptoa((vm_paddr_t)Maxmem)) {
+ vm_offset_t vendaddr;
+
+ /*
+ * Count the number of bounce pages
+ * needed in order to complete this transfer
+ */
+ vaddr = trunc_page((vm_offset_t)buf);
+ vendaddr = (vm_offset_t)buf + buflen;
+
+ while (vaddr < vendaddr) {
+ paddr = pmap_kextract(vaddr);
+ if (run_filter(dmat, paddr) != 0) {
+ needbounce = 1;
+ map->pagesneeded++;
+ }
+ vaddr += PAGE_SIZE;
+ }
+ }
+
+ vaddr = (vm_offset_t)buf;
+
+ /* Reserve Necessary Bounce Pages */
+ if (map->pagesneeded != 0) {
+ mtx_lock(&bounce_lock);
+ if (reserve_bounce_pages(dmat, map, 0) != 0) {
+ mtx_unlock(&bounce_lock);
+ return (ENOMEM);
+ }
+ mtx_unlock(&bounce_lock);
+ }
+
lastaddr = *lastaddrp;
- bmask = ~(dmat->boundary - 1);
+ bmask = ~(dmat->boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
/*
@@ -578,6 +618,9 @@
sgsize = (baddr - curaddr);
}
+ if (map->pagesneeded != 0 && run_filter(dmat, curaddr))
+ curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+
/*
* Insert chunk into a segment, coalescing with
* previous segment if possible.
@@ -587,7 +630,7 @@
segs[seg].ds_len = sgsize;
first = 0;
} else {
- if (curaddr == lastaddr &&
+ if (needbounce == 0 && curaddr == lastaddr &&
(segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
(dmat->boundary == 0 ||
(segs[seg].ds_addr & bmask) == (curaddr & bmask)))
@@ -630,8 +673,6 @@
#endif
int nsegs, error;
- KASSERT(dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) || map != NULL,
- ("bus_dmamap_load_mbuf: No support for bounce pages!"));
KASSERT(m0->m_flags & M_PKTHDR,
("bus_dmamap_load_mbuf: no packet header"));
@@ -639,12 +680,12 @@
error = 0;
if (m0->m_pkthdr.len <= dmat->maxsize) {
int first = 1;
- vm_offset_t lastaddr = 0;
+ bus_addr_t lastaddr = 0;
struct mbuf *m;
for (m = m0; m != NULL && error == 0; m = m->m_next) {
if (m->m_len > 0) {
- error = _bus_dmamap_load_buffer(dmat,
+ error = _bus_dmamap_load_buffer(dmat, map,
dm_segments,
m->m_data, m->m_len,
NULL, flags, &lastaddr,
@@ -675,7 +716,7 @@
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
- vm_offset_t lastaddr;
+ bus_addr_t lastaddr;
#ifdef __GNUC__
bus_dma_segment_t dm_segments[dmat->nsegments];
#else
@@ -686,9 +727,6 @@
struct iovec *iov;
struct thread *td = NULL;
- KASSERT(dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) || map != NULL,
- ("bus_dmamap_load_uio: No support for bounce pages!"));
-
resid = uio->uio_resid;
iov = uio->uio_iov;
@@ -711,7 +749,7 @@
caddr_t addr = (caddr_t) iov[i].iov_base;
if (minlen > 0) {
- error = _bus_dmamap_load_buffer(dmat,
+ error = _bus_dmamap_load_buffer(dmat, map,
dm_segments,
addr, minlen,
td, flags, &lastaddr, &nsegs, first);
@@ -836,12 +874,14 @@
}
static int
-reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map)
+reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit)
{
int pages;
mtx_assert(&bounce_lock, MA_OWNED);
pages = MIN(free_bpages, map->pagesneeded - map->pagesreserved);
+ if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages))
+ return (map->pagesneeded - (map->pagesreserved + pages));
free_bpages -= pages;
reserved_bpages += pages;
map->pagesreserved += pages;
@@ -856,6 +896,9 @@
{
struct bounce_page *bpage;
+ KASSERT(map != NULL && map != &nobounce_dmamap,
+ ("add_bounce_page: bad map %p", map));
+
if (map->pagesneeded == 0)
panic("add_bounce_page: map doesn't need any pages");
map->pagesneeded--;
@@ -893,7 +936,7 @@
free_bpages++;
active_bpages--;
if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) {
- if (reserve_bounce_pages(map->dmat, map) == 0) {
+ if (reserve_bounce_pages(map->dmat, map, 1) == 0) {
STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links);
More information about the p4-projects
mailing list