Re: usb_pc_cpu_flush

2015-02-02 Thread Hans Petter Selasky

Hi Ian,

Any news on this issue?

I've put the following patch into -current for your convenience:

https://svnweb.freebsd.org/changeset/base/278074

Kohji: Maybe you also want to test and review this patch?

--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-16 Thread Hans Petter Selasky

Hi Ian,

Please find attached a patch which disable the double mapping of 
allocated DMA capable buffers in the USB stack for all drivers.


Can you test it and check out the total memory usage before and after 
the patch? Also verify it if makes any difference on any platforms.


Thank you!

--HPS
Index: sys/dev/usb/usb_transfer.c
===
--- sys/dev/usb/usb_transfer.c	(revision 277240)
+++ sys/dev/usb/usb_transfer.c	(working copy)
@@ -237,7 +237,7 @@
 		n_obj = 1;
 	} else {
 		/* compute number of objects per page */
-		n_obj = (USB_PAGE_SIZE / size);
+		n_obj = 1; /* (USB_PAGE_SIZE / size); */
 		/*
 		 * Compute number of DMA chunks, rounded up
 		 * to nearest one:
@@ -273,8 +273,11 @@
 		&parm->curr_xfer->xroot->dma_parent_tag;
 	}
 
-	if (ppc) {
-		*ppc = parm->xfer_page_cache_ptr;
+	if (ppc != NULL) {
+		if (n_obj != 1)
+			*ppc = parm->xfer_page_cache_ptr;
+		else
+			*ppc = parm->dma_page_cache_ptr;
 	}
 	r = count;			/* set remainder count */
 	z = n_obj * size;		/* set allocation size */
@@ -281,7 +284,18 @@
 	pc = parm->xfer_page_cache_ptr;
 	pg = parm->dma_page_ptr;
 
-	for (x = 0; x != n_dma_pc; x++) {
+	if (n_obj == 1) {
+	for (x = 0; x != n_dma_pc; x++) {
+		if (usb_pc_alloc_mem(parm->dma_page_cache_ptr,
+		pg, z, align)) {
+			return (1);	/* failure */
+		}
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
+		parm->dma_page_cache_ptr++;
+		pg += n_dma_pg;
+	}
+	} else {
+	for (x = 0; x != n_dma_pc; x++) {
 
 		if (r < n_obj) {
 			/* compute last remainder */
@@ -294,7 +308,7 @@
 		}
 		/* Set beginning of current buffer */
 		buf = parm->dma_page_cache_ptr->buffer;
-		/* Make room for one DMA page cache and one page */
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
 		parm->dma_page_cache_ptr++;
 		pg += n_dma_pg;
 
@@ -314,6 +328,7 @@
 			}
 			mtx_unlock(pc->tag_parent->mtx);
 		}
+	}
 	}
 
 	parm->xfer_page_cache_ptr = pc;
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"

Re: usb_pc_cpu_flush

2015-01-14 Thread Hans Petter Selasky

On 01/14/15 16:03, Ian Lepore wrote:

If you are allocating the memory using bus_dmamem_alloc() then no,
absolutely not.  It's working for you by accident because of the
USB_HOST_ALIGN hacks which I think date back to freebsd 8 or so.

When I talked to you a couple years ago about doing it the right way,
you were outraged (perhaps rightly so) about the inefficiency involved,
because of things like allocating a 16 byte buffer causing the
allocation of a full page just so that the caching attributes could be
changed.  So I fixed that with the busdma zone allocator stuff that
makes it very efficient to allocate many tiny dma buffers (coherent or
not), and when you use buffers allocated that way, the sync operations
code can make some safe assumptions and avoid doing bounces due to
cacheline alignments.

If buffers were allocated right-sized now that it's efficient to do so,
the USB_HOST_ALIGN hack could go away.   Hmm, actually it might be
necessary to start using the busdma zone allocator in mips as well
before undoing the hack.


Hi Ian,

This sounds good. I'll make a quick patch you can try this week which 
splits the USB busdma allocations again. It is a quite trivial thing to 
do. Can you or Kott then test this patch?


