Skip to contentSkip to conversation

Pinning kernel memory

DISCUSSION Thomas Schlichter 3 participants 3 messages Dec 12, 2002

lore
Share & tools
lore
#0 lore raw

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

#1 lore raw
Quoted 4 lines · Thomas Schlichter

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

Signature · 3 lines
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>
#2 lore raw

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:

Quoted 10 lines · Thomas Schlichter
Quoted 4 lines

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