linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Re: Problems with DMA from user space on MPC834x (Cache coherency?)
@ 2006-10-12 17:32 Manish Joshi
  2006-10-13  9:18 ` Lauri Ehrenpreis
  0 siblings, 1 reply; 6+ messages in thread
From: Manish Joshi @ 2006-10-12 17:32 UTC (permalink / raw)
  To: Lauri Ehrenpreis, linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 3216 bytes --]

Yeah it looks like a cache coherency problem from the first look.
You may try enabling snooping on the DMA channel if MPC824X supports it. Check in Mode register setting.
Else you may want to use flush_dcache_range(start, last) functions and see if it helps.
 
----- Original Message ----
From: Lauri Ehrenpreis <lauri.ehrenpreis@liewenthal.ee>
To: linuxppc-embedded@ozlabs.org
Sent: Wednesday, October 11, 2006 7:20:03 AM
Subject: Problems with DMA from user space on MPC834x (Cache coherency?)


Hi!

I have a problem with DMA from user space on a platform powered by MPC834x
processor (which has powerpc e300 core inside). Our linux kernel version is
2.6.17.

My user space program does something like this:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma();

while /disk is mounted to a partition residing on USB memory stick or SD
card.
page_aligned_buf starts from page boundary and contains enough full pages
for
the data (so I can allways map full page with dma_map_page in kernel).

The buffer address and data length will then be passed to a driver, which
calls
get_user_pages, then maps each page with dma_map_page and tells a PCI
device
to start reading from that page:

...
down_read(&current->mm->mmap_sem);
result = get_user_pages(current, current->mm, page_aligned_buf, nr_pages,
0, 0, pages, NULL);
up_read(&current->mm->mmap_sem);

for (i = 0; i < nr_pages; i++) {
    find_data_checksum(pages[i]);
    dma_addr = dma_map_page(&fpga.pci_dev->dev, pages[i], 0, PAGE_SIZE,
DMA_TO_DEVICE);

    start_dma();

    wait_until_dma_ready();

    dma_unmap_page(&fpga.pci_dev->dev, dma_addr, dma_len, DMA_TO_DEVICE);

    if(!checksum_ok_in_fpga())
        print_page_data();
}

for (i = 0; i < nr_pages; i++)
    page_cache_release(pages[i]);

The problem is that sometimes the PCI device receives wrong bytes at random
locations. I find the data checksum inside the driver and inside the FPGA.
Inside the driver I use kmap(page) and kunmap(page) to access data on the
user page. Sometimes the checksums do not match and I can see with the FPGA
debugging tool, that the FPGA receives different data than the driver is
printing out.

I have noticed 3 things regarding this error:
1) When I copy the data I read from the block device to another buffer in
userspace and pass this new buffer to the driver, then this error will
never occur:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
memcpy(new_page_aligned_buf, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma(new_page_aligned_buf, len);

2) this error does not occur when I use copy_from_user instead of
get_user_pages
and dma_map_page inside driver.

3) this error does not occur on our previuos device, which has x86
platform.

I am currently out of ideas what to do next.. It seems to me like a cache
coherency problem. Can anyone suggest what might be wrong?

--
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


[-- Attachment #2: Type: text/html, Size: 4713 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread
* Problems with DMA from user space on MPC834x (Cache coherency?)
@ 2006-10-11 14:20 Lauri Ehrenpreis
  0 siblings, 0 replies; 6+ messages in thread
From: Lauri Ehrenpreis @ 2006-10-11 14:20 UTC (permalink / raw)
  To: linuxppc-embedded


Hi!

I have a problem with DMA from user space on a platform powered by MPC834x
processor (which has powerpc e300 core inside). Our linux kernel version is
2.6.17.

My user space program does something like this:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma();

while /disk is mounted to a partition residing on USB memory stick or SD
card.
page_aligned_buf starts from page boundary and contains enough full pages
for
the data (so I can allways map full page with dma_map_page in kernel).

The buffer address and data length will then be passed to a driver, which
calls
get_user_pages, then maps each page with dma_map_page and tells a PCI
device
to start reading from that page:

...
down_read(&current->mm->mmap_sem);
result = get_user_pages(current, current->mm, page_aligned_buf, nr_pages,
0, 0, pages, NULL);
up_read(&current->mm->mmap_sem);

for (i = 0; i < nr_pages; i++) {
	find_data_checksum(pages[i]);
	dma_addr = dma_map_page(&fpga.pci_dev->dev, pages[i], 0, PAGE_SIZE,
DMA_TO_DEVICE);

	start_dma();

	wait_until_dma_ready();

	dma_unmap_page(&fpga.pci_dev->dev, dma_addr, dma_len, DMA_TO_DEVICE);

	if(!checksum_ok_in_fpga())
		print_page_data();
}

for (i = 0; i < nr_pages; i++)
	page_cache_release(pages[i]);

The problem is that sometimes the PCI device receives wrong bytes at random
locations. I find the data checksum inside the driver and inside the FPGA.
Inside the driver I use kmap(page) and kunmap(page) to access data on the
user page. Sometimes the checksums do not match and I can see with the FPGA
debugging tool, that the FPGA receives different data than the driver is
printing out.

I have noticed 3 things regarding this error:
1) When I copy the data I read from the block device to another buffer in
userspace and pass this new buffer to the driver, then this error will
never occur:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
memcpy(new_page_aligned_buf, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma(new_page_aligned_buf, len);

2) this error does not occur when I use copy_from_user instead of
get_user_pages
and dma_map_page inside driver.

3) this error does not occur on our previuos device, which has x86
platform.

I am currently out of ideas what to do next.. It seems to me like a cache
coherency problem. Can anyone suggest what might be wrong?

--

^ permalink raw reply	[flat|nested] 6+ messages in thread
* Problems with DMA from user space on MPC834x (Cache coherency?)
@ 2006-10-11 14:14 Lauri Ehrenpreis
  0 siblings, 0 replies; 6+ messages in thread
From: Lauri Ehrenpreis @ 2006-10-11 14:14 UTC (permalink / raw)
  To: linuxppc-embedded


Hi!

I have a problem with DMA from user space on a platform powered by MPC834x
processor (which has powerpc e300 core inside). Our linux kernel version is
2.6.17.

My user space program does something like this:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma();

while /disk is mounted to a partition residing on USB memory stick or SD  
card.
page_aligned_buf starts from page boundary and contains enough full pages  
for
the data (so I can allways map full page with dma_map_page in kernel).

The buffer address and data length will then be passed to a driver, which  
calls
get_user_pages, then maps each page with dma_map_page and tells a PCI  
device
to start reading from that page:

...
down_read(&current->mm->mmap_sem);
result = get_user_pages(current, current->mm, page_aligned_buf, nr_pages,  
0, 0, pages, NULL);
up_read(&current->mm->mmap_sem);

for (i = 0; i < nr_pages; i++) {
	find_data_checksum(pages[i]);
	dma_addr = dma_map_page(&fpga.pci_dev->dev, pages[i], 0, PAGE_SIZE,  
DMA_TO_DEVICE);

	start_dma();

	wait_until_dma_ready();

	dma_unmap_page(&fpga.pci_dev->dev, dma_addr, dma_len, DMA_TO_DEVICE);

	if(!checksum_ok_in_fpga())
		print_page_data();
}

for (i = 0; i < nr_pages; i++)
	page_cache_release(pages[i]);

The problem is that sometimes the PCI device receives wrong bytes at random
locations. I find the data checksum inside the driver and inside the FPGA.
Inside the driver I use kmap(page) and kunmap(page) to access data on the
user page. Sometimes the checksums do not match and I can see with the FPGA
debugging tool, that the FPGA receives different data than the driver is
printing out.

I have noticed 3 things regarding this error:
1) When I copy the data I read from the block device to another buffer in
userspace and pass this new buffer to the driver, then this error will
never occur:

file_fd = open("/disk/file", O_RDONLY);
result = read(file_fd, page_aligned_buf, len);
memcpy(new_page_aligned_buf, page_aligned_buf, len);
call_driver_ioctl_which_performs_dma(new_page_aligned_buf, len);

2) this error does not occur when I use copy_from_user instead of  
get_user_pages
and dma_map_page inside driver.

3) this error does not occur on our previuos device, which has x86  
platform.

I am currently out of ideas what to do next.. It seems to me like a cache
coherency problem. Can anyone suggest what might be wrong?

--

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-10-13 15:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-12 17:32 Problems with DMA from user space on MPC834x (Cache coherency?) Manish Joshi
2006-10-13  9:18 ` Lauri Ehrenpreis
2006-10-13 15:27   ` Kumar Gala
2006-10-13 15:49     ` Liu Dave-r63238
  -- strict thread matches above, loose matches on Subject: below --
2006-10-11 14:20 Lauri Ehrenpreis
2006-10-11 14:14 Lauri Ehrenpreis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).