目标: 对于指定进程(通过其 pid),确定分配的虚拟地址空间的大小(所有 vmas 的总和)。
问题:从内核 6.1 开始,vm_area_struct 中不存在 vm_next 指针。所以给定的代码给出了编译器错误。 那么如何遍历分配给一个粒子进程的所有 vm_area_struct 并实现上述目标呢?
我的代码:
static int __init dummy_init(void)
{
printk("-----------------------------------------------------\n"); /*for aesthetics*/
struct task_struct *task;
struct mm_struct *mm;
struct vm_area_struct *vma;
unsigned long virt_size = 0;
unsigned long phys_size = 0;
if (target_pid < 0)
{
printk(KERN_ERR "Invalid input parameters.\n");
return -EINVAL;
}
rcu_read_lock();
task = pid_task(find_get_pid(target_pid), PIDTYPE_PID);
if (!task)
{
printk(KERN_ERR "Process with PID %d not found.\n", target_pid);
rcu_read_unlock();
return -ESRCH;
}
mm = get_task_mm(task);
if (!mm) {
printk(KERN_ERR "Failed to get memory descriptor for PID %d.\n", target_pid);
rcu_read_unlock();
return -EFAULT;
}
down_read(&mm->mmap_lock);
// Iterate through the VMAs and calculate sizes
for (vma = mm->mmap_base; vma; vma = vma->vm_next) {
virt_size += vma->vm_end - vma->vm_start;
}
up_read(&mm->mmap_lock);
rcu_read_unlock();
printk(KERN_INFO "PID: %d, Allocated Virtual Address Space: %lu KB\n", target_pid, virt_size >> 10);
printk("-----------------------------------------------------\n"); /*for aesthetics*/
return 0;
}
显然,
vm_next
中由vm_prev
和vm_area_struct
形成的链表在6.1中被删除了,因为最近引入的枫树中已经存在相同的功能。 这是提交。
现在走VMA似乎有两种主要方式:
struct ma_state
)通过mas_find()
、mas_for_each()
等手动迭代枫树。struct vma_iterator
和相关的辅助函数/宏:for_each_vma()
、vma_next()
、vma_prev()
。这是一个例子:
struct vm_area_struct *vma;
VMA_ITERATOR(iter, mm, 0);
for_each_vma(iter, vma) {
virt_size += vma->vm_end - vma->vm_start;
}