Hi,
can anyone explain me why it is not possible to mmap(2) a buffer
allocated in kernel by pci_alloc_consistent() to userspace on a 2.4
kernel?
In kernel PCI device initialization function I do something like:
...
kladdr = pci_alloc_consistent (dev, BUFSIZE, &baddr);
...
Then I send the physical address (i.e. the value of phaddr = __pa(kladdr))
to the userspace application, and then when in the userspace I do
something like
...
fd = fopen ("/dev/mem", O_RDWR);
buf = mmap (NULL, BUFSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phaddr);
...
I get a mapping stated correctly in /proc/<pid>/maps as
40016000-4001e000 rw-s 11ac0000 00:06 4 /dev/mem
which is all correct. But when I read the contents of the mmap(2)ped
memory within the application I get all zeroes, while the value of the
buffer when read from kernel space or by simply doing
dd if=/dev/mem of=temp.dat bs=65536 skip=4524 count=1
I get the correct values (which are not all zeros). Something in the
process of mmap(2) system call seems to redirect the pages to /dev/zero it
seems. Is it intentional? Why?
Can I get around it somehow? The desired goal would be to mmap the buffer
directly from kernel upon an ioctl call to the driver of the PCI device.
(I do it by emmulating the mmap(2) call but initiated from the kernel by
calling the do_mmap_pgoff() with appropriate arguments, but (no surprise)
it does the same thing as the mmap(2) called from the userspace.
Can the mmapping be done correctly at least from the kernel somehow? Or is
it not possible at all.
Any hint would be much appreciated.
Thanks,
Martin.
On Fri, 2005-09-16 at 20:33 +0200, Martin Drab wrote:
> Hi,
>
> can anyone explain me why it is not possible to mmap(2) a buffer
> allocated in kernel by pci_alloc_consistent() to userspace on a 2.4
> kernel?
>
> In kernel PCI device initialization function I do something like:
>
> ...
> kladdr = pci_alloc_consistent (dev, BUFSIZE, &baddr);
> ...
>
> Then I send the physical address (i.e. the value of phaddr = __pa(kladdr))
> to the userspace application, and then when in the userspace I do
> something like
>
> ...
> fd = fopen ("/dev/mem", O_RDWR);
> buf = mmap (NULL, BUFSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phaddr);
> ...
yuch.
why don't you make your device have an mmap operation instead?
(the device node that you use to get your physical address to userspace
in the first place)
On Fri, 16 Sep 2005, Arjan van de Ven wrote:
> On Fri, 2005-09-16 at 20:33 +0200, Martin Drab wrote:
> > Hi,
> >
> > can anyone explain me why it is not possible to mmap(2) a buffer
> > allocated in kernel by pci_alloc_consistent() to userspace on a 2.4
> > kernel?
> >
> > In kernel PCI device initialization function I do something like:
> >
> > ...
> > kladdr = pci_alloc_consistent (dev, BUFSIZE, &baddr);
> > ...
> >
> > Then I send the physical address (i.e. the value of phaddr = __pa(kladdr))
> > to the userspace application, and then when in the userspace I do
> > something like
> >
> > ...
> > fd = fopen ("/dev/mem", O_RDWR);
> > buf = mmap (NULL, BUFSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phaddr);
> > ...
>
>
> yuch.
> why don't you make your device have an mmap operation instead?
> (the device node that you use to get your physical address to userspace
> in the first place)
And would that help anyhow?
Just a background:
This is a RT driver for the RT Linux (that's why the 2.4 kernel). It is a
data acquisition card. What I would like to do is:
Driver allocates a finite (predefined) number of DMA buffers with
pci_alloc_consistent() during the initialization. (This fixed alloc is
necessary, since when you switch the driver into RT you cannot do any
memory allocations anymore). And then I would like to fill a buffer via
DMA, send a notice to the app. via the RT FIFO device that a buffer is
filled, app. then calls the ioctl of the RT FIFO with the buffer number
(obtained via the RT FIFO) that he wants to mmap, the ioctl mmaps it to
the app., app. uses the data, and then calls another ioctl to unmap the
buffer and release it for next filling.
There's just a limited way to communicate between the RT and non-RT part
of the kernel/app. The RT-FIFOs and their IOCTLs are safe. I'm not
entirely sure a simple mmap would be safe here, but I may try that.
Martin
On Fri, 16 Sep 2005, Martin Drab wrote:
> On Fri, 16 Sep 2005, Arjan van de Ven wrote:
> > On Fri, 2005-09-16 at 20:33 +0200, Martin Drab wrote:
> > > Hi,
> > >
> > > can anyone explain me why it is not possible to mmap(2) a buffer
> > > allocated in kernel by pci_alloc_consistent() to userspace on a 2.4
> > > kernel?
> > >
> > > In kernel PCI device initialization function I do something like:
> > >
> > > ...
> > > kladdr = pci_alloc_consistent (dev, BUFSIZE, &baddr);
> > > ...
> > >
> > > Then I send the physical address (i.e. the value of phaddr = __pa(kladdr))
> > > to the userspace application, and then when in the userspace I do
> > > something like
> > >
> > > ...
> > > fd = fopen ("/dev/mem", O_RDWR);
> > > buf = mmap (NULL, BUFSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phaddr);
> > > ...
> >
> > yuch.
> > why don't you make your device have an mmap operation instead?
> > (the device node that you use to get your physical address to userspace
> > in the first place)
>
> And would that help anyhow?
...
>
> There's just a limited way to communicate between the RT and non-RT part
> of the kernel/app. The RT-FIFOs and their IOCTLs are safe. I'm not
> entirely sure a simple mmap would be safe here, but I may try that.
Well, now that I think about it, I think it may be done in a "safe" way,
since the RT would be in total controll over the buffers, and would
allow to mmap only the filled buffers after they are filled. But that
would assume, that the app. behaves politely and only asks for the buffers
that it gets a notification for. Or am I mistaken somewhere?
Martin
On Fri, Sep 16, 2005 at 11:24:08PM +0200, Martin Drab wrote:
>
> And would that help anyhow?
yes it would
> (obtained via the RT FIFO) that he wants to mmap, the ioctl mmaps it to
> the app., app. uses the data, and then calls another ioctl to unmap the
> buffer and release it for next filling.
don't use ioctls for this; the driver can just provide an mmap method and
you can map this pci alloc'd ram straight into the userspace app...
On Fri, 16 Sep 2005, Arjan van de Ven wrote:
>
> On Fri, Sep 16, 2005 at 11:24:08PM +0200, Martin Drab wrote:
> >
> > And would that help anyhow?
>
> yes it would
>
> > (obtained via the RT FIFO) that he wants to mmap, the ioctl mmaps it to
> > the app., app. uses the data, and then calls another ioctl to unmap the
> > buffer and release it for next filling.
>
> don't use ioctls for this; the driver can just provide an mmap method and
> you can map this pci alloc'd ram straight into the userspace app...
OK, will do. Thaks.
Martin