Hello,
I want to create a big area of unswappable, physical continuous kernel memory
for hardware testing purposes. Currently I allocate the memory using
alloc_pages(GFP_KERNEL, order) and after this I pin it using
SetPageReserved(page) for each page.
Is this acceptable, or may it happen that after the alloc_pages()-call the
kswapd begins to swap out this memory and just any other memory is pinned??
Do I perhaps have to lock the mm->page_table_lock and test each page before I
pin it?? If it is swapped out, how can I assure to get this page back swapped
in?
is SetPageReserved the right way to pin a memory page, or should
SetPageActive(page) or even LockPage(page) be used??
I hope anyone can help me...
Thank you!
Sincerely yours
Thomas Schlichter
On Thu, 12 Dec 2002, Thomas Schlichter wrote:
> I want to create a big area of unswappable, physical continuous kernel memory
> for hardware testing purposes. Currently I allocate the memory using
> alloc_pages(GFP_KERNEL, order) and after this I pin it using
> SetPageReserved(page) for each page.
Kernel memory is never swappable, so there is no need to "pin it".
Rik
--
Bravely reimplemented by the knights who say "NIH".
http://www.surriel.com/ http://guru.conectiva.com/
Current spamtrap: <a href=mailto:"[email protected]">[email protected]</a>
Thanks, Oliver Neukum mailed me a similar answer, too.
So it looks as my problem was an other one, but setting the pages reserved
solved it.
The problem was that I remapped these kernel pages into user space and
accessing this remapped memory always leaded to a SIGBUS. And since setting
the pages reserved "pins" them, I thought they were swapped out...
I don't know if that is the correct way I do it, and if anyone can tell me how
it should be done I'll be interested...
Thomas Schlichter
P.S.: Here are some of the lines from the code I wrote that should show what I
mean... ;-)
int mem_init_module(void)
{
struct page *page;
~~~ cut ~~~
// allocate mem_size bytes of physical continuous kernel memory
page = alloc_pages( GFP_KERNEL, order );
if( !page )
{
printk( "<1>kernel_mem.o: could not get %d bytes of kernel memory\n",
mem_size );
return -ENOMEM;
}
mem_addr = page_address( page );
// pin the memory
while( page < virt_to_page(mem_addr + mem_size) )
SetPageReserved( page++ );
~~~ cut ~~~
return 0; // initialization successful
}
int mem_mmap( struct file *filp, struct vm_area_struct *vma )
{
unsigned long offset; // byte offset from start address
unsigned long physical; // physical start address
unsigned long vsize; // size in virtual address space
unsigned long psize; // size in physical address space
offset = vma->vm_pgoff << PAGE_SHIFT;
physical = virt_to_bus(mem_addr) + offset;
vsize = vma->vm_end - vma->vm_start;
psize = mem_size - offset;
printk( "<1>kernel_mem.o: mmap offset %lu, physical %#010lx, vsize %lu,
psize %lu\n", offset, physical, vsize, psize );
// virtual range is fully mapped to physical address space ?
if ( vsize > psize )
{
printk("<1>kernel_mem.o: mmap failed as vsize > psize\n");
return -EINVAL;
}
// do the remapping
remap_page_range( vma->vm_start, physical, vsize, vma->vm_page_prot );
// register memory operations to the kernel tables (like file operations)
vma->vm_ops = &mem_vm_ops;
// invoke the vma_open routine (which actually does nothing)
mem_vma_open( vma );
return 0;
}
Am Donnerstag, 12. Dezember 2002 21:15 schrieb Rik van Riel:
> On Thu, 12 Dec 2002, Thomas Schlichter wrote:
> > I want to create a big area of unswappable, physical continuous kernel
> > memory for hardware testing purposes. Currently I allocate the memory
> > using alloc_pages(GFP_KERNEL, order) and after this I pin it using
> > SetPageReserved(page) for each page.
>
> Kernel memory is never swappable, so there is no need to "pin it".
>
>
> Rik