Shared memeory between the user and kernel mode

We're looking for suggestions on the recommended method for sharing a memory region (on the order of 1.5 meg)between user-level apps. and a device driver in a high-performance application. The reason for sharing the memory is to nterleave between (MPEG) hardware driver and the library where either the user-level apps., or the device driver can modify the shared memory region (using mainly atomic ops. and polling to achieve the necessary interlocks). The shared memory must remain resident, permanently allocated (at least as long as the apps. and/or the device driver need it) and accessible from both the kernel and user-level.

So far, we see some implementation alternatives:

1.Shared memory primitives 2.Use mmap(2) to map a file into the user address space and pin it into memory

Related question:

1.is a device driver permitted to make system calls that for example obtain/release a user-level semaphore (cf, semget(2))?

2.Is there a list somewhere, of driver do's and don'ts, listing allowed system calls from a kernel-level driver?

3.We'd like to be able to use semaphores to synchronize access to the shared mem. instead of a more elaborate atomic-op related scheme, that requires polling when contention is detected, but whatever method we use, it has to work inside the kernel-level driver as well in the user-app. how?

4.What is the best approach for performing the mapping of kernel mememory into user memory?

5.How should the user memory address space mananged (ie, how does the driver determine where the memory should be allocated in the user address space)?

6.Are there internal kernel functions that can be called to accomplish most of the work, or do the page tables have to be modified directly by the driver (that's what we're doing now)?

7.Are there any security and/or MP gotchas (we're familiar with how the MP issues are handled in the kernel but are wondering what are the non-obvious issues relating to page table management, etc. that we should be aware of).

Best Regards,

kawshol

Reply to
kawshol
Loading thread data ...

The standard way to do this is to implement the mmap() call in your device driver. Framebuffers generally use this, and the X Window system uses mmap() to render directly into the frame buffer itself.

This is the wrong approach. Generally you don't want the kernel interacting with userspace in this kind of way.

The driver probably does not need to autonomously operate on the data in the buffer of it's own accord, so from that perspective, there should be no requirement for locking. Instead, the system should be designed such that your video hardware responds to commands from user space (eg via ioctl()) which tell it to perform operations on the buffer. In this way, the responsibility for ensuring that two conflicting operations on the buffer do not occur is shifted out of the driver and into userspace.

See Linux Device Drivers and implementing the mmap() call.

No it does not, the virtual address which is mapped onto the physical hardware address will not be fixed. Calling mmap() will return a pointer to the address where the hardware can be accessed.

Jeez, that sounds bad. Why are you messing with the page tables ?

Reply to
Geronimo W. Christ Esq

Hi Geronimo,

Ok I understand better now. mmap() is the way. I am newbie to the linux.

I would rephrase the problem I have a MPEG hardware block that needs the ~1.5 MB physical contiguous memory(fixed at a address). A user-land library will fill the packets to be encoded to this memory space. The hardware encoder will put back the encoded data to this space back.

My questions are.

1.Can I allocate a memory in the kernel space and using mmap() share that with the user space? can I fix this space when kernel boots? 2.Can I set some asynchronous events that can be triggered on the interrupt form the hardware( to write to frame-buffer)?(or I need to implement the poll() in library?)

Best Regards, kawshol

Ger> > We're looking for suggestions on the recommended method for sharing a

Reply to
kawshol

I assume the buffer you're referring to is split into input and output sections.

The trouble is that while you can use mmap() to make the buffer visible from both user and kernel space, you also have to tell the driver each time there is some more data ready to be encoded; also the driver has to report back to userspace when a newly encoded packet is available. That makes it slightly more tricky.

You might be better off with a more simple implementation using read() and write(). It's a shade less efficient than a shared buffer, but easier to understand.

You can allocate RAM and share it this way certainly. But how does your hardware access it - is it using DMA ?

Why do you need to do that ?

If you are looking to have userspace respond to an interrupt from the hardware, then yes, poll() is generally the way this is done. You can also use signals but that's a bit more messy.

Reply to
Geronimo W. Christ Esq

Thanks,

we have some solution, we keep aside some memory form the linux and then we map this memory for the shareing using mmap. In user-space and kernel-space this memory can be accessed. Because the memory area is just another memory pool is has to be managed separately (hence propriety memory management). It uses one the standard malloc() function of Linux to allocate the memory pool.

we have split the interrupt in to two parts user mode a polling while kernel mode just registers the event.

Thanks for the help.

Best Regards, kawshol

Reply to
kawshol

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.