• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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