--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-14 Thread Ian Lepore
On Wed, 2015-01-14 at 06:13 +0100, Hans Petter Selasky wrote:
> On 01/13/15 21:25, Ian Lepore wrote:
> > On Tue, 2015-01-13 at 17:52 +0100, Hans Petter Selasky wrote:
> >> On 01/13/15 17:29, Ian Lepore wrote:
> >>> On Tue, 2015-01-13 at 16:57 +0100, Hans Petter Selasky wrote:
[...]
> >>
> >> Hi,
> >>
> >> Can you give an example of a NIC driver which you consider a good
> >> example which use DMA both for data (not only mbufs) and the control
> >> path and use busdma as you consider to be correct?
> >>
> >> --HPS
> >
> > dev/ffec/if_ffec.c.  I'm not happy with the fact that it takes two calls
> > (a PRE and a POST) to accomplish a single action, but that's the right
> > way to do things in the current busdma world, PRE and POST operations
> > need to be paired.
> >
> > I think we need new busdma support for shared concurrent access
> > descriptors, because it's a type of dma that just isn't supported well
> > by the existing API.  There should be a new flag for bus_dmamem_alloc()
> > that indicates the memory is going to be used for such shared access
> > (because some platforms may be able to provide memory that's mapped
> > optimally for such situations), and there should be new sync ops that
> > don't require a pair of calls to accomplish a single action.
> >
> > All of this is in the context of shared descriptor memory.  Regular IO
> > buffers should just use the proper sequence of PRE and POST syncs (and
> > most especially should *never* do POSTREAD before PREREAD like the
> > current usb_pc_cpu_invalidate() does, because with bounce buffers that
> > will just not work right).
> >
> 
> Hi,
> 
> I understand and that can be done for IO-buffers like in the FFEC 
> driver. For other buffers it is a bigger task, however:
> 
> I see that some memory is allocated using "BUS_DMA_COHERENT" in 
> if_ffec.c and in those cases no busdma sync operations are performed! Is 
> that correct? For example "rxdesc_ring" is allocated coherently and no 
> cache sync ops are done before and after access.
> 

No, it does do sync operations on the descriptors rings, because one of
the documented rules of coherent memory is that you still have to do all
the normal sync ops.  Traditionally coherent has meant "completely
disable caching" on arm and you could get away with not doing the sync
ops, but that's not true anymore.  Arm memory subsystems are more
complex these days and sync ops are needed in some cases even for
uncached memory.

In the current ffec code, sync ops on descriptor memory are done on line
655/657 (these could really be back to back without the TDAR write
between them).  At this point new descriptors have been written to the
tx ring and the PREWRITE makes the changes visible to the hardware, the
write into the TDAR register informs the hardware that descriptors were
changed and it should rescan the list.  The POSTWRITE is a no-op but
included for technical correctness.

Another desc-ring related set of sync ops is on lines 683-684.  In this
case the hardware has updated some of the descriptors and the
PREREAD/POSTREAD sync ops ensure that the cpu will see the changes.  The
same is true on lines 850-851.  This is the place where having two calls
is really a performance hit, because both PRE and POSTREAD sync will do
an invalidate, and it really only needs to be done once, but the busdma
conventions are that PRE and POST ops need to come in properly-sequenced
pairs.

And finally on 899-900 is the rx code similar to the tx code on 655/657,
where the driver has updated descriptors in the ring and done a PREWRITE
to make the changes visible to the hardware.

