All of lore.kernel.org
 help / color / mirror / Atom feed
* Kernel memory allocation and page used counter
@ 2003-10-14  9:08 Hans Berglund
  0 siblings, 0 replies; only message in thread
From: Hans Berglund @ 2003-10-14  9:08 UTC (permalink / raw)
  To: linux-kernel

I have reserved a bounch of 128k sized pieces of kernel memory
using addr[i] = __get_free_pages (GFP_KERNEL, 5); repeated times.

The first time the pages are used, I can DMA to this memory,
and get the data without problems. After freeing the memory
with free_pages (addr[i], 5); and allocating next time, the
kernel crashes in different ways each time when I use the memory.
Usually an oops with the message: "Unable to handle kernel paging
request at virtual address xxxxxxxx".

I have noticed that the struct page->count.counter of the first page
of each 128k chunk is incremented, but not of the remaining pages.
Then I tried to increment the counter "manually" by using get_page()
just after allocation, and the system seemed to become stable.

Do I really have to mark the pages as used, just after allocation, and
is there a kernel call to du this in one operation?
If the pages are used by others, why does the kernel crash after the
second allocation, and not the first?


I am running kernel 2.4.19, and I use the code below to do the
mapping.

All answers are appreciated.

Hans



struct page *xxx_vma_nopage (struct vm_area_struct *vma,
			      unsigned long addr, int write)
{
     int offset, block;
     void *virt_addr;
     card_t *cp;
     struct page *cpage;

     cp = vma->vm_private_data;
     offset = addr - vma->vm_start;
     if ((addr < vma->vm_start) || (addr >= vma->vm_end))
     {
	PWARNING ("nopage: Mapping out of range, start=0x%x, addr=0x%x,"
		  "end=0x%x\n",
		  (int)vma->vm_start, (int)addr, (int)vma->vm_end);
	return (0);
     }
     block = offset / KM_SIZE;         /* KM_SIZE = 128k */
     virt_addr = cp->list[block].address + (offset % KM_SIZE);
     cpage = virt_to_page (virt_addr);
     get_page (cpage);
     return (cpage);
}


struct vm_operations_struct xxx_vmops =
{
     open:   xxx_vma_open,
     close:  xxx_vma_close,
     nopage: xxx_vma_nopage,
};


int
xxx_mmap (struct file *filp, struct vm_area_struct *vma)
{
     card_t *cp = &xxxarr[MINOR(filp->f_dentry->d_inode->i_rdev)];
     vma->vm_flags |= VM_RESERVED;

     vma->vm_ops = &xxx_vmops;
     vma->vm_private_data = cp;
     xxx_vma_open(vma);
     return (0);
}



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-10-14  9:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-14  9:08 Kernel memory allocation and page used counter Hans Berglund

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.