History

bpf: Convert bpf_preload.ko to use light skeleton.

The main change is a move of the single line #include "iterators.lskel.h" from iterators/iterators.c to bpf_preload_kern.c. Which means that generated light skeleton can be used from user space or user mode driver like iterators.c or from the kernel module or the kernel itself. The direct use of light skeleton from the kernel module simplifies the code, since UMD is no longer necessary. The libbpf.a required user space and UMD. The CO-RE in the kernel and generated "loader bpf program" used by the light skeleton are capable to perform complex loading operations traditionally provided by libbpf. In addition UMD approach was launching UMD process every time bpffs has to be mounted. With light skeleton in the kernel the bpf_preload kernel module loads bpf iterators once and pins them multiple times into different bpffs mounts.

Alexei Starovoitov committed 4 years ago

Commit cb80ddc1 parent d7beb3d9 files · +70 −247Browse files

Showing the changes to kernel/bpf/inode.c (1 of 9 files). Show all

Unified · Split

kernel/bpf/inode.c+10−29
@@ -710,11 +710,10 @@ static DEFINE_MUTEX(bpf_preload_lock); · 709 unmodified lines
710710 static int populate_bpffs(struct dentry *parent)
711711 {
712712 struct bpf_preload_info objs[BPF_PRELOAD_LINKS] = {};
713− struct bpf_link *links[BPF_PRELOAD_LINKS] = {};
714713 int err = 0, i;
715714
716715 /* grab the mutex to make sure the kernel interactions with bpf_preload
717− * UMD are serialized
716+ * are serialized
718717 */
719718 mutex_lock(&bpf_preload_lock);
720719
@@ -722,40 +721,22 @@ static int populate_bpffs(struct dentry *parent) · 1 unmodified line
722721 if (!bpf_preload_mod_get())
723722 goto out;
724723
725− if (!bpf_preload_ops->info.tgid) {
726− /* preload() will start UMD that will load BPF iterator programs */
727− err = bpf_preload_ops->preload(objs);
728− if (err)
724+ err = bpf_preload_ops->preload(objs);
725+ if (err)
726+ goto out_put;
727+ for (i = 0; i < BPF_PRELOAD_LINKS; i++) {
728+ bpf_link_inc(objs[i].link);
729+ err = bpf_iter_link_pin_kernel(parent,
730+ objs[i].link_name, objs[i].link);
731+ if (err) {
732+ bpf_link_put(objs[i].link);
729733 goto out_put;
730− for (i = 0; i < BPF_PRELOAD_LINKS; i++) {
731− links[i] = bpf_link_by_id(objs[i].link_id);
732− if (IS_ERR(links[i])) {
733− err = PTR_ERR(links[i]);
734− goto out_put;
735− }
736734 }
737− for (i = 0; i < BPF_PRELOAD_LINKS; i++) {
738− err = bpf_iter_link_pin_kernel(parent,
739− objs[i].link_name, links[i]);
740− if (err)
741− goto out_put;
742− /* do not unlink successfully pinned links even
743− * if later link fails to pin
744− */
745− links[i] = NULL;
746− }
747− /* finish() will tell UMD process to exit */
748− err = bpf_preload_ops->finish();
749− if (err)
750− goto out_put;
751735 }
752736 out_put:
753737 bpf_preload_mod_put();
754738 out:
755739 mutex_unlock(&bpf_preload_lock);
756− for (i = 0; i < BPF_PRELOAD_LINKS && err; i++)
757− if (!IS_ERR_OR_NULL(links[i]))
758− bpf_link_put(links[i]);
759740 return err;
760741 }
761742