lkml.org 
[lkml]   [2003]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectKernel memory allocation and page used counter
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);
}


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:49    [W:0.048 / U:0.472 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site