> The buffer that Mr. Kott hit a crash on should also be allocated 
> coherently. Looking at the ARM busdma code in -current I see a possible bug:
> 
> > int
> > _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
> > bus_size_t buflen, struct pmap *pmap, int flags, bus_dma_segment_t 
> > *segs,
> > int *segp)
> > {
> > bus_size_t sgsize;
> > bus_addr_t curaddr;
> > struct sync_list *sl;
> > vm_offset_t vaddr = (vm_offset_t)buf;
> > int error = 0;
> >
> > if (segs == NULL)
> > segs = dmat->segments;
> > if ((flags & BUS_DMA_LOAD_MBUF) != 0)
> > map->flags |= DMAMAP_CACHE_ALIGNED;
> >
> > if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
> > _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, 
> > flags);
> > if (map->pagesneeded != 0) {
> > error = _bus_dmamap_reserve_pages(dmat, map, flags);
> > if (error)
> > return (error);
> > }
> > }
> > CTR3(KTR_BUSDMA, "lowaddr= %d boundary= %d, "
> > "alignment= %d", dmat->lowaddr, dmat->boundary, 
> > dmat->alignment);
> >
> > while (buflen > 0) {
> > /*
> >  * Get the physical address for this segme

Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 21:25, Ian Lepore wrote:

On Tue, 2015-01-13 at 17:52 +0100, Hans Petter Selasky wrote:

On 01/13/15 17:29, Ian Lepore wrote:

On Tue, 2015-01-13 at 16:57 +0100, Hans Petter Selasky wrote:

On 01/13/15 16:40, Ian Lepore wrote:

On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:

On 01/13/15 15:49, Ian Lepore wrote:

On Tue, 2015-01-13 at 00:14 -0700, kott wrote:

Yes with cache disabled, this problem is not seen. Seems to be with a issue
with l2 cache.
Thanks kott


Except that there are no known problems with l2 cache on armv7 right
now.  There are known problems with the USB driver using the busdma
routines incorrectly, which accidentally works okay on x86 platforms but
likely not so well on others.



Hi,

If there is a problem it is in "usb_pc_cpu_flush()" or
"usb_pc_cpu_invalidate()":

void
usb_pc_cpu_flush(struct usb_page_cache *pc)
{
if (pc->page_offset_end == pc->page_offset_buf) {
/* nothing has been loaded into this page cache! */
return;
}
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
}

USB has a very simple DMA sync language, either flush or invalidate.
These are used correctly from what I can see with regard to the FreeBSD
USB specification.
(unless a simple restart somehow fixes the problem)
If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be
written to RAM before the function returns, please let me know.

--HPS


You have an incomplete concept of how busdma sync operations work.  It
isn't a simple "cpu cache written to ram" operation, there are bounce
buffers and other complexities involved that require that the sync
operations be done at the correct time in the correct order, and the
current usb driver doesn't do that.  Instead it does things like

bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);

And that's just nonsense that will lead to problems like delivering
random buffer garbage to/from a device.

To the degree that USB works at all on non-x86 platforms it works by
accident.  Usually.  Except when it doesn't.

-- Ian



Hi,

Bounce buffers are perfectly fine with USB as long as the busdma does
what it is told. If there is no easy way to do a simple "cache flush" or
"cache invalide" or bounce buffer "flush" or bounce buffer "invalidate"
multiple times in a row, then busdma cannot co-exist with USB. It is not
because I'm stubborn, but because of the way USB DMA controllers are
designed.

With USB chipsets we sometimes need to read the RAM area for a single
buffer multiple times to poll for updates. From what I've been told in
the past BUSDMA does.

--HPS

--HPS

--HPS



And so we reach the same old impasse, where you declare that USB is
special and doesn't have to behave like other drivers, even though it is
in no way unique in terms of having things like concurrent shared access
to descriptor memory, something that virtually every modern NIC has.



Hi,

Can you give an example of a NIC driver which you consider a good
example which use DMA both for data (not only mbufs) and the control
path and use busdma as you consider to be correct?

--HPS


dev/ffec/if_ffec.c.  I'm not happy with the fact that it takes two calls
(a PRE and a POST) to accomplish a single action, but that's the right
way to do things in the current busdma world, PRE and POST operations
need to be paired.

I think we need new busdma support for shared concurrent access
descriptors, because it's a type of dma that just isn't supported well
by the existing API.  There should be a new flag for bus_dmamem_alloc()
that indicates the memory is going to be used for such shared access
(because some platforms may be able to provide memory that's mapped
optimally for such situations), and there should be new sync ops that
don't require a pair of calls to accomplish a single action.

All of this is in the context of shared descriptor memory.  Regular IO
buffers should just use the proper sequence of PRE and POST syncs (and
most especially should *never* do POSTREAD before PREREAD like the
current usb_pc_cpu_invalidate() does, because with bounce buffers that
will just not work right).



Hi,

I understand and that can be done for IO-buffers like in the FFEC 
driver. For other buffers it is a bigger task, however:


I see that some memory is allocated using "BUS_DMA_COHERENT" in 
if_ffec.c and in those cases no busdma sync operations are performed! Is 
that correct? For example "rxdesc_ring" is allocated coherently and no 
cache sync ops are done before and after access.


The buffer that Mr. Kott hit a crash on should also be allocated 
coherently. Looking at the ARM busdma code in -current I see a possible bug:



int
_bus

Re: usb_pc_cpu_flush

2015-01-13 Thread Ian Lepore
On Tue, 2015-01-13 at 17:52 +0100, Hans Petter Selasky wrote:
> On 01/13/15 17:29, Ian Lepore wrote:
> > On Tue, 2015-01-13 at 16:57 +0100, Hans Petter Selasky wrote:
> >> On 01/13/15 16:40, Ian Lepore wrote:
> >>> On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:
> >>>> On 01/13/15 15:49, Ian Lepore wrote:
> >>>>> On Tue, 2015-01-13 at 00:14 -0700, kott wrote:
> >>>>>> Yes with cache disabled, this problem is not seen. Seems to be with a 
> >>>>>> issue
> >>>>>> with l2 cache.
> >>>>>> Thanks kott
> >>>>>
> >>>>> Except that there are no known problems with l2 cache on armv7 right
> >>>>> now.  There are known problems with the USB driver using the busdma
> >>>>> routines incorrectly, which accidentally works okay on x86 platforms but
> >>>>> likely not so well on others.
> >>>>>
> >>>>
> >>>> Hi,
> >>>>
> >>>> If there is a problem it is in "usb_pc_cpu_flush()" or
> >>>> "usb_pc_cpu_invalidate()":
> >>>>
> >>>> void
> >>>> usb_pc_cpu_flush(struct usb_page_cache *pc)
> >>>> {
> >>>>if (pc->page_offset_end == pc->page_offset_buf) {
> >>>>/* nothing has been loaded into this page cache! */
> >>>>return;
> >>>>}
> >>>>bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
> >>>> }
> >>>>
> >>>> USB has a very simple DMA sync language, either flush or invalidate.
> >>>> These are used correctly from what I can see with regard to the FreeBSD
> >>>> USB specification.
> >>>> (unless a simple restart somehow fixes the problem)
> >>>> If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be
> >>>> written to RAM before the function returns, please let me know.
> >>>>
> >>>> --HPS
> >>>
> >>> You have an incomplete concept of how busdma sync operations work.  It
> >>> isn't a simple "cpu cache written to ram" operation, there are bounce
> >>> buffers and other complexities involved that require that the sync
> >>> operations be done at the correct time in the correct order, and the
> >>> current usb driver doesn't do that.  Instead it does things like
> >>>
> >>>   bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
> >>>   bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);
> >>>
> >>> And that's just nonsense that will lead to problems like delivering
> >>> random buffer garbage to/from a device.
> >>>
> >>> To the degree that USB works at all on non-x86 platforms it works by
> >>> accident.  Usually.  Except when it doesn't.
> >>>
> >>> -- Ian
> >>>
> >>
> >> Hi,
> >>
> >> Bounce buffers are perfectly fine with USB as long as the busdma does
> >> what it is told. If there is no easy way to do a simple "cache flush" or
> >> "cache invalide" or bounce buffer "flush" or bounce buffer "invalidate"
> >> multiple times in a row, then busdma cannot co-exist with USB. It is not
> >> because I'm stubborn, but because of the way USB DMA controllers are
> >> designed.
> >>
> >> With USB chipsets we sometimes need to read the RAM area for a single
> >> buffer multiple times to poll for updates. From what I've been told in
> >> the past BUSDMA does.
> >>
> >> --HPS
> >>
> >> --HPS
> >>
> >> --HPS
> >>
> >
> > And so we reach the same old impasse, where you declare that USB is
> > special and doesn't have to behave like other drivers, even though it is
> > in no way unique in terms of having things like concurrent shared access
> > to descriptor memory, something that virtually every modern NIC has.
> >
> 
> Hi,
> 
> Can you give an example of a NIC driver which you consider a good 
> example which use DMA both for data (not only mbufs) and the control 
> path and use busdma as you consider to be correct?
> 
> --HPS

dev/ffec/if_ffec.c.  I'm not happy with the fact that it takes two calls
(a PRE and a POST) to accomplish a single action, but that's the right
way to do things in the current busdma world, PRE and POST operations
need to be paired.

