Thread (36 messages) 36 messages, 6 authors, 2021-01-26

Re: [PATCH v2 bpf-next 1/4] bpf: introduce task_vma bpf_iter

From: Alexei Starovoitov <hidden>
Date: 2021-01-05 19:47:31
Also in: netdev

On Tue, Jan 05, 2021 at 07:38:08PM +0000, Song Liu wrote:
quoted
On Jan 5, 2021, at 9:27 AM, Alexei Starovoitov [off-list ref] wrote:

On Tue, Jan 5, 2021 at 9:11 AM Song Liu [off-list ref] wrote:
quoted

quoted
On Jan 5, 2021, at 8:27 AM, Alexei Starovoitov [off-list ref] wrote:

On Mon, Jan 4, 2021 at 9:47 PM Song Liu [off-list ref] wrote:
quoted

quoted
On Jan 4, 2021, at 5:46 PM, Alexei Starovoitov [off-list ref] wrote:

On Fri, Dec 18, 2020 at 05:23:25PM +0000, Song Liu wrote:
quoted
quoted
On Dec 18, 2020, at 8:38 AM, Yonghong Song [off-list ref] wrote:



On 12/17/20 9:23 PM, Alexei Starovoitov wrote:
quoted
On Thu, Dec 17, 2020 at 8:33 PM Song Liu [off-list ref] wrote:
quoted
quoted
ahh. I missed that. Makes sense.
vm_file needs to be accurate, but vm_area_struct should be accessed as ptr_to_btf_id.
Passing pointer of vm_area_struct into BPF will be tricky. For example, shall we
allow the user to access vma->vm_file? IIUC, with ptr_to_btf_id the verifier will
allow access of vma->vm_file as a valid pointer to struct file. However, since the
vma might be freed, vma->vm_file could point to random data.
I don't think so. The proposed patch will do get_file() on it.
There is actually no need to assign it into a different variable.
Accessing it via vma->vm_file is safe and cleaner.
I did not check the code but do you have scenarios where vma is freed but old vma->vm_file is not freed due to reference counting, but
freed vma area is reused so vma->vm_file could be garbage?
AFAIK, once we unlock mmap_sem, the vma could be freed and reused. I guess ptr_to_btf_id
or probe_read would not help with this?
Theoretically we can hack the verifier to treat some ptr_to_btf_id as "less
valid" than the other ptr_to_btf_id, but the user experience will not be great.
Reading such bpf prog will not be obvious. I think it's better to run bpf prog
in mmap_lock then and let it access vma->vm_file. After prog finishes the iter
bit can do if (mmap_lock_is_contended()) before iterating. That will deliver
better performance too. Instead of task_vma_seq_get_next() doing
mmap_lock/unlock at every vma. No need for get_file() either. And no
__vm_area_struct exposure.
I think there might be concern calling BPF program with mmap_lock, especially that
the program is sleepable (for bpf_d_path). It shouldn't be a problem for common
cases, but I am not 100% sure for corner cases (many instructions in BPF + sleep).
Current version is designed to be very safe for the workload, which might be too
conservative.
I know and I agree with all that, but how do you propose to fix the
vm_file concern
without holding the lock while prog is running? I couldn't come up with a way.
I guess the gap here is that I don't see why __vm_area_struct exposure is an issue.
It is similar to __sk_buff, and simpler (though we had more reasons to introduce
__sk_buff back when there wasn't BTF).

If we can accept __vm_area_struct, current version should work, as it doesn't have
problem with vm_file
True. The problem with __vm_area_struct is that it is a hard coded
uapi with little to none
extensibility. In this form vma iterator is not really useful beyond
the example in selftest.
With __vm_area_struct, we can still probe_read the page table, so we can 
cover more use cases than the selftest. But I agree that it is not as
extensible as feeding real vm_area_struct with BTF to the BPF program. 
Another confusing thing with __vm_area_struct is vm_flags field.
It's copied directly. As __vm_area_struct->flags this field is uapi field,
but its contents are kernel internal. We avoided such corner cases in the past.
When flags field is copied into uapi the kernel internal flags are encoded
and exposed as separate uapi flags. That was the case with
BPF_TCP_* flags. If we have to do this with vm_flags (VM_EXEC, etc) that
might kill the patchset due to abi concerns.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help