LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 02-25-2010, 09:23 AM   #1
orback
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Rep: Reputation: 0
Is it safe to use copy_to_user on a __iomem pointer returned by ioremap?


Hi,

I am currently writing a device driver and i wounder if it is safe to use copy_to_user on an __iomem pointer return by ioremap()? Or do I have to copy with memcpy_fromio() to an kmalloced buffer in the driver first and then copy_to_user?

Thanks

Last edited by orback; 02-25-2010 at 09:30 AM.
 
Old 02-26-2010, 05:43 AM   #2
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Hello,

I think copy_to_user will work without problem (not 100% confirm) as ioremap actually maps memory-region in virtual-address space which is valid for any normal memory operations although if you are doing atomic ioremap then make sure that the memory functions used should not sleep

I hope this helps.

Fawad Lateef
 
Old 02-26-2010, 06:21 AM   #3
cladisch
Member
 
Registered: Oct 2008
Location: Earth
Distribution: Slackware
Posts: 228

Rep: Reputation: 54
The contents of the address range returned by ioremap() should not be accessed like normal memory; you have to use the read/writeb/w/l() or memcpy_from/toio() functions.

On x86(-64), MMIO accesses actually are normal memory accesses, so copy_to_user() will work, but this would not be portable to some other architectures.
 
1 members found this post helpful.
Old 02-26-2010, 06:41 AM   #4
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Quote:
Originally Posted by cladisch View Post
The contents of the address range returned by ioremap() should not be accessed like normal memory; you have to use the read/writeb/w/l() or memcpy_from/toio() functions.

On x86(-64), MMIO accesses actually are normal memory accesses, so copy_to_user() will work, but this would not be portable to some other architectures.
Yup, you are right. This is what the comment above that function tells. I used these functions many many years ago, so I mixed up the things. Thanks for reminding me
 
Old 02-26-2010, 08:39 AM   #5
orback
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Original Poster
Rep: Reputation: 0
Ok, thank you for you reply. Do you know if this extra memory copy consumes much performace?
 
Old 02-26-2010, 08:46 AM   #6
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Quote:
Originally Posted by orback View Post
Ok, thank you for you reply. Do you know if this extra memory copy consumes much performace?
There might be some way of copying iomapped data directly to user-space buffer (just search for this), but if you do this extra copy then obviously it will consume CPU cycles and how much cycles it consume depends on size of the buffer/mapped-region
 
Old 02-26-2010, 09:37 AM   #7
cladisch
Member
 
Registered: Oct 2008
Location: Earth
Distribution: Slackware
Posts: 228

Rep: Reputation: 54
Quote:
There might be some way of copying iomapped data directly to user-space buffer (just search for this)
AFAIK there is no function for this.

Since the intermediate buffer is fully cached, there shouldn't be too much of a performance hit; I'd expect it to be unnoticeable in most cases.

If you have to copy really big amounts of data, you might want to allow the application to mmap() the device's address range, or, if that is not possible, to mmap() your own buffer that you copied the data into. (See chapter 15 of LDD3.)
 
Old 02-26-2010, 10:28 AM   #8
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Quote:
Originally Posted by cladisch View Post
AFAIK there is no function for this.

Since the intermediate buffer is fully cached, there shouldn't be too much of a performance hit; I'd expect it to be unnoticeable in most cases.

If you have to copy really big amounts of data, you might want to allow the application to mmap() the device's address range, or, if that is not possible, to mmap() your own buffer that you copied the data into. (See chapter 15 of LDD3.)
Intermediate buffer _might_ be in cache but still copying data will eat cycles (lets say if copy each byte from cache takes 1-cycle then copying 1KB of data will take at-least 1000 cycles, right ?)

Yes, this mmap thing will be right approach for avoiding extra memcpy. As if data is big amount then copying will reduce performance.
 
Old 02-26-2010, 11:05 AM   #9
cladisch
Member
 
Registered: Oct 2008
Location: Earth
Distribution: Slackware
Posts: 228