I think we need new busdma support for shared concurrent access
descriptors, because it's a type of dma that just isn't supported well
by the existing API.  There should be a new flag for bus_dmamem_alloc()
that indicates the memory is going to be used for such shared access
(because some platforms may be able to provide memory that's mapped
optimally for such situations), and there should be new sync ops that
don't require a pair of calls to accomplish a single action.

All of this is in the context of shared descriptor memory.  Regular IO
buffers should just use the proper sequence of PRE and POST syncs (and
most especially should *never* do POSTREAD before PREREAD like the
current usb_pc_cpu_invalidate() does, because with bounce buffers that
will just not work right).

-- Ian

 

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

Hi Kott,

Can you tell us which ARM kernel configuration file you are using for 
FreeBSD? Reading through this thread I cannot see this piece of 
information yet.


Have you tested other ARM platforms?

Thank you,

--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 17:52, Hans Petter Selasky wrote:


Hi,

Can you give an example of a NIC driver which you consider a good
example which use DMA both for data (not only mbufs) and the control
path and use busdma as you consider to be correct?

--HPS


So that I can compare this agains what USB is doing.

--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 17:29, Ian Lepore wrote:

On Tue, 2015-01-13 at 16:57 +0100, Hans Petter Selasky wrote:

On 01/13/15 16:40, Ian Lepore wrote:

On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:

On 01/13/15 15:49, Ian Lepore wrote:

On Tue, 2015-01-13 at 00:14 -0700, kott wrote:

Yes with cache disabled, this problem is not seen. Seems to be with a issue
with l2 cache.
Thanks kott


Except that there are no known problems with l2 cache on armv7 right
now.  There are known problems with the USB driver using the busdma
routines incorrectly, which accidentally works okay on x86 platforms but
likely not so well on others.



Hi,

If there is a problem it is in "usb_pc_cpu_flush()" or
"usb_pc_cpu_invalidate()":

void
usb_pc_cpu_flush(struct usb_page_cache *pc)
{
   if (pc->page_offset_end == pc->page_offset_buf) {
   /* nothing has been loaded into this page cache! */
   return;
   }
   bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
}

USB has a very simple DMA sync language, either flush or invalidate.
These are used correctly from what I can see with regard to the FreeBSD
USB specification.

If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be
written to RAM before the function returns, please let me know.

--HPS


You have an incomplete concept of how busdma sync operations work.  It
isn't a simple "cpu cache written to ram" operation, there are bounce
buffers and other complexities involved that require that the sync
operations be done at the correct time in the correct order, and the
current usb driver doesn't do that.  Instead it does things like

bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);

And that's just nonsense that will lead to problems like delivering
random buffer garbage to/from a device.

To the degree that USB works at all on non-x86 platforms it works by
accident.  Usually.  Except when it doesn't.

-- Ian



Hi,

Bounce buffers are perfectly fine with USB as long as the busdma does
what it is told. If there is no easy way to do a simple "cache flush" or
"cache invalide" or bounce buffer "flush" or bounce buffer "invalidate"
multiple times in a row, then busdma cannot co-exist with USB. It is not
because I'm stubborn, but because of the way USB DMA controllers are
designed.

With USB chipsets we sometimes need to read the RAM area for a single
buffer multiple times to poll for updates. From what I've been told in
the past BUSDMA does.

--HPS

--HPS

--HPS



And so we reach the same old impasse, where you declare that USB is
special and doesn't have to behave like other drivers, even though it is
in no way unique in terms of having things like concurrent shared access
to descriptor memory, something that virtually every modern NIC has.



Hi,

Can you give an example of a NIC driver which you consider a good 
example which use DMA both for data (not only mbufs) and the control 
path and use busdma as you consider to be correct?


