12

This is my module to allocate one huge page by using dequeue_huge_page_vma() and alloc_buddy_huge_page(). To make them vma independent, I get available vm area from __get_vm_area_node(), and then get its virtual address. I want to allocate one 2MB page, however, kernel says :

[   84.944634] BUG: unable to handle kernel paging request at ffffc90013d02000
[   84.944641] IP: [<ffffffffa0ac9063>] vma_null_test+0x63/0xa3 [vma_null_test]
[   84.944650] PGD bd019067 PUD bd01a067 PMD b35c0067 PTE 0
[   84.944657] Oops: 0000 [#1] SMP 

My code:

/*
 * vma_null_test.c - Cindy: to test if vma can be set to NULL in alloc_huge_page() 
 */

 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/hugetlb.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <asm/page.h>
 #include <linux/nodemask.h>
 #include <linux/gfp.h>
 #include <linux/mm_types.h>
 #include <asm-generic/pgtable.h>
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #define TWO_MB 0x200000

struct hstate *h;

struct vm_struct *__get_vm_area_node(unsigned long size,
            unsigned long align, unsigned long flags, unsigned long start,
            unsigned long end, int node, gfp_t gfp_mask, void *caller);

struct page *dequeue_huge_page_vma(struct hstate *,struct vm_area_struct *,
            unsigned long, int);

struct page *alloc_buddy_huge_page(struct hstate *,struct vm_area_struct *,
                            unsigned long);

struct page *alloc_huge_page_node_mod(unsigned long vaddr)
{
struct page *page;

page = dequeue_huge_page_vma(h, NULL, vaddr, 0);

if (!page)
    page = alloc_buddy_huge_page(h, NULL, vaddr);

return page;
}

static int __init vma_null_test(void)
{
  struct vm_struct *area;
  h=&default_hstate;
  unsigned long *address;
  struct page *page;
  int ret;

  area=__get_vm_area_node(TWO_MB, 1, VM_ALLOC, VMALLOC_START, VMALLOC_END, -1,   GFP_KERNEL|__GFP_HIGHMEM, __builtin_return_address(0));
  address=(unsigned long *)area->addr;
  page=alloc_huge_page_node_mod(*address);
  if(IS_ERR(page)){
  ret=-PTR_ERR(page);
  printk(KERN_ERR "Cannot allocate page\n");

  }
  else{
  ret=0;
  printk(KERN_ERR "Allocate one huge page at virtual address:%x\n",*address);
  }

  return ret;
}

static void __exit vma_null_exit(void)
{
  printk(KERN_ERR ".............Exit..........\n");
}

module_init(vma_null_test);
module_exit(vma_null_exit);
MODULE_LICENSE("GPL");
red0ct
  • 4,840
  • 3
  • 17
  • 44
CindyRabbit
  • 359
  • 2
  • 17
  • add a printk statement after each statement and see where it crashes. Also, you can try to load debug symbols into the debugger and check where it crashed. And paste more information from the crash report. There should be more than what you included. – feeling_lonely May 14 '14 at 20:23
  • Can you provide dump of the area object ? – t0k3n1z3r Oct 07 '14 at 08:19

1 Answers1

0

This is a really old question, but what the heck...

__get_vm_area_node() can return NULL for several reasons, you deference its return value unconditionally. This is unwise.

Mike
  • 4,041
  • 6
  • 20
  • 37
Rich
  • 640
  • 5
  • 12