1
预备知识:
RIP(指令指针)RIP寻址代码段存储区内的下一条指令
RSP(堆栈指针)RSP寻址一个称为堆栈的存储区。通过这个指针存取堆栈存储器数据,具体操作将在本书后面讲解访问堆栈存储器数据的指令时再进行说明。这个寄存器作为16位寄存器被引用时,为SP;如果作为32位寄存器,则是ESP
发生panic后,某些情况下会提示 “unable to handle kernel NULL pointer ... RIP”
1)
RIP: 0010:[<0000000000000000>] [<0000000000000000>]
则说明 ops-> 指向的函数指针为空 , 需要看你的ops中是否定义了相应的函数
2)
CR2: 0000000000000000
说明 你的 数据或者 函数 指针为空。(因为 数据或者函数指针最终 是通过 CR2访问mem的)
2
曾经为了跑打桩测试,在vmalloc 或者 kmalloc前面加上了 150字节左右的统计信息(哪个函数,哪行)。
kmalloc没有问题。但是在用vmlloc时总是有问题。
查看内核代码发现:
vmalloc 分配的都是整页的内存, 即使vmalloc(20),它实际也会给你分配1个page
这就可以解释为什么 有 dm-io_vm_sync接口, 而没有 dm_io_km_sync接口了 。因为 你往bio上加页,只能加page的整数倍,不可能加 100字节。
如果把统计信息加到vmalloc分配内存的头部,再把偏移后的数据交给 dm-io-sync传,就改变了vmalloc的语义,就会最终在drivers/md/dm-io.c文件的endio函数返回时,bi_size 不为0 ,最终会导致D+
解决方法:
把统计信息 加到 vmalloc分配的内存的末尾, 因为vfree时,不知道分配的内存的长度。 所以可以 把 “分配的内存的地址, 长度”放到一个结构体中,再把这个结构体 以“分配的内存的地址” 为key加到radix_tree,或者红黑树 时,以便将来查找。
virt_to_page 与 vmalloc
virt_to_page 它的参数必须是要在896M一下的内存, 而且必须是一段连续的内存, 这样通过vmalloc分配的地址不能作为它的参数, 因为vmalloc有可能分配高端内存,而且vmalloc分配的内存也不一定连续。
出现的问题: vmalloc分配的东西 作为wait_on_bit的参数,而最终wait_on_bit会调用virt_to_page函数