--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Ian Lepore
On Tue, 2015-01-13 at 16:57 +0100, Hans Petter Selasky wrote:
> On 01/13/15 16:40, Ian Lepore wrote:
> > On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:
> >> On 01/13/15 15:49, Ian Lepore wrote:
> >>> On Tue, 2015-01-13 at 00:14 -0700, kott wrote:
> >>>> Yes with cache disabled, this problem is not seen. Seems to be with a 
> >>>> issue
> >>>> with l2 cache.
> >>>> Thanks kott
> >>>
> >>> Except that there are no known problems with l2 cache on armv7 right
> >>> now.  There are known problems with the USB driver using the busdma
> >>> routines incorrectly, which accidentally works okay on x86 platforms but
> >>> likely not so well on others.
> >>>
> >>
> >> Hi,
> >>
> >> If there is a problem it is in "usb_pc_cpu_flush()" or
> >> "usb_pc_cpu_invalidate()":
> >>
> >> void
> >> usb_pc_cpu_flush(struct usb_page_cache *pc)
> >> {
> >>   if (pc->page_offset_end == pc->page_offset_buf) {
> >>   /* nothing has been loaded into this page cache! */
> >>   return;
> >>   }
> >>   bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
> >> }
> >>
> >> USB has a very simple DMA sync language, either flush or invalidate.
> >> These are used correctly from what I can see with regard to the FreeBSD
> >> USB specification.
> >>
> >> If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be
> >> written to RAM before the function returns, please let me know.
> >>
> >> --HPS
> >
> > You have an incomplete concept of how busdma sync operations work.  It
> > isn't a simple "cpu cache written to ram" operation, there are bounce
> > buffers and other complexities involved that require that the sync
> > operations be done at the correct time in the correct order, and the
> > current usb driver doesn't do that.  Instead it does things like
> >
> > bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
> > bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);
> >
> > And that's just nonsense that will lead to problems like delivering
> > random buffer garbage to/from a device.
> >
> > To the degree that USB works at all on non-x86 platforms it works by
> > accident.  Usually.  Except when it doesn't.
> >
> > -- Ian
> >
> 
> Hi,
> 
> Bounce buffers are perfectly fine with USB as long as the busdma does 
> what it is told. If there is no easy way to do a simple "cache flush" or 
> "cache invalide" or bounce buffer "flush" or bounce buffer "invalidate" 
> multiple times in a row, then busdma cannot co-exist with USB. It is not 
> because I'm stubborn, but because of the way USB DMA controllers are 
> designed.
> 
> With USB chipsets we sometimes need to read the RAM area for a single 
> buffer multiple times to poll for updates. From what I've been told in 
> the past BUSDMA does.
> 
> --HPS
> 
> --HPS
> 
> --HPS
> 

And so we reach the same old impasse, where you declare that USB is
special and doesn't have to behave like other drivers, even though it is
in no way unique in terms of having things like concurrent shared access
to descriptor memory, something that virtually every modern NIC has.

-- Ian


___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 16:57, Hans Petter Selasky wrote:

BUSDMA does.

--HPS


... allow this.

--HPS

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 16:40, Ian Lepore wrote:

On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:

On 01/13/15 15:49, Ian Lepore wrote:

On Tue, 2015-01-13 at 00:14 -0700, kott wrote:

Yes with cache disabled, this problem is not seen. Seems to be with a issue
with l2 cache.
Thanks kott


Except that there are no known problems with l2 cache on armv7 right
now.  There are known problems with the USB driver using the busdma
routines incorrectly, which accidentally works okay on x86 platforms but
likely not so well on others.



Hi,

If there is a problem it is in "usb_pc_cpu_flush()" or
"usb_pc_cpu_invalidate()":

void
usb_pc_cpu_flush(struct usb_page_cache *pc)
{
  if (pc->page_offset_end == pc->page_offset_buf) {
  /* nothing has been loaded into this page cache! */
  return;
  }
  bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
}

USB has a very simple DMA sync language, either flush or invalidate.
These are used correctly from what I can see with regard to the FreeBSD
USB specification.

If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be
written to RAM before the function returns, please let me know.

--HPS


You have an incomplete concept of how busdma sync operations work.  It
isn't a simple "cpu cache written to ram" operation, there are bounce
buffers and other complexities involved that require that the sync
operations be done at the correct time in the correct order, and the
current usb driver doesn't do that.  Instead it does things like

bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);

And that's just nonsense that will lead to problems like delivering
random buffer garbage to/from a device.

To the degree that USB works at all on non-x86 platforms it works by
accident.  Usually.  Except when it doesn't.

-- Ian



Hi,

Bounce buffers are perfectly fine with USB as long as the busdma does 
what it is told. If there is no easy way to do a simple "cache flush" or 
"cache invalide" or bounce buffer "flush" or bounce buffer "invalidate" 
multiple times in a row, then busdma cannot co-exist with USB. It is not 
because I'm stubborn, but because of the way USB DMA controllers are 
designed.


