Skip to content

adopt (breaking) changes from linux kernel v6.15, v6.19 and v7.0 - #110

Closed
tiararodney wants to merge 24 commits into
PlatformLab:mainfrom
tiararodney:linux-v619
Closed

tiararodney wants to merge 24 commits into
PlatformLab:mainfrom
tiararodney:linux-v619

Conversation

@tiararodney

@tiararodney tiararodney commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

As suggested in #107:

$> git log --pretty=tformat:'%s' 22c5317f..HEAD
Build test harness against !defined(CONFIG_DEBUG_PREEMPT)
Build test harness against linux 7.0 kernel asm/checksum_64.h header
Build test harness against linux 6.19 kernel linux/mutex.h header
Build test harness against linux 6.19 kernel net/ipv6.h header
Build test harness against linux 6.19 kernel net/ip.h header
Build test harness against linux 6.19 kernel net/inet_common.h header
Build test harness against linux 6.18 kernel linux/slab.h header
Build test harness against linux 6.18 kernel linux/hrtimer.h header
Build test harness against linux 6.18 kernel net/icmp.h header
Build test harness against linux 6.19 kernel linux/xxhash.h header
Build test harness against linux 6.18 kernel linux/rhashtable.h header
Build test harness against linux 6.19 kernel linux/rbtree.h header
rbtree: inline rb_last()
rbtree: inline rb_first()
Build test harness against percpu cache hot data
Build test harness against kbuild dialect and extensions
Build against linux 7.0 kernel net/pkt_sched.h header
Build against linux 6.19 kernel net/socket.h header
Build against linux 7.0 kernel compiler_types.h header

