On Tue, May 30, 2000 at 07:58:41PM +0200, Uwe H. Speck wrote:
> Hi David and all others,
>
> could someone please explain what are the consequences of the problem
> David wrote about the possible size of a module. He wrote (copy of this
> see at the end of my mail):
>
> "Yet another good reason not to use global variables in modules,
> since this means that it is more *** difficult to find their physical address ***."
>
> My questions (note: I'm using *** RTAI ***):
>
> If I declare (for example) 4 arrays of each 50kb as global variables in a module.
> Is there a problem accessing the array members???
>
> Is there really NO limitation of memory use in a module?
>
> What about the maximum Stack size. Would a Stack of 50kB be possible or is
> there a danger using a stack bigger than 8192 bytes?
>
>
> Thanks in advance
This is a bit longer and answers more than the questions you asked, but
I've seen these questions asked before.
The method for loading modules is as follows: The insmod command reads
the .o file, copies the code into a temporary buffer, and then fixes all
the unresolved symbols. It then does the load_module system call, and
the kernel allocates a block of memory **using vmalloc**, and copies the
user-space image of the module to the in-kernel buffer. Then it runs
init_module().
The important point is that it uses vmalloc(). Actually, only current
kernels use vmalloc, older kernels (2.0, maybe) used kmalloc. kmalloc()
is limited to 128 kB _maximum_, although in practice, it is difficult to
get more than 16 kB. This is because kmalloc allocates contiguous RAM --
most of the time, a large contiguous block of RAM does not exist. This
became a problem as more of the kernel became modularized, and especially
when some drivers became larger than 128 kB. One of the advantages of
using kmalloc() is that virtual memory addresses in the allocated space
are easily converted to physical addresses, i.e., the signals that are
send to the DRAM controller. This is very convenient if you are writing
a hardware driver.
vmalloc() gets around the 128 (hard) / 16 (realistic) barrier by not
allocating contiguous space, but rather allocating a bunch of individual
pages around physical RAM, and maps them contiguously in virtual memory
space. This is convenient for code and static data that is accessed
by the processor, i.e., through a C pointer. However, if you want to
convert a virtual address to a physical address, you (actually, a kernel
function) need to go through the page tables, find the page containing
the address, and then see where it is mapped to. This takes a lot longer
than x-or'ing with 0xc0000000. And you need to do this with every
PAGE_SIZE range of addresses, since the mapping to physical memory is
not contiguous.
The distinction between kmalloc and vmalloc becomes an issue when you
write drivers for busmastering PCI cards. These cards need to know the
physical addresses of buffers that it copies to/from. Most drivers
allocate a large chunk of RAM using vmalloc, and then walk through
each page of the chunk, convert the virtual address to a physical
address, and write the physical address to the PCI device. The PCI
device then thinks the buffer is a collection of small buffers
scattered around in physical memory. The device doesn't really care
that they are scattered around, since it was designed for this kind
of operation. Naturally, you could do the same thing using kmalloc,
except it would be a little bit faster, because it is easier to
convert a kmalloc address to a physical address.
For a real-time device, things are only slightly more complicated.
The function that converts vmalloc addresses to physical addresses is
not real-time compatible (it grabs spinlocks). Thus, you need to
convert all the pages in your vmalloc buffer to physical addresses
_before_ you go real-time. Not a big deal, but it is an issue that
you need to know and program around.
If you don't use busmastering PCI DMA, chances are that all of this
is irrelevant, since you don't need to convert virtual addresses to
physical addresses anyway.
Another (soft) real-time consideration with using vmalloc() is that
it can call schedule() if it can't allocate all the memory that was
asked for. If you are writing a soft-real-time friendly device driver,
like Comedi, this can be an issue, because the driver may be causing
uncontrolled pauses in the soft-real-time task.
I dislike global variables, and especially global variable buffers
because of programming style issues.
I don't know about issues related to stack size.
dave...
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/