Rep: Reputation: 54
Quote:
if copy each byte from cache takes 1-cycle then copying 1KB of data will take at-least 1000 cycles, right ?
Yes. However, reading one uncached word from memory can take about 150 cycles, and reading one word from a device might take 1000 cycles. Anything you do in the L1 cache just doesn't matter in comparison.
 
Old 02-26-2010, 11:33 AM   #10
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Quote:
Originally Posted by cladisch View Post
Yes. However, reading one uncached word from memory can take about 150 cycles, and reading one word from a device might take 1000 cycles. Anything you do in the L1 cache just doesn't matter in comparison.
Correct, its negligible as compare to memory or device access, but if high performance is needed then each cycle makes a difference.

Anyways, we can leave this discussion (if you don't mind) and let thread-starter decide if this extra copy effecting him or not according to his requirements.
 
Old 02-27-2010, 03:29 AM   #11
orback
LQ Newbie
 
Registered: Oct 2009
Posts: 7

Original Poster
Rep: Reputation: 0
Thank you for all you info. I have tried to mmap() the device address range and just copy the data direct in the user application with memcpy(). But my problem is that the performance is to bad only 2.5MB/s in read from the device with mmap. I guest that no burst reads are done, only single accesses. The device by the way is an PCI express device. Unfortunately the device has no DMA on it an I have to read large amount of data. It should be enough if I could increase the performance with a factor of 10. Any ideas how to increase the performance? A question about mmap then, the memory that I am mmap in the driver is not ioremapped, I only do:
remap_pfn_range(vma, vma->vm_start, pci_resource_start(pcie->pci_dev, 0) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)
This is the right to do it? I works but like I said the performance is hideous.
 
Old 03-01-2010, 09:49 AM   #12
fslateef
LQ Newbie
 
Registered: Dec 2003
Location: London, UK
Distribution: Ubuntu, Fedora, Debian
Posts: 9

Rep: Reputation: 0
Quote:
Originally Posted by orback View Post
Thank you for all you info. I have tried to mmap() the device address range and just copy the data direct in the user application with memcpy(). But my problem is that the performance is to bad only 2.5MB/s in read from the device with mmap. I guest that no burst reads are done, only single accesses. The device by the way is an PCI express device. Unfortunately the device has no DMA on it an I have to read large amount of data. It should be enough if I could increase the performance with a factor of 10. Any ideas how to increase the performance? A question about mmap then, the memory that I am mmap in the driver is not ioremapped, I only do:
remap_pfn_range(vma, vma->vm_start, pci_resource_start(pcie->pci_dev, 0) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)
This is the right to do it? I works but like I said the performance is hideous.
I used the same remap_pfn_range function in mmap in one of my projects and it was working fine and very fast (but mmaped memory in my case was simple kernel memory-pages not device).

How you are accessing this mapped memory from user-space ? And how you are filling the data from kernel-space ?

It will be good if you can provide some code-snippet, so that anyone can guide you in a better way ?

Regards,

Fawad Lateef
 
Old 03-01-2010, 10:32 AM   #13
cladisch
Member
 
Registered: Oct 2008
Location: Earth
Distribution: Slackware
Posts: 228

Rep: Reputation: 54
Quote:
the performance is too bad only 2.5MB/s in read from the device with mmap. I guess that no burst reads are done, only single accesses.
To enable burst reads, set the page protection flags to cacheable.
However, vma->vm_page_prot comes from userspace and is likely to alredy include those flags. Furthermore, if the device changes the mmap-ed memory, you cannot make it cacheable because you might get stale data.

How fast is kernel driver able to read from the device into its own buffer?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
difference between socket returned descriptor and accept returned descriptor naveenisback Programming 1 08-29-2009 04:55 AM
copy_to_user nili Linux - Kernel 8 05-20-2008 04:08 AM
regarding ioremap() for accessing hardware ksrinivas Debian 0 03-29-2007 10:42 PM
ioremap and remap_page_range mspies Linux - Software 1 08-20-2005 10:41 PM
ioremap() and readl() not compiling CyberEE Linux - Software 0 01-19-2004 10:10 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 08:33 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration