Date: Fri, 31 Jan 2025 16:03:21 GMT From: =?utf-8?Q?Jean-S=C3=A9bastien?= =?utf-8?Q?P=C3=A9dron?= <dumbbell@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 1de8fcf419fc - main - linuxkpi: Add Linux 6.7 `get_file_rcu()` variant Message-ID: <202501311603.50VG3LPI038815@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by dumbbell: URL: https://cgit.FreeBSD.org/src/commit/?id=1de8fcf419fce890474271215dce3b6e4876b60a commit 1de8fcf419fce890474271215dce3b6e4876b60a Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> AuthorDate: 2025-01-01 13:11:14 +0000 Commit: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> CommitDate: 2025-01-31 16:00:49 +0000 linuxkpi: Add Linux 6.7 `get_file_rcu()` variant [Why] In Linux 6.7, the signature of `get_file_rcu()` changed significantly, going from: bool get_file_rcu(struct linux_file *f); ... to: struct linux_file * get_file_rcu(struct linux_file **f); I.e., both the argument and the return value changed in an incompatible way. This is used by the i915 DRM driver. [How] This patch introduces the variant and hide the new prototype behind `LINUXKPI_VERSION >= 60700`. Reviewed by: manu Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D48756 --- sys/compat/linuxkpi/common/include/linux/fs.h | 5 ++++ sys/compat/linuxkpi/common/src/linux_compat.c | 39 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h index d277b717423f..86b922ac9a1d 100644 --- a/sys/compat/linuxkpi/common/include/linux/fs.h +++ b/sys/compat/linuxkpi/common/include/linux/fs.h @@ -264,12 +264,17 @@ get_file(struct linux_file *f) return (f); } +struct linux_file * linux67_get_file_rcu(struct linux_file **f); +#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60700 +#define get_file_rcu(f) linux67_get_file_rcu(f) +#else static inline bool get_file_rcu(struct linux_file *f) { return (refcount_acquire_if_not_zero( f->_file == NULL ? &f->f_count : &f->_file->f_count)); } +#endif static inline struct inode * igrab(struct inode *inode) diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index ec3ccb16b47d..e5049a4b8f43 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -75,6 +75,7 @@ #include <linux/moduleparam.h> #include <linux/cdev.h> #include <linux/file.h> +#include <linux/fs.h> #include <linux/sysfs.h> #include <linux/mm.h> #include <linux/io.h> @@ -1082,6 +1083,44 @@ linux_poll_wakeup(struct linux_file *filp) spin_unlock(&filp->f_kqlock); } +static struct linux_file * +__get_file_rcu(struct linux_file **f) +{ + struct linux_file *file1, *file2; + + file1 = READ_ONCE(*f); + if (file1 == NULL) + return (NULL); + + if (!refcount_acquire_if_not_zero( + file1->_file == NULL ? &file1->f_count : &file1->_file->f_count)) + return (ERR_PTR(-EAGAIN)); + + file2 = READ_ONCE(*f); + if (file2 == file1) + return (file2); + + fput(file1); + return (ERR_PTR(-EAGAIN)); +} + +struct linux_file * +linux67_get_file_rcu(struct linux_file **f) +{ + struct linux_file *file1; + + for (;;) { + file1 = __get_file_rcu(f); + if (file1 == NULL) + return (NULL); + + if (IS_ERR(file1)) + continue; + + return (file1); + } +} + static void linux_file_kqfilter_detach(struct knote *kn) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202501311603.50VG3LPI038815>