With USB chipsets we sometimes need to read the RAM area for a single 
buffer multiple times to poll for updates. From what I've been told in 
the past BUSDMA does.


--HPS

--HPS

--HPS

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Ian Lepore
On Tue, 2015-01-13 at 16:27 +0100, Hans Petter Selasky wrote:
> On 01/13/15 15:49, Ian Lepore wrote:
> > On Tue, 2015-01-13 at 00:14 -0700, kott wrote:
> >> Yes with cache disabled, this problem is not seen. Seems to be with a issue
> >> with l2 cache.
> >> Thanks kott
> >
> > Except that there are no known problems with l2 cache on armv7 right
> > now.  There are known problems with the USB driver using the busdma
> > routines incorrectly, which accidentally works okay on x86 platforms but
> > likely not so well on others.
> >
> 
> Hi,
> 
> If there is a problem it is in "usb_pc_cpu_flush()" or 
> "usb_pc_cpu_invalidate()":
> 
> void
> usb_pc_cpu_flush(struct usb_page_cache *pc)
> {
>  if (pc->page_offset_end == pc->page_offset_buf) {
>  /* nothing has been loaded into this page cache! */
>  return;
>  }
>  bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
> }
> 
> USB has a very simple DMA sync language, either flush or invalidate. 
> These are used correctly from what I can see with regard to the FreeBSD 
> USB specification.
> 
> If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be 
> written to RAM before the function returns, please let me know.
> 
> --HPS

You have an incomplete concept of how busdma sync operations work.  It
isn't a simple "cpu cache written to ram" operation, there are bounce
buffers and other complexities involved that require that the sync
operations be done at the correct time in the correct order, and the
current usb driver doesn't do that.  Instead it does things like 

bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD);

And that's just nonsense that will lead to problems like delivering
random buffer garbage to/from a device.

To the degree that USB works at all on non-x86 platforms it works by
accident.  Usually.  Except when it doesn't.

-- Ian


___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Hans Petter Selasky

On 01/13/15 15:49, Ian Lepore wrote:

On Tue, 2015-01-13 at 00:14 -0700, kott wrote:

Yes with cache disabled, this problem is not seen. Seems to be with a issue
with l2 cache.
Thanks kott


Except that there are no known problems with l2 cache on armv7 right
now.  There are known problems with the USB driver using the busdma
routines incorrectly, which accidentally works okay on x86 platforms but
likely not so well on others.



Hi,

If there is a problem it is in "usb_pc_cpu_flush()" or 
"usb_pc_cpu_invalidate()":


void
usb_pc_cpu_flush(struct usb_page_cache *pc)
{
if (pc->page_offset_end == pc->page_offset_buf) {
/* nothing has been loaded into this page cache! */
return;
}
bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE);
}

USB has a very simple DMA sync language, either flush or invalidate. 
These are used correctly from what I can see with regard to the FreeBSD 
USB specification.


If the "usb_pc_cpu_flush()" function does not cause the CPU cache to be 
written to RAM before the function returns, please let me know.


--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread Ian Lepore
On Tue, 2015-01-13 at 00:14 -0700, kott wrote:
> Yes with cache disabled, this problem is not seen. Seems to be with a issue
> with l2 cache.
> Thanks kott

Except that there are no known problems with l2 cache on armv7 right
now.  There are known problems with the USB driver using the busdma
routines incorrectly, which accidentally works okay on x86 platforms but
likely not so well on others.

-- Ian


___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2015-01-13 Thread kott
Yes with cache disabled, this problem is not seen. Seems to be with a issue
with l2 cache.
Thanks kott



--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5980199.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-29 Thread kott
Will check with  cache disabled. this may be the problem 



--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5976832.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-25 Thread Hans Petter Selasky

Hi,

There might be an option somewhere you can set in the boot enviroment, 
which will disable the CPU cache ... I guess something is failing in 
that area. Else we would see the same with regular PCs too.


--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread Hans Petter Selasky

On 12/24/14 15:35, kott via freebsd-usb wrote:

did try with freebsd11 also and it fails in the same point at
usb_pc_cpu_flush.
Is this a known issue ? any suggestions would help



This is not a known issue. Which ARM kernel are you building?

--HPS

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread kott via freebsd-usb
did try with freebsd11 also and it fails in the same point at 
usb_pc_cpu_flush.
Is this a known issue ? any suggestions would help



