Bu, dequeue_huge_page_vma() ve alloc_buddy_huge_page() işlevini kullanarak büyük bir sayfa ayırmak için benim modülümdür. Vma'yı bağımsız yapmak için __v_vm_area_node() 'den vm alanını alıyorum ve sanal adresini aldım. Bir 2MB sayfasını ayırmak istediğiniz, ancak, çekirdek diyor ki:Modem neden çekirdek çağrı isteği ile ilgilenemiyor?
[ 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
Kodum:
/*
* 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");
Her ifadeden sonra bir printk ifadesi ekleyin ve nereye düştüğünü görün. Ayrıca, hata ayıklayıcı sembollerini hata ayıklayıcısına yüklemeyi deneyebilir ve nerede kilitlendiğini kontrol edebilirsiniz. Ve çarpma raporundan daha fazla bilgi yapıştırın. Eklediğinden daha fazlası olmalı. – hebbo
Bölge nesnesinin dökümünü sağlayabilir misiniz? – t0k3n1z3r