개요
eBPF에서 pointer에 Rust의 ownership모델을 더하여서, 포인터의 활용성을 높이는 kptr이라는 새로운 타입을 말한다.
Referenced pointer
eBPF는 기존의 Helper function을 넘어서 더욱 많은 커널에 존재하는 기능을 사용하기 위해서 kfunc라는 새로운 unstable한 helper function API를 커널에 만들 수 있는 기법을 도입하였다. 이 kfunc는 reference pointer라는 새로운 pointer를 만들었는데, 이는 acquire와 release라는 조합으로 프로그래밍되어서, acquire과 release사이에 이 포인터가 dereference되지 않다는 보장만 해주면, verifier가 owner ship을 추적하면서 safety를 보장해주는 semantic이 발생하였다.
Reference pointer and usability
Ref.P (Reference pointer)를 사용하게 되면서, bpf_probe_read_user와 같은 probe함수를 사용하지 않아도 되었다. 또한 Ref.P가 helper functions이나 kfunc와 같은 다른 함수의 Argument로 사용될때의 Safety를 쉽게 파악할 수 있게 되었다. 그러나 Ref.P를 MAP에 넣을 수 없었기 때문에 kfunc로 Ref.P를 얻고 release하는 작업을 매 Ref.P의 사용마다 하여야 하기 때문에 불편함과 성능상의 불이익이 있었다.
kptr
kptr은 이 문제를 해결하기 위해서 등장하였다. kptr은 eBPF MAP에 저장될 수 있는 포인터 타입으로써, kfunc나 helper functions을 통해서 획득 가능하다. kptr은 unreference혹은 reference타입을 가지는데, unreference는 기존의 eBPF pointer와 비슷하게 validate를 체크하지 않기 때문에 probe함수로만 접근하여야 한다. kptr의 reference type은 Rust의 ownership모델이나 c++의 unique ptr처럼 단 하나의 reference 소유자를 가지게 된다. kptr을 다른 context로 전송하기 위해서, bpf_kptr_xchg라는 helper function을 통해서 kptr의 ownership을 swap할 수 있게 하였다. 만약 프로그램이 kptr을 map에 저장하고 release를 명시적으로 호출 하지 않으면, 자동으로 연관된 release를 호출함으로써, kptr를 release하도록 한다.