1<picture> 2 <source media="(prefers-color-scheme: dark)" srcset="assets/libbpf-logo-sideways-darkbg.png" width="40%"> 3 <img src="assets/libbpf-logo-sideways.png" width="40%"> 4</picture> 5 6Libbpf sync 7=========== 8 9Libbpf *authoritative source code* is developed as part of [bpf-next Linux source 10tree](https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next) under 11`tools/lib/bpf` subdirectory and is periodically synced to Github. 12 13Most of the mundane mechanical things like bpf and bpf-next tree merge, Git 14history transformation, cherry-picking relevant commits, re-generating 15auto-generated headers, etc. are taken care by 16[sync-kernel.sh script](https://github.com/libbpf/libbpf/blob/master/scripts/sync-kernel.sh). 17But occasionally human needs to do few extra things to make everything work 18nicely. 19 20This document goes over the process of syncing libbpf sources from Linux repo 21to this Github repository. Feel free to contribute fixes and additions if you 22run into new problems not outlined here. 23 24Setup expectations 25------------------ 26 27Sync script has particular expectation of upstream Linux repo setup. It 28expects that current HEAD of that repo points to bpf-next's master branch and 29that there is a separate local branch pointing to bpf tree's master branch. 30This is important, as the script will automatically merge their histories for 31the purpose of libbpf sync. 32 33Below, we assume that Linux repo is located at `~/linux`, it's current head is 34at latest `bpf-next/master`, and libbpf's Github repo is located at 35`~/libbpf`, checked out to latest commit on `master` branch. It doesn't matter 36from where to run `sync-kernel.sh` script, but we'll be running it from inside 37`~/libbpf`. 38 39``` 40$ cd ~/linux && git remote -v | grep -E '^(bpf|bpf-next)' 41bpf https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git (fetch) 42bpf ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git 43(push) 44bpf-next 45https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git (fetch) 46bpf-next 47ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git (push) 48$ git branch -vv | grep -E '^? (master|bpf-master)' 49* bpf-master 2d311f480b52 [bpf/master] riscv, bpf: Fix patch_text implicit declaration 50 master c8ee37bde402 [bpf-next/master] libbpf: Fix bpf_xdp_query() in old kernels 51$ git checkout bpf-master && git pull && git checkout master && git pull 52... 53$ git log --oneline -n1 54c8ee37bde402 (HEAD -> master, bpf-next/master) libbpf: Fix bpf_xdp_query() in old kernels 55$ cd ~/libbpf && git checkout master && git pull 56Your branch is up to date with 'libbpf/master'. 57Already up to date. 58``` 59 60Running setup script 61-------------------- 62 63First step is to always run `sync-kernel.sh` script. It expects three arguments: 64 65``` 66$ scripts/sync-kernel.sh <libbpf-repo> <kernel-repo> <bpf-branch> 67``` 68 69Note, that we'll store script's entire output in `/tmp/libbpf-sync.txt` and 70put it into PR summary later on. **Please store scripts output and include it 71in PR summary for others to check for anything unexpected and suspicious.** 72 73``` 74$ scripts/sync-kernel.sh ~/libbpf ~/linux bpf-master | tee /tmp/libbpf-sync.txt 75Dumping existing libbpf commit signatures... 76WORKDIR: /home/andriin/libbpf 77LINUX REPO: /home/andriin/linux 78LIBBPF REPO: /home/andriin/libbpf 79... 80``` 81 82Most of the time this will go very uneventful. One expected case when sync 83script might require user intervention is if `bpf` tree has some libbpf fixes, 84which is nowadays not a very frequent occurence. But if that happens, script 85will show you a diff between expected state as of latest bpf-next and synced 86Github repo state. And will ask if these changes look good. Please use your 87best judgement to verify that differences are indeed from expected `bpf` tree 88fixes. E.g., it might look like below: 89 90``` 91Comparing list of files... 92Comparing file contents... 93--- /home/andriin/linux/include/uapi/linux/netdev.h 2023-02-27 16:54:42.270583372 -0800 94+++ /home/andriin/libbpf/include/uapi/linux/netdev.h 2023-02-27 16:54:34.615530796 -0800 95@@ -19,7 +19,7 @@ 96 * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP 97 * in zero copy mode. 98 * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw 99- * oflloading. 100+ * offloading. 101 * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear 102 * XDP buffer support in the driver napi callback. 103 * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements 104/home/andriin/linux/include/uapi/linux/netdev.h and /home/andriin/libbpf/include/uapi/linux/netdev.h are different! 105Unfortunately, there are some inconsistencies, please double check. 106Does everything look good? [y/N]: 107``` 108 109If it looks sensible and expected, type `y` and script will proceed. 110 111If sync is successful, your `~/linux` repo will be left in original state on 112the original HEAD commit. `~/libbpf` repo will now be on a new branch, named 113`libbpf-sync-<timestamp>` (e.g., `libbpf-sync-2023-02-28T00-53-40.072Z`). 114 115Push this branch into your fork of `libbpf/libbpf` Github repo and create a PR: 116 117``` 118$ git push --set-upstream origin libbpf-sync-2023-02-28T00-53-40.072Z 119Enumerating objects: 130, done. 120Counting objects: 100% (115/115), done. 121Delta compression using up to 80 threads 122Compressing objects: 100% (28/28), done. 123Writing objects: 100% (32/32), 5.57 KiB | 1.86 MiB/s, done. 124Total 32 (delta 21), reused 0 (delta 0), pack-reused 0 125remote: Resolving deltas: 100% (21/21), completed with 9 local objects. 126remote: 127remote: Create a pull request for 'libbpf-sync-2023-02-28T00-53-40.072Z' on GitHub by visiting: 128remote: https://github.com/anakryiko/libbpf/pull/new/libbpf-sync-2023-02-28T00-53-40.072Z 129remote: 130To github.com:anakryiko/libbpf.git 131 * [new branch] libbpf-sync-2023-02-28T00-53-40.072Z -> libbpf-sync-2023-02-28T00-53-40.072Z 132Branch 'libbpf-sync-2023-02-28T00-53-40.072Z' set up to track remote branch 'libbpf-sync-2023-02-28T00-53-40.072Z' from 'origin'. 133``` 134 135**Please, adjust PR name to have a properly looking timestamp. Libbpf 136maintainers will be very thankful for that!** 137 138By default Github will turn above branch name into PR with subject "Libbpf sync 1392023 02 28 t00 53 40.072 z". Please fix this into a proper timestamp, e.g.: 140"Libbpf sync 2023-02-28T00:53:40.072Z". Thank you! 141 142**Please don't forget to paste contents of /tmp/libbpf-sync.txt into PR 143summary!** 144 145Once PR is created, libbpf CI will run a bunch of tests to check that 146everything is good. In simple cases that would be all you'd need to do. In more 147complicated cases some extra adjustments might be necessary. 148 149**Please, keep naming and style consistent.** Prefix CI-related fixes with `ci: ` 150prefix. If you had to modify sync script, prefix it with `sync: `. Also make 151sure that each such commit has `Signed-off-by: Your Full Name <your@email.com>`, 152just like you'd do that for Linux upstream patch. Libbpf closely follows kernel 153conventions and styling, so please help maintaining that. 154 155Including new sources 156--------------------- 157 158If entirely new source files (typically `*.c`) were added to the library in the 159kernel repository, it may be necessary to add these to the build system 160manually (you may notice linker errors otherwise), because the script cannot 161handle such changes automatically. To that end, edit `src/Makefile` as 162necessary. Commit 163[c2495832ced4](https://github.com/libbpf/libbpf/commit/c2495832ced4239bcd376b9954db38a6addd89ca) 164is an example of how to go about doing that. 165 166Similarly, if new public API header files were added, the `Makefile` will need 167to be adjusted as well. 168 169Updating allow/deny lists 170------------------------- 171 172Libbpf CI intentionally runs a subset of latest BPF selftests on old kernel 173(4.9 and 5.5, currently). It happens from time to time that some tests that 174previously were successfully running on old kernels now don't, typically due to 175reliance on some freshly added kernel feature. It might look something like this in [CI logs](https://github.com/libbpf/libbpf/actions/runs/4206303272/jobs/7299609578#step:4:2733): 176 177``` 178 All error logs: 179 serial_test_xdp_info:FAIL:get_xdp_none errno=2 180 #283 xdp_info:FAIL 181 Summary: 49/166 PASSED, 5 SKIPPED, 1 FAILED 182``` 183 184In such case we can either work with upstream to fix test to be compatible with 185old kernels, or we'll have to add a test into a denylist (or remove it from 186allowlist, like was [done](https://github.com/libbpf/libbpf/commit/ea284299025bf85b85b4923191de6463cd43ccd6) 187for the case above). 188 189``` 190$ find . -name '*LIST*' 191./ci/vmtest/configs/ALLOWLIST-4.9.0 192./ci/vmtest/configs/DENYLIST-5.5.0 193./ci/vmtest/configs/DENYLIST-latest.s390x 194./ci/vmtest/configs/DENYLIST-latest 195./ci/vmtest/configs/ALLOWLIST-5.5.0 196``` 197 198Please determine which tests need to be added/removed from which list. And then 199add that as a separate commit. **Please keep using the same branch name, so 200that the same PR can be updated.** There is no need to open new PRs for each 201such fix. 202 203Regenerating vmlinux.h header 204----------------------------- 205 206To compile latest BPF selftests against old kernels, we check in pre-generated 207[vmlinux.h](https://github.com/libbpf/libbpf/blob/master/.github/actions/build-selftests/vmlinux.h) 208header file, located at `.github/actions/build-selftests/vmlinux.h`, which 209contains type definitions from latest upstream kernel. When after libbpf sync 210upstream BPF selftests require new kernel types, we'd need to regenerate 211`vmlinux.h` and check it in as well. 212 213This will looks something like this in [CI logs](https://github.com/libbpf/libbpf/actions/runs/4198939244/jobs/7283214243#step:4:1903): 214 215``` 216 In file included from progs/test_spin_lock_fail.c:5: 217 /home/runner/work/libbpf/libbpf/.kernel/tools/testing/selftests/bpf/bpf_experimental.h:73:53: error: declaration of 'struct bpf_rb_root' will not be visible outside of this function [-Werror,-Wvisibility] 218 extern struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root, 219 ^ 220 /home/runner/work/libbpf/libbpf/.kernel/tools/testing/selftests/bpf/bpf_experimental.h:81:35: error: declaration of 'struct bpf_rb_root' will not be visible outside of this function [-Werror,-Wvisibility] 221 extern void bpf_rbtree_add(struct bpf_rb_root *root, struct bpf_rb_node *node, 222 ^ 223 /home/runner/work/libbpf/libbpf/.kernel/tools/testing/selftests/bpf/bpf_experimental.h:90:52: error: declaration of 'struct bpf_rb_root' will not be visible outside of this function [-Werror,-Wvisibility] 224 extern struct bpf_rb_node *bpf_rbtree_first(struct bpf_rb_root *root) __ksym; 225 ^ 226 3 errors generated. 227 make: *** [Makefile:572: /home/runner/work/libbpf/libbpf/.kernel/tools/testing/selftests/bpf/test_spin_lock_fail.bpf.o] Error 1 228 make: *** Waiting for unfinished jobs.... 229 Error: Process completed with exit code 2. 230``` 231 232You'll need to build latest upstream kernel from `bpf-next` tree, using BPF 233selftest configs. Concat arch-agnostic and arch-specific configs, build kernel, 234then use bpftool to dump `vmlinux.h`: 235 236``` 237$ cd ~/linux 238$ cat tools/testing/selftests/bpf/config \ 239 tools/testing/selftests/bpf/config.x86_64 > .config 240$ make -j$(nproc) olddefconfig all 241... 242$ bpftool btf dump file ~/linux/vmlinux format c > ~/libbpf/.github/actions/build-selftests/vmlinux.h 243$ cd ~/libbpf && git add . && git commit -s 244``` 245 246Check in generated `vmlinux.h`, don't forget to use `ci: ` commit prefix, add 247it on top of sync commits. Push to Github and let libbpf CI do the checking for 248you. See [this commit](https://github.com/libbpf/libbpf/commit/34212c94a64df8eeb1dd5d064630a65e1dfd4c20) 249for reference. 250 251Troubleshooting 252--------------- 253 254If something goes wrong and sync script exits early or is terminated early by 255user, you might end up with `~/linux` repo on temporary sync-related branch. 256Don't worry, though, sync script never destroys repo state, it follows 257"copy-on-write" philosophy and creates new branches where necessary. So it's 258very easy to restore previous state. So if anything goes wrong, it's easy to 259start fresh: 260 261``` 262$ git branch | grep -E 'libbpf-.*Z' 263 libbpf-baseline-2023-02-28T00-43-35.146Z 264 libbpf-bpf-baseline-2023-02-28T00-43-35.146Z 265 libbpf-bpf-tip-2023-02-28T00-43-35.146Z 266 libbpf-squash-base-2023-02-28T00-43-35.146Z 267* libbpf-squash-tip-2023-02-28T00-43-35.146Z 268$ git cherry-pick --abort 269$ git checkout master && git branch | grep -E 'libbpf-.*Z' | xargs git br -D 270Switched to branch 'master' 271Your branch is up to date with 'bpf-next/master'. 272Deleted branch libbpf-baseline-2023-02-28T00-43-35.146Z (was 951bce29c898). 273Deleted branch libbpf-bpf-baseline-2023-02-28T00-43-35.146Z (was 3a70e0d4c9d7). 274Deleted branch libbpf-bpf-tip-2023-02-28T00-43-35.146Z (was 2d311f480b52). 275Deleted branch libbpf-squash-base-2023-02-28T00-43-35.146Z (was 957f109ef883). 276Deleted branch libbpf-squash-tip-2023-02-28T00-43-35.146Z (was be66130d2339). 277Deleted branch libbpf-tip-2023-02-28T00-43-35.146Z (was 2d311f480b52). 278``` 279 280You might need to do the same for your `~/libbpf` repo sometimes, depending at 281which stage sync script was terminated. 282