We're looking for suggestions on the recommended method for
sharing a memory region (on the order of 0.5 meg) between
user-level apps. and a device driver in a high-performance
application. The reason for sharing the memory is to
interleave debugging- and transaction- related info. 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 two implementation
1) use shared memory primitives (shmget(2),shmctl(2),
shmat(2), shmdt(2)). Here, probably at boot time, an suid
root program would allocate the shared memory buffer,
specifying SHM_LOCK to shmctl(), which will lock the pages
into memory, once touched. We haven't used those functions
before, and are a little uneasy with the warning in the
ftok(3) description that says the key it returns is
not-so-unique, but that is not the central problem.
Once the memory has been allocated, and touched by the
initialization program to bring it into physical memory, it
will remain resident. Subsequently, the user apps. would
make an ioctl() call to the driver to tell it where the
shared memory is located.
After the shared memory has been created and mapped into
user space, can the driver access the user memory without
making further arrangments - or is it required it map the
memory into kernel space? What about access control and
address validity check issues?
Related question: is a device driver permitted to make
system calls that for example obtain/release a user-level
semaphore (cf, semget(2))? Is there a list somewhere, of
driver do's and don'ts, listing allowed system calls from a
kernel-level driver? 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.
1a) use mmap(2) to map a file into the user address space,
and call mlock(2) to pin it into memory (this operation
would be done at boot time). This is similar to (1) above,
but uses differnt primitives. It isn't so important that
an actual file is mapped, because it will be pinned into
memory, but this seems to be the only method of
sharing memory, when making mmap() calls.
This approach offers a natural method for the applications
to find the shared memory by name, and to configure the
size at runtime, and doesn't suffer from the uniqueness
difficulties of ftok().
2) have a driver do the allocation from kernel mmeory, and
then map that into the user address space. This is the
approach we are currently taking, and have prototyped. The
driver supports an ioctl() to allocate the shared memory
buffer, and to map it into user-space. What is the best
approach for performing the mapping of kernel mem. into
user memory? 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)?
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)? 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).
Any suggestions, or pointers to existing code and/or
documentation that relate to the problem of sharing
mem. between user-level apps., and a kernel-level
Thanks, - Gary
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to email@example.com
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:10 EST