--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5975773.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread Hans Petter Selasky

On 12/24/14 13:22, kott via freebsd-usb wrote:

This platform is armv7 freebsd10. it does fail in the second usb_pc_cpu_flush




Did you try booting a freebsd11 kernel?

--HPS

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread kott via freebsd-usb
This platform is armv7 freebsd10. it does fail in the second usb_pc_cpu_flush



--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5975763.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread kott via freebsd-usb
Thanks
platform is  freebsd10 ,  armv7 based.



--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5975752.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-24 Thread Hans Petter Selasky

On 12/24/14 04:41, kott via freebsd-usb wrote:

the value of "r0" is 0.



Hi,

In the function "_ehci_append_qh" do you know if it is the second or 
first call to "usb_pc_cpu_flush" which fails. The pointer which is 
passed as an argument to this function resides in the memory which is 
flushed, so most likely the cache sync operations are not working like 
expected!


What platform is this? Non-freebsd? Did it work before?

--HPS
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-23 Thread kott via freebsd-usb
the value of "r0" is 0.

>>>>>>
_ehci_append_qh: 0xf3dd2300 to 0xf3dc3c00
Kernel page fault with the following non-sleepable locks held:
exclusive sleep mutex ehci0 (usb_def_mtx) r = 0 (0xc73ece74) locked
sys/dev/usb/usb_transfer.c
exclusive sleep mutex USB device mutex (USB device mutex) r = 0 (0xc73da850)
locked sys/de/usb/usb_transfer.c

Fatal kernel mode data abort: 'Translation Fault (S)'
trapframe: 0xf3de6be0
FSR=0005, FAR=0018, spsr=6113
r0 =, r1 =6113, r2 =00c0, r3 =00fd2302
r4 =f3dd2300, r5 =f3dc3c00, r6 =c12b244c, r7 =c76420c0
r8 =c73ed2a8, r9 =, r10=c7642000, r11=f3de6c3c
r12=f3de6c40, ssp=f3de6c30, slr=c105ec48, pc =c1069e34


Stopped at  usb_pc_cpu_flush+0xc:   ldr r2, [r0, #0x018]
>>>>>>>





--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583p5975691.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


Re: usb_pc_cpu_flush

2014-12-23 Thread Hans Petter Selasky

On 12/23/14 19:26, kott wrote:

Hello -
I am seeing this fault when i plugin a external usb device, and was
wondering if this indicates DMA/Cache coherency problem
-
_ehci_append_qh: 0xf3dd2300 to 0xf3dc3c00
Kernel page fault with the following non-sleepable locks held:
exclusive sleep mutex ehci0 (usb_def_mtx) r = 0 (0xc73ece74) locked @
sys/dev/usb/usb_transfer.c
exclusive sleep mutex USB device mutex (USB device mutex) r = 0 (0xc73da850)
locked @ /sys/dev/usb/usb_transfer.c

Stopped at  usb_pc_cpu_flush+0xc:   ldr r2, [r0, #0x018]


Thanks
kott


Hi,

The flush is supposed to call some other functions which write the 
memory cache to RAM. It should not panic like that. Can you get the 
complete backtrace. I guess that some memory content might have been 
lost due to missing or wrong cache sync operations. What is the value of 
"r0" ?


--HPS

___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"


usb_pc_cpu_flush

2014-12-23 Thread kott
Hello - 
I am seeing this fault when i plugin a external usb device, and was
wondering if this indicates DMA/Cache coherency problem 
-
_ehci_append_qh: 0xf3dd2300 to 0xf3dc3c00
Kernel page fault with the following non-sleepable locks held:
exclusive sleep mutex ehci0 (usb_def_mtx) r = 0 (0xc73ece74) locked @
sys/dev/usb/usb_transfer.c
exclusive sleep mutex USB device mutex (USB device mutex) r = 0 (0xc73da850)
locked @ /sys/dev/usb/usb_transfer.c

Stopped at  usb_pc_cpu_flush+0xc:   ldr r2, [r0, #0x018]


Thanks
kott





--
View this message in context: 
http://freebsd.1045724.n5.nabble.com/usb-pc-cpu-flush-tp5975583.html
Sent from the freebsd-usb mailing list archive at Nabble.com.
___
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"