TODO:

  • some remaining errors in the test harness regarding __seg_gs, and I'm thinking about ditching commit d40d78d altogether and just remove the x86 specific gates (works, but feels hacked), so that __seg_gs isn't auto-selected at all. But I don't yet understand how this would affect other architectures... Note: removing the gates entirely made the renaming of current_task redundant. Only seems applicable for x86.
  • unit tests haven't adopted the changes from 917d6c3 yet. Note: applied onto same commit.
  • changes to linux/rbtree.h in v7.0 break some test cases cherry-picked changes from lib/rbtree.c and applied kernel version guard
  • vendored-libs like xxhash.c break... I'm not sure if patching is the strategy.
  • build and test against vanilla kernel (I've used Ubuntu so far) Note: I'm using a tiny test bench, so I can continuously test against vanilla kernels
  • linker issues for test harness (it compiles already though)

You can use the following script to reproduce the build, and tests against the vanilla kernel 7.0.14 (unit + smoke test, loading the module in a QEMU guest), which I patched against.

sh -ex << 'EOF'
WORKDIR="$(mktemp -d)"
HOMA_GIT_BRANCH=linux-v619 # branch only exists on my fork, which is accounted for further down
KERNEL_VERSION=7.0.14

finally () {
    cat $WORKDIR/test-report/unit/$KERNEL_VERSION/$HOMA_GIT_BRANCH.log 2>/dev/null \
    || cat /dev/null
    cat $WORKDIR/test-report/smoke/$KERNEL_VERSION/$HOMA_GIT_BRANCH.log 2>/dev/null \
    || cat /dev/null
    rm -r "$WORKDIR"
} 

trap finally EXIT

git clone https://github.com/tiararodney/HomaModuleTestBench.git "$WORKDIR"
cd "$WORKDIR"

git submodule update --init HomaModule.git/
sh ./configure

# need to adjust the submodule to point to my fork...
git -C HomaModule.git/ remote set-url origin https://github.com/tiararodney/HomaModule.git
git -C HomaModule.git/ fetch origin $HOMA_GIT_BRANCH
git -C HomaModule.git/ checkout -B $HOMA_GIT_BRANCH origin/$HOMA_GIT_BRANCH


make -j2 test-report/unit/$KERNEL_VERSION/$HOMA_GIT_BRANCH.log \
         test-report/smoke/$KERNEL_VERSION/$HOMA_GIT_BRANCH.log
EOF

kernel ver. >=7.0 changed the signature of __cond_acquires [1] and introduced a
return value token, so a Clang checker is now able to differentiate between held
and unheld locks. Context analysis wasn't documented, prior to v7.0.

on `homa_rpc.h::homa_rpc_try_lock()`, the correct choice would probably be to
use a `nonzero` token, however since these are annotations that don't expand to
anything outside of Clang's static analysis, I think it's safe to just use
`nonnull` as a truthy value? The macros' docstring make that assumption as well
[2]...

What might be a bit problematic regarding readability is that the inline
`__COND_ACQUIRES` in `homa_rpc.h` is dependent on the include order of the
headers throughout. Not a real issue though, since `homa_impl.h is always
included before `homa_rpc.h` throughout and it was like that with the raw
`__cond_acquires` before anyway.

[1] https://www.kernel.org/doc/html/v7.0/dev-tools/context-analysis.html#c.__cond_acquires
[2] https://github.com/torvalds/linux/blob/v7.0/include/linux/compiler-context-analysis.h#L288-L291
@tiararodney

This comment was marked as outdated.

this is a drive-by commit and should probably be handled via a separate PR...

explicitly pinning to C11 and ms-extensions, as to mirror what kbuild does,
since newer versions of GCC use C23 by default.
@tiararodney
tiararodney force-pushed the linux-v619 branch 2 times, most recently from 46292f2 to d40d78d Compare October 1, 2026 08:33
@tiararodney tiararodney changed the title adopt (breaking) changes from linux kernel v6.19 and v7.0 adopt (breaking) changes from linux kernel v6.15, v6.19 and v7.0 Oct 1, 2026
sockaddr is deprecated since v6.19 [1] and replaced by sockaddr_unsized, which
is now unbounded against addr_len, removing the prior 14-bytes cap. It's
interchangeable throughout Homa though, since there is no dependency on
`sizeof(struct sockaddr)`..

[1] https://github.com/torvalds/linux/blob/v6.19/include/linux/socket.h#L35
qdisk_from_priv was removed in v7.0 [1], however it's just a tiny helper [2]
anyway, so we can simply redefine it.

[1] torvalds/linux@1145739
[2] https://github.com/torvalds/linux/blob/v6.18/include/net/pkt_sched.h#L28-L31
@tiararodney
tiararodney force-pushed the linux-v619 branch 3 times, most recently from c7680f0 to c3f72da Compare October 2, 2026 05:23
starting with kernel v6.15, the task_struct was moved into pcpu_hot [1][2],
hence the conflicting named address spaces (generic vs __seg_gs), when
DECLARE_PER_CPU_CACHE_HOT [3] is expanded.

The unit tests model per-CPU variables as plain arrays (see the DECLARE_PER_CPU
/ per_cpu / this_cpu_ptr overrides in `mock.h`), so the test build must not see
x86's segment-based ("named address space") per-CPU addressing. On kernels built
with CONFIG_CC_HAS_NAMED_AS, per-CPU symbols become __seg_gs-qualified [4]. That
qualifier is applicable through __typeof__ in the kselftest EXPECT_* macros onto
auto variables ("__seg_gs specified for auto variable") and conflicts with the
mock's plain declarations.

[1] https://lore.kernel.org/all/20250303165246.2175811-1-brgerst@gmail.com/
[2] torvalds/linux@a1e4cc0
[3] https://github.com/torvalds/linux/commits/v6.15/arch/x86/include/asm/current.h
[4] https://github.com/torvalds/linux/blob/v6.15/arch/x86/include/asm/current.h#L16
edumazet and others added 3 commits October 2, 2026 08:08
Inline these two small helpers, heavily used in TCP and FQ packet
scheduler, and in many other places. This reduces kernel text size, and
brings a 1.5% improvement on a network TCP stress test.

This is a very small function, inlining it saves cpu cycles by reducing
register pressure and removing call/ret overhead. It also reduces vmlinux
text size by 744 bytes on a typical x86_64 build.

(cherry picked from commit c2d2dad24503d7e2eb7cba354fcc73f95fa78d7a of
torvalds/linux.git)
[ vendored test/rbtree.c: drop only the out-of-line rb_first(). Its
  EXPORT_SYMBOL() was already stripped on import, and the inline now comes
  from the kernel's <linux/rbtree.h>.. ]
This is a very small function, inlining it saves cpu cycles in TCP by
reducing register pressure and removing call/ret overhead. It also reduces
vmlinux text size by 122 bytes on a typical x86_64 build.

(cherry picked from commit 94984bfed58ca129f7e259ce09973ed0b3f540a8 of
torvalds/linux.git)
[ vendored test/rbtree.c: drop only the out-of-line rb_last(). Its
  EXPORT_SYMBOL() was already stripped on import, and the inline now comes
  from the kernel's <linux/rbtree.h>.]
linux 6.19 inlined rb_first() and rb_last() into <linux/rbtree.h> [1][2],
removing the out-of-line definitions mirrored by the previous two commits.
on kernels < 6.19 the header still only declares them extern, so the
vendored test/rbtree.c must keep the out-of-line copies.

restoring them under a LINUX_VERSION_CODE guard so the harness builds on both...

[1] torvalds/linux@c2d2dad
[2] torvalds/linux@94984bf
linux 6.18 added an alignment parameter to the k[v]malloc family [1]: the
rhashtable bucket-table allocation moved from kvmalloc_node_noprof(size,
flags, node) to kvmalloc_node_align_noprof(size, align, flags, node), and
on >= 6.18 the old kvmalloc_node_noprof is a 4-arg macro that no longer
expands for the 3-arg call ("implicit declaration of kvmalloc_node_noprof").

The vendored test/rhashtable.c was imported from ~v6.15, so guard the
bucket-table allocation: use the align form (align = 1) on >= 6.18 and the
original 3-arg form on older kernels.

[1] torvalds/linux@2cd8231
linux 6.19 removed the streaming xxh32 API from `linux/xxhash.h`. struct
xxh32_state and xxh32_reset()/copy_state() are gone [1], only `xxh32()`, which
Homa uses via xxh32_hash() in homa_peer.c, remains. The vendored test/xxhash.c
still defines the out-of-line xxh32_copy_state() and xxh32_reset(), which
reference the now-removed struct xxh32_state.

[1] torvalds/linux@a0b8c6a
@tiararodney
tiararodney force-pushed the linux-v619 branch 2 times, most recently from f815e40 to ddfabfe Compare October 2, 2026 11:39
In linux 6.18 the last parameter of __icmp_send()' was changed from `const
struct ip_options *` to `const struct inet_skb_parm *` [1].

The mock definition conflicted with the new prototype.

[1] torvalds/linux@0d3c4a4
linux 6.18 removed the get_time member from struct hrtimer_clock_base

kernel now reads clock time via hrtimer_cb_get_time()) [1]. The mock's
`hrtimer_init()`/`hrtimer_setup()` assigned `clock_base.get_time`, and the
backing `hrtimer_get_time()` stub is unused once those assignments go away.

[1] torvalds/linux@cdea7cd
linux 6.18 added an alignment parameter to `__kvmalloc_node_noprof()` [1].

the mock's definition used the old prototype and no longer matched. The mock
ignores the alignment.

[1] torvalds/linux@2cd8231
linux 6.19 introduced struct sockaddr_unsized (linux/socket.h) and switched
inet_dgram_connect()'s address argument to it [1]

[1] torvalds/linux@449f68f
Linux 6.19 switched ip4_datagram_connect() address argument to the new
struct sockaddr_unsized (linux/socket.h).

[1] torvalds/linux@449f68f
linux 6.19 switched ip6_datagram_connect() address argument to the new
struct sockaddr_unsized (linux/socket.h) [1].

[1] torvalds/linux@449f68f
linux 6.19 turned __mutex_init() into a static inline in linux/mutex.h
(non-DEBUG, non-PREEMPT_RT config). it was an extern before...

[1] torvalds/linux@51d7a05
linux 7.0 made csum_ipv6_magic() a static inline in the x86
asm/checksum_64.h [1], it was out-of-line before so the harness supplied its
own stub. The mock's definition then conflicted with the inline.

[1] torvalds/linux@529676c
linux/preempt.h only declares preempt_count_add()/preempt_count_sub() as extern
functions under CONFIG_DEBUG_PREEMPT or CONFIG_TRACE_PREEMPT_TOGGLE, otherwise
it defines them as macros around the arch __preempt_count_add() inline. The mock
defined them unconditionally, which redefined that inline on a kernel built
without those options.
@tiararodney

Copy link
Copy Markdown
Contributor Author

Alright, after having ignored the test harness (pardon...), both the module and test harness now compile against 7.0.0-34-generic on Ubuntu with GCC15 and (hopefully) only linker issues are remaining. All the required changes have luckily been pretty mechanical so far.

I've restructured the commits, since I figured this PR is probably a bad idea scope-wise anyway (way too broad)... Instead, I focused on it serving as a reference for creating new PRs according to the kernel version compatibility breakpoints?

Up until now, 4 version breakpoints for 6.15, 6.18, 6.19, and 7.0 surfaced and some expectations towards the build environment required patching. The commits are verbosely labeled and all changes in linux are annotated with commit references. Two changes, required patching vendored sources, which I cherry-picked of the linux sources and retained the provenance.

With CONFIG_RANDOM_KMALLOC_CACHES (set on the test machine), the kmalloc
inlines in linux/slab.h hash the caller against random_kmalloc_seed to pick a
cache, so the symbol is referenced at link time. Provide it in the mock.

(Completes the linux/slab.h adaptation; may be squashed into the
__kvmalloc_node_noprof commit.)
In linux 6.19 `static inline __mutex_init()` delegates to `mutex_init_generic()`
[1][2], so guarding out the mock `__mutex_init()` for >=6.19 leavs that symbol
referenced at link time.

Providing a stand-in mock for mutex_init_generic().

[1] torvalds/linux@51d7a05
[2] https://lore.kernel.org/all/20251105142350.Tfeevs2N@linutronix.de/
linux 6.17 added system_percpu_wq (system_wq is kept as deprecated alias
though) [1].

`schedule_work()`/`queue_work()` inlines now reference system_percpu_wq, so it
is needed at link time.

[1] torvalds/linux@128ea9f
linux 6.19 routes WARN() on x86 through a static call [1]

fortify-string memcpy() checks, compiled into the -O2 lib files
(rbtree.c/rhashtable.c/xxhash.c), pull in the __SCK__WARN_trap key and
__SCT__WARN_trap trampoline.

Providing both, matching the existing static-call stubs..

[1] torvalds/linux@860238a

@johnousterhout johnousterhout left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for these patches. Most look good to me and I will start applying them, but I have a few questions.

Comment thread test/Makefile
WARNS := -Wall -Wundef -Wno-trigraphs -Wno-sign-compare -Wuninitialized \
-Wno-strict-aliasing -Wunused-but-set-variable -Werror
CFLAGS := $(WARNS) -Wstrict-prototypes -MD -no-pie -g $(CINCLUDES) $(DEFS) \
CFLAGS := -std=gnu11 -fms-extensions $(WARNS) -Wstrict-prototypes -MD -no-pie -g $(CINCLUDES) $(DEFS) \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say a bit more about why -fms-extensions is needed? I don't see this flag when I do normal kbuilds of Homa.

@tiararodney tiararodney Oct 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ms-extensions was necessary because of two anonymous structs in:

In file included from kernels/linux-7.0.14-unit/include/linux/huge_mm.h:7,
                 from kernels/linux-7.0.14-unit/include/linux/mm.h:1473,
                 from kernels/linux-7.0.14-unit/include/linux/pid_namespace.h:7,
                 from kernels/linux-7.0.14-unit/include/linux/ptrace.h:10,
                 from kernels/linux-7.0.14-unit/include/linux/audit.h:13,
                 from build/proof-3fa701c/homa_impl.h:31,
                 from HomaModule.git/test/unit_homa_incoming.c:3:
kernels/linux-7.0.14-unit/include/linux/fs.h:2427:31: error: declaration does not
declare anything [-Werror]
 2427 |         struct __filename_head;
      |                               ^
In file included from kernels/linux-7.0.14-unit/include/linux/init.h:5,
                 from kernels/linux-7.0.14-unit/include/linux/printk.h:6,
                 from kernels/linux-7.0.14-unit/include/asm-generic/bug.h:31,
                 from kernels/linux-7.0.14-unit/arch/x86/include/asm/bug.h:193,
                 from kernels/linux-7.0.14-unit/include/linux/bug.h:5,
                 from build/proof-3fa701c/homa_impl.h:10:
kernels/linux-7.0.14-unit/include/linux/build_bug.h:80:41: error: static assertion
failed: "sizeof(struct filename) % 64 == 0"
   80 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
      |                                         ^~~~~~~~~~~~~~
kernels/linux-7.0.14-unit/include/linux/build_bug.h:79:34: note: in expansion of
macro '__static_assert'
   79 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__,
#expr)
      |                                  ^~~~~~~~~~~~~~~
kernels/linux-7.0.14-unit/include/linux/fs.h:2431:1: note: in expansion of macro
'static_assert'
 2431 | static_assert(sizeof(struct filename) % 64 == 0);
      | ^~~~~~~~~~~~~
In file included from kernels/linux-7.0.14-unit/include/linux/ns_common.h:5,
                 from kernels/linux-7.0.14-unit/include/linux/pid_namespace.h:11:
kernels/linux-7.0.14-unit/include/linux/ns/ns_common_types.h:119:31: error:
declaration does not declare anything [-Werror]
  119 |                 struct ns_tree;
      |                               ^

plan9-extensions works too, and I have yet to find out why kbuild defaults to ms-extensions... I grabbed it from the kbuild .cmd.

Here's a script to reproduce the fault (at least on Ubuntu 26.04 with GCC15 against the 7.0.14 kernel sources):

sh -ex <<'EOF'
WORKDIR="$(mktemp -d)"
KERNEL_VERSION=7.0.14
COMMIT=0815fe9

finally() {
    rm -rf "$WORKDIR"
}
trap finally EXIT

git clone https://github.com/tiararodney/HomaModuleTestBench.git "$WORKDIR"
cd "$WORKDIR"
git submodule update --init HomaModule.git/

git -C HomaModule.git/ remote set-url origin https://github.com/tiararodney/HomaModule.git
git -C HomaModule.git/ fetch origin linux-v619
git -C HomaModule.git/ checkout "$COMMIT"

sh ./configure --with-docker-gcc=15
make kernels/linux-${KERNEL_VERSION}-unit/include/generated/autoconf.h

# set up build dir once, usually the test bench make takes care of that, but I
# just need to compile a single file to proof the failure...
BDIR=build/$KERNEL_VERSION/$COMMIT
mkdir -p $BDIR/test
cp -alf -t $BDIR      HomaModule.git/*.c HomaModule.git/*.h HomaModule.git/Makefile
cp -alf -t $BDIR/test  HomaModule.git/test/*
rm -f $BDIR/test/mock.c
cat HomaModule.git/test/mock.c unit-mock-compat.c > $BDIR/test/mock.c

xcompile() {
    rm -f $BDIR/test/unit_homa_incoming.o $BDIR/test/.deps
    docker run --rm -v "$PWD":/src homa-gcc15 \
        make -C $BDIR/test \
        KDIR=/src/kernels/linux-$KERNEL_VERSION-unit \
        unit_homa_incoming.o
}

printf 'checking with no `-std=gnu11 -fms-extensions`... ' \
| tee -a result.log
sed -i 's/-std=gnu11 -fms-extensions //' $BDIR/test/Makefile
! xcompile && {
    echo "failed (expected)" | tee -a result.log
} || {
    echo "passed (unexpected)" | tee -a result.log
}

printf 'checking with `-std=gnu11 only` (no `-fms-extensions`)... ' \
| tee -a result.log
sed -i 's/^CFLAGS :=    /CFLAGS :=    -std=gnu11 /' $BDIR/test/Makefile
! xcompile && {
    echo "failed (expected)" | tee -a result.log
} || {
    echo "passed (unexpected)" | tee -a result.log
}

printf 'checking with `-std=gnu11` `-fms-extensions`... ' \
| tee -a result.log
sed -i 's/-std=gnu11 /-std=gnu11 -fms-extensions /' $BDIR/test/Makefile
xcompile && {
    echo "passed (expected)" | tee -a result.log
} || {
    echo "failed (unexpected)" | tee -a result.log
}

cat result.log
EOF

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; I've now added these changes to my repo.

Comment thread homa_qdisc.c

#include <linux/ethtool.h>

#ifndef qdisc_from_priv

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm going to redefine this with a Homa-specific name, in order to eliminate any dependency on Linux version.

Comment thread test/rbtree.c
__rb_insert(node, root, augment_rotate);
}

/* Linux 6.19 inlined rb_first()/rb_last() into <linux/rbtree.h> as static

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than trying to patch the sources to rbtree.c, rhashtable.c, and xxhash.c so that they compile across multiple versions, I wonder if it might be simpler just to keep different versions of these files and then select the appropriate version in the Makefile (this is basically what I have been doing so far: when I upgrade to new Linux versions, I grab new versions of those files from the kernel sources)? Thoughts on the tradeoffs between these approaches?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. My motivation for cherry-picking the commits of the kernel sources was mainly provenance.

TLDR; Copy/Paste approach: simpler, but check-free and requires extra care for documentation. Patching/Commit approach: extra-steps, but comes with a trip-wire and is self-documenting.

A "copy file over from release 6.18" approach, that's all changes to the file up until 6.18, I wouldn't necessarily argue against. But I imagined this would be harder to reason over, since the patch would not necessarily reflect "all changes up until it broke". Traceability would solely depend upon a proper commit message.

Retaining the commit history provenance of the kernel sources circumvents this entirely. It's extra steps, but they're mechanical and it would also be a free trip-wire in regards to drifts and regressions, since conflicting changes would actually result in a merge conflict. Copy-pasting would be conflict free, but only because it's check-free... The changes would also basically be self-documenting. Additionally, the coupling with consumers is stronger compared to orchestrating via Makefile, as there can only ever be one version of a file checked out.

You'd retain the versioning against kernel versions (currently handled via Makefile) if patching against the kernel remained chronologically ordered, as the branches currently imply (I'm referring to this in #110 (comment)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking this over, I've decided to go with the full-file approach. For these files, I don't think provenance matters: all that matters is having a .c file that is consistent with the .h file from the system directories (so people don't need full Linux sources to compile Homa's tests). I don't expect there to be very many distinct versions at any given time, and upgrading feels easier this way (just grab the .c file that corresponds to the header file for the current release).

Comment thread test/Makefile
$(KERN_INCLUDES) \
-include $(KDIR)/include/linux/kconfig.h
-include $(KDIR)/include/linux/kconfig.h \
-include seg_compat.h

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say a bit more about why this file is needed? I saw the commit log entry, but I'm confused because my normal build version is 6.17 and I'm not seeing any problems (and CONFIG_CC_HAS_NAMED_AS is defined for me).

@tiararodney tiararodney Oct 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible, that your kernel config doesn't set CONFIG_USE_X86_SEG_SUPPORT? It's gated by both CONFIG_CC_HAS_NAMED_AS and CONFIG_USE_X86_SEG_SUPPORT independently.

I was trying to rectify

./mock.h:244:28: error: conflicting named address spaces (generic vs __seg_gs) for 'current_task'

these are all the sites that popped up:

with the #undefs, we're avoiding these sites.

Here's a script to recreate the issue and fix (Ubuntu 26.04, GCC15, kernel 7.0.14). I've been assuming a minimal kernel config with defaults (though tinyconfig isn't working, which I described here)

sh -ex <<'EOF'
WORKDIR="$(mktemp -d)"
KERNEL_VERSION=7.0.14
COMMIT=0815fe9

finally() {
    rm -rf "$WORKDIR"
}
trap finally EXIT

git clone https://github.com/tiararodney/HomaModuleTestBench.git "$WORKDIR"
cd "$WORKDIR"
git submodule update --init HomaModule.git/

git -C HomaModule.git/ remote set-url origin https://github.com/tiararodney/HomaModule.git
git -C HomaModule.git/ fetch origin linux-v619
git -C HomaModule.git/ checkout "$COMMIT"

sh ./configure --with-docker-gcc=15
make kernels/linux-${KERNEL_VERSION}-unit/include/generated/autoconf.h

printf "checking kernel config CONFIG_CC_HAS_NAMED_AS... " | tee -a result.log
grep -q 'CONFIG_CC_HAS_NAMED_AS=y' \
    kernels/linux-${KERNEL_VERSION}-unit/include/config/auto.conf && {
    echo 'set (y)' | tee -a result.log
} || {
    echo 'not set' | tee -a result.log
}
printf "checking kernel config CONFIG_USE_X86_SEG_SUPPORT... " | tee -a result.log
grep -q 'CONFIG_USE_X86_SEG_SUPPORT=y' \
    kernels/linux-${KERNEL_VERSION}-unit/include/config/auto.conf && {
    echo 'set (y)' | tee -a result.log
} || {
    echo 'not set' | tee -a result.log
}

# shortcut. normally the test bench make does this... For the proof, 
# compilation of a single file is enough...
BDIR=build/$KERNEL_VERSION/$COMMIT
mkdir -p $BDIR/test
cp -alf -t $BDIR      HomaModule.git/*.c HomaModule.git/*.h HomaModule.git/Makefile
cp -alf -t $BDIR/test  HomaModule.git/test/*
rm -f $BDIR/test/mock.c
cat HomaModule.git/test/mock.c unit-mock-compat.c > $BDIR/test/mock.c

xcompile() {
    rm -f $BDIR/test/unit_homa_incoming.o $BDIR/test/.deps
    docker run --rm -v "$PWD":/src homa-gcc15 \
        make -C $BDIR/test \
        KDIR=/src/kernels/linux-${KERNEL_VERSION}-unit \
        unit_homa_incoming.o
}

printf 'checking compilation without seg_compat.h... ' | tee -a result.log
sed -i 's/-include seg_compat.h//' $BDIR/test/Makefile
! xcompile && {
    echo "failed (expected)" | tee -a result.log
} || {
    echo "passed (unexpected)" | tee -a result.log
}

printf 'checking compilation with seg_compat.h... ' | tee -a result.log
sed -i '/-include.*kconfig\.h/a\
\t    -include seg_compat.h' $BDIR/test/Makefile
xcompile && {
    echo "passed (expected)" | tee -a result.log
} || {
    echo "failed (unexpected)" | tee -a result.log
}

cat result.log
EOF

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I finally bit the bullet and created a 7.0.14 build environment so I can test all of the changes. I was able to build and run unit tests under 7.0.14 without needing these changes. Is it possible the the issues you are seeing are related to a difference in compiler versions (I'm using gcc 13.3.0). For now, I'm going to leave this patch out. I will push what I believe is a working version shortly.

Can you try that out and let me know if you're still having problems building on 7.0.14?

linux 7.0 turned __vlan_get_protocol_offset() into an out-of-line function
returning struct vlan_type_depth [1]. The inlined `__vlan_get_protocol()` calls
it, so it is needed at link time.

Providing a mock returning a zeroed vlan_type_depth.

[1] torvalds/linux@7a4cd71
@tiararodney

Copy link
Copy Markdown
Contributor Author

Thanks for these patches. Most look good to me and I will start applying them, but I have a few questions.

Glad I can contribute in some capacity! The patching journey towards 7.0 is now finally complete... The linker issues are now resolved as well and the test harness executes.

Are you sure about cherry-picking the commits directly onto main though?

The commits currently are in chronological order of my patching odyssee, which probably isn't ideal for a PR?

I kept all commits strictly atomic, so it would be possible to order them in regards to the linux version they target. That way the repository convention for releasing versioned tags signifying the linux kernel version compatibility could be kept across all breaking kernel versions (6.15, 6.17, 6.18 and 7.0 from what I discovered during patching).

My suggestion would be to use this PR as a scratchpad and once you're happy with the patches, I'd chunk the commits for multiple PRs (squash where appropriate), targeting the kernel versions they're patching. I'd write a Git rebase script, based on this PR branch HEAD, so we can be sure as to not introduce any regressions?

@johnousterhout

johnousterhout commented Oct 5, 2026 via email

Copy link
Copy Markdown
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants