From 4631ac5d83c47f282bf74d57f27537e4a9c012f1 Mon Sep 17 00:00:00 2001 From: Sergey Nikitin Date: Mon, 3 Mar 2025 17:37:50 +0300 Subject: [PATCH 1/3] fix root Makefile to support linux-6.13 Fix path to kernel sources for autocompat scripts. CURDIR cannot be used since it now points to Onload build directory. Use objtree instead. Fix expression, that sets 'src' variable, to use absolute 'obj' path. See Linux commit 13b25489b6f8 Signed-off-by: Sergey Nikitin --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f089e35db..ec12e487f 100644 --- a/Makefile +++ b/Makefile @@ -118,7 +118,7 @@ AUTOCOMPAT := $(obj)/src/driver/linux_resource/autocompat.h LINUX_RESOURCE := $(src)/src/driver/linux_resource $(AUTOCOMPAT): $(LINUX_RESOURCE)/kernel_compat.sh $(LINUX_RESOURCE)/kernel_compat_funcs.sh @mkdir -p $(@D) - ($< -k $(CURDIR) $(if $(filter 1,$(V)),-v,-q) > $@) || (rm -f $@ && false) + ($< -k $(realpath $(objtree)) $(if $(filter 1,$(V)),-v,-q) > $@) || (rm -f $@ && false) mkdirs: @mkdir -p $(obj)/src/lib/efhw @@ -251,7 +251,7 @@ $(scripts): $(KBUILDTOP)/driver/linux/%.sh: src/driver/linux/%.sh modules modules_install: $(OUTMAKEFILES) $(Q)$(MAKE) -C $(KPATH) M=$(KBUILDTOP) \ - "src=\$$(patsubst $(KBUILDTOP)%,$$PWD%,\$$(obj))" \ + "src=\$$(patsubst $(KBUILDTOP)%,$$PWD%,\$$(realpath \$$(obj)))" \ "SRCPATH=$$PWD/src" \ 'subdir-ccflags-y=$(subst ','\'',$(ONLOAD_CFLAGS))' \ MMAKE_IN_KBUILD=1 MMAKE_USE_KBUILD=1 MMAKE_NO_RULES=1 \ From 28028588421d901001a5c1182b45672bfc130287 Mon Sep 17 00:00:00 2001 From: Sergey Nikitin Date: Mon, 3 Mar 2025 17:02:46 +0300 Subject: [PATCH 2/3] driver/onload: fix compat for get_file_rcu() Current compat code assumes that get_file_rcu() is a macro. It's not true since linux-6.7. Additionally, in linux-6.13, after removing file::f_count field, this code no longer compiles. See Linux commits 0ede61d8589c and 90ee6ed776c0. Update compat code to support new version of get_file_rcu(). Signed-off-by: Sergey Nikitin --- src/driver/linux_onload/onload_kernel_compat.h | 16 ++++++++++++---- src/driver/linux_onload/onloadfs.c | 2 +- src/driver/linux_resource/kernel_compat.sh | 1 + src/lib/efthrm/tcp_helper_ioctl.c | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/driver/linux_onload/onload_kernel_compat.h b/src/driver/linux_onload/onload_kernel_compat.h index 3ca63c79b..5475fe039 100644 --- a/src/driver/linux_onload/onload_kernel_compat.h +++ b/src/driver/linux_onload/onload_kernel_compat.h @@ -36,10 +36,18 @@ ci_call_usermodehelper(char *path, char **argv, char **envp, int wait); #endif -#ifndef get_file_rcu -/* Linux <= 4.0 */ -#define get_file_rcu(x) atomic_long_inc_not_zero(&(x)->f_count) -#endif +static inline struct file *ci_get_file_rcu(struct file **f) +{ +#ifdef EFRM_HAVE_GET_FILE_RCU_FUNC + return get_file_rcu(f); +#else + /* In linux < 6.7 get_file_rcu() was defined as a macro, like this: + * #define get_file_rcu(x) atomic_long_inc_not_zero(&(x)->f_count) + * Use the same implementation, but match new get_file_rcu() prototype. */ + struct file *file = *f; + return atomic_long_inc_not_zero(&file->f_count) ? file : NULL; +#endif /* EFRM_HAVE_GET_FILE_RCU_FUNC */ +} /* init_timer() was removed in Linux 4.15, with timer_setup() * replacing it */ diff --git a/src/driver/linux_onload/onloadfs.c b/src/driver/linux_onload/onloadfs.c index 7d61b5d3c..805a3d1aa 100644 --- a/src/driver/linux_onload/onloadfs.c +++ b/src/driver/linux_onload/onloadfs.c @@ -346,7 +346,7 @@ oo_create_fd(tcp_helper_resource_t* thr, oo_sp ep_id, int flags, if( _filp && *_filp ) { rcu_read_lock(); - rc = get_file_rcu(*_filp); + rc = !IS_ERR_OR_NULL(ci_get_file_rcu(_filp)); rcu_read_unlock(); if( rc == 0 ) { OO_DEBUG_TCPH(ci_log("%s: fd=%d reuses file", __FUNCTION__, fd)); diff --git a/src/driver/linux_resource/kernel_compat.sh b/src/driver/linux_resource/kernel_compat.sh index d277510b1..7b976e21b 100755 --- a/src/driver/linux_resource/kernel_compat.sh +++ b/src/driver/linux_resource/kernel_compat.sh @@ -177,6 +177,7 @@ EFRM_HAVE_FOLLOW_PTE symbol follow_pte include/linux/mm.h EFRM_HAVE_FOLLOW_PTE_VMA symtype follow_pte include/linux/mm.h int(struct vm_area_struct*, unsigned long, pte_t**, spinlock_t**) EFRM_HAVE_LINUX_TPH_H file include/linux/pci-tph.h +EFRM_HAVE_GET_FILE_RCU_FUNC symtype get_file_rcu include/linux/fs.h struct file*(struct file __rcu **) # TODO move onload-related stuff from net kernel_compat " | grep -E -v -e '^#' -e '^$' | sed 's/[ \t][ \t]*/:/g' diff --git a/src/lib/efthrm/tcp_helper_ioctl.c b/src/lib/efthrm/tcp_helper_ioctl.c index 204590f62..7f5359894 100644 --- a/src/lib/efthrm/tcp_helper_ioctl.c +++ b/src/lib/efthrm/tcp_helper_ioctl.c @@ -340,7 +340,7 @@ efab_tcp_helper_detach_file(tcp_helper_endpoint_t* ep, filp = ep->file_ptr; /* filp might be NULL if we raced with FD close, other than that * filp is still valid even if close completed concurrently thanks to rcu_lock */ - if( filp == NULL || ! get_file_rcu(filp) ) { + if( filp == NULL || IS_ERR_OR_NULL(ci_get_file_rcu(&filp)) ) { /* filp is being freed concurrently, best to back off until it is completed */ OO_DEBUG_TCPH(ci_log("%s: pid=%d fd=%d => is being freed", __FUNCTION__, pid, fd)); CITP_STATS_NETIF_INC(&trs->netif, sock_attach_fd_detach_fail_soft); From e0c168f8fdd6a02c57170511cbfb286d0f1f7584 Mon Sep 17 00:00:00 2001 From: Sergey Nikitin Date: Mon, 3 Mar 2025 16:46:58 +0300 Subject: [PATCH 3/3] lib/efthrm: fix usage of poll_does_not_wait() poll_does_not_wait() was removed in linux-6.13. Replace it with direct access to poll_table structure. Signed-off-by: Sergey Nikitin --- src/lib/efthrm/tcp_helper_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/efthrm/tcp_helper_linux.c b/src/lib/efthrm/tcp_helper_linux.c index e5bbc0ba9..64fb0d73e 100644 --- a/src/lib/efthrm/tcp_helper_linux.c +++ b/src/lib/efthrm/tcp_helper_linux.c @@ -414,7 +414,7 @@ static unsigned efab_linux_tcp_helper_fop_poll_tcp(struct file* filp, efab_fop_poll__prime_if_needed(trs, tep_p, SOCK_POLL_AWAITING_EVENTS(mask, wait), enable_interrupts); - if( ! poll_does_not_wait(wait) && s->b.state == CI_TCP_CLOSED && + if( wait && wait->_qproc && s->b.state == CI_TCP_CLOSED && tep_p->os_socket != NULL) { /* From the closed state, handover is possible. We should add OS * socket waitqueue to the poll table.