El 28/08/14 a les 20.58, Alexander Motin ha escrit: > On 28.08.2014 21:45, John-Mark Gurney wrote: >> Alexander Motin wrote this message on Thu, Aug 28, 2014 at 21:23 +0300: >>> Hi, Roger. >>> >>> It looks to me like this commit does not work as it should. I got >>> problem when I just tried `newfs /dev/ada0 ; mount /dev/ada0 /mnt`. >>> Somehow newfs does not produce valid filesystem. Problem is reliably >>> repeatable and reverting this commit fixes it. >>> >>> I found at least one possible cause there: If original data buffer is >>> unmapped, misaligned and not physically contiguous, then present x86 >>> bus_dmamap_load_bio() implementation will process each physically >>> contiguous segment separately. Due to the misalignment first and last >>> physical segments may have size not multiple to 512 bytes. Since each >>> segment processed separately, they are not joined together, and >>> xbd_queue_cb() is getting segments not multiple to 512 bytes. Attempt to >>> convert them to exact number of sectors in the driver cause data corruption. >> >> Are you sure this isn't a problem w/ the tag not properly specifying >> the correct alignement? > > I don't know how to specify it stronger then this: > error = bus_dma_tag_create( > bus_get_dma_tag(sc->xbd_dev), /* parent */ > 512, PAGE_SIZE, /* algnmnt, boundary */ > BUS_SPACE_MAXADDR, /* lowaddr */ > BUS_SPACE_MAXADDR, /* highaddr */ > NULL, NULL, /* filter, filterarg */ > sc->xbd_max_request_size, > sc->xbd_max_request_segments, > PAGE_SIZE, /* maxsegsize */ > BUS_DMA_ALLOCNOW, /* flags */ > busdma_lock_mutex, /* lockfunc */ > &sc->xbd_io_lock, /* lockarg */ > &sc->xbd_io_dmat); > >> Also, I don't think there is a way for busdma >> to say that you MUST have a segment be a multiple of 512, though you >> could use a 512 boundary, but that would force all segments to only be >> 512 bytes... > > As I understand, that is mandatory requirement for this "hardware". > Alike 4K alignment requirement also exist at least for SDHCI, and IIRC > UHCI/OHCI hardware. Even AHCI requires both segment addresses and > lengths to be even. > > I may be wrong, but I think it is quite likely that hardware that > requires segment address alignment quite likely will have the same > requirements for segments length.
I've been able to trigger it quite easily by adding the following KASSERTs and got a "panic: Invalid segment size 2080". I will try to look into it tomorrow, or else revert the commit. Thanks for noticing. Roger. --- diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index 7a1c974..6226534 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -199,6 +199,13 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) while (1) { while (sg < last_block_sg) { + + KASSERT((segs->ds_len % 512) == 0, + ("Invalid segment size %u", segs->ds_len)); + KASSERT((segs->ds_addr % 512) == 0, + ("Invalid segment alignment ds_addr: %jx", + (uintmax_t) segs->ds_addr)); + buffer_ma = segs->ds_addr; fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT; lsect = fsect + (segs->ds_len >> XBD_SECTOR_SHFT) - 1; _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"