Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jan 2016 20:38:39 +0000 (UTC)
From:      Colin Percival <cperciva@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r293698 - head/sys/kern
Message-ID:  <201601112038.u0BKcdhW088420@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cperciva
Date: Mon Jan 11 20:38:39 2016
New Revision: 293698
URL: https://svnweb.freebsd.org/changeset/base/293698

Log:
  Fix a bug introduced in r291716:
  
  "The problem with the approach taken both in _bus_dmamap_load_pages and
  bus_dmamap_load_ma_triv is that they split the request buffer into
  arbitrary chunks based on page boundaries, creating segments that no
  longer have a size that's a multiple of the sector size. This breaks
  drivers like blkfront (and probably other stuff)." [1]
  
  This was most easily triggered by running `fsck /` on a system running
  in Xen (e.g. Amazon EC2) but also showed up via growfs(8) and probably
  many other userland tools which access the disk directly.
  
  Patch by:	royger [1]
  "Thinks this should be fine" by:	ken

Modified:
  head/sys/kern/subr_bus_dma.c

Modified: head/sys/kern/subr_bus_dma.c
==============================================================================
--- head/sys/kern/subr_bus_dma.c	Mon Jan 11 20:27:05 2016	(r293697)
+++ head/sys/kern/subr_bus_dma.c	Mon Jan 11 20:38:39 2016	(r293698)
@@ -131,28 +131,6 @@ _bus_dmamap_load_mbuf_sg(bus_dma_tag_t d
 }
 
 /*
- * Load tlen data starting at offset within a region specified by a list of
- * physical pages.
- */
-static int
-_bus_dmamap_load_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
-    vm_page_t *pages, bus_size_t tlen, int offset, int *nsegs, int flags)
-{
-	vm_paddr_t paddr;
-	bus_size_t len;
-	int error, i;
- 
-	for (i = 0, error = 0; error == 0 && tlen > 0; i++, tlen -= len) {
-		len = min(PAGE_SIZE - offset, tlen);
-		paddr = VM_PAGE_TO_PHYS(pages[i]) + offset;
-		error = _bus_dmamap_load_phys(dmat, map, paddr, len,
-		    flags, NULL, nsegs);
-		offset = 0;
-	}
-	return (error);
-}
- 
-/*
  * Load from block io.
  */
 static int
@@ -168,8 +146,8 @@ _bus_dmamap_load_bio(bus_dma_tag_t dmat,
 	}
 
 	if ((bio->bio_flags & BIO_UNMAPPED) != 0)
-		return (_bus_dmamap_load_pages(dmat, map, bio->bio_ma,
-		    bio->bio_bcount, bio->bio_ma_offset, nsegs, flags));
+		return (_bus_dmamap_load_ma(dmat, map, bio->bio_ma,
+		    bio->bio_bcount, bio->bio_ma_offset, flags, NULL, nsegs));
 
 	return (_bus_dmamap_load_buffer(dmat, map, bio->bio_data,
 	    bio->bio_bcount, kernel_pmap, flags, NULL, nsegs));



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