Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Sep 2023 09:39:50 +0900
From:      Tomoaki AOKI <junchoon@dec.sakura.ne.jp>
To:        Jake Freeland <jake@technologyfriends.net>, Warner Losh <imp@bsdimp.com>
Cc:        FreeBSD-STABLE Mailing List <freebsd-stable@freebsd.org>
Subject:   Re: Is there any plan for ZFS and timerfd updates on stable/14?
Message-ID:  <20230917093950.0dbe3eefb1c34d61dea8adef@dec.sakura.ne.jp>
In-Reply-To: <20230903133328.54577b85b097da319ecde4ba@dec.sakura.ne.jp>
References:  <20230903123028.4ffceb705824f86d2efc21e3@dec.sakura.ne.jp> <CAOgZAGbOGs8-iW7sAPBboO2OM_FNR2TrSpGH3qd1Rf9_qfhMwg@mail.gmail.com> <CANCZdfr61v7Po28f9mJ-a3ZVnQRArcSdfHw_1tuB3L7iCm04Dw@mail.gmail.com> <CAOgZAGaY=NAn9zSWEW4K_mm1z6J0MKKF3McKzsDZEUCgs3gVjA@mail.gmail.com> <20230903133328.54577b85b097da319ecde4ba@dec.sakura.ne.jp>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

--Multipart=_Sun__17_Sep_2023_09_39_50_+0900_e5eQYjc5MKn/Pcke
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On Sun, 3 Sep 2023 13:33:28 +0900
Tomoaki AOKI <junchoon@dec.sakura.ne.jp> wrote:

> On Sat, 2 Sep 2023 22:47:53 -0500
> Jake Freeland <jake@technologyfriends.net> wrote:
> 
> > On Sat, Sep 2, 2023 at 10:40 PM Warner Losh <imp@bsdimp.com> wrote:
> > 
> > >
> > >
> > > On Sat, Sep 2, 2023, 9:36 PM Jake Freeland <jake@technologyfriends.net>
> > > wrote:
> > >
> > >> On Sat, Sep 2, 2023 at 10:31 PM Tomoaki AOKI <junchoon@dec.sakura.ne.jp>
> > >> wrote:
> > >>
> > >>> Hi.
> > >>>
> > >>> There are discussions about deadlocks issue of ZFS on freebsd-current
> > >>> ML, starting from [1] last month.
> > >>> IIRC, at least some fixes (candidates?) are merged to main, but not yet
> > >>> to stable/14.
> > >>>
> > >>> Upcoming (aleready released? or still rc3?) OpenZFS 2.2-release seems
> > >>> to have most of them. So my 1st question is "Is there any plan to
> > >>> import vendor/openzfs/zfs-2.2-release into stable/14 BEFORE BRANCHING
> > >>> releng/14?
> > >>>
> > >>> And one more. timerfd is added at last-minutes BEFORE stable/14 is
> > >>> branched, and already have not-yet-MFC'ed fixes [2], [3], [4] and
> > >>> Differential revision D41600 on Phablicator [5] related to memory leaks
> > >>> and locks.
> > >>> Additionally, splitting out lib32 part to proper place is proposed
> > >>> as D41640 [6].  Both [5] and [6] are accepted but not yet landed.
> > >>> Also, D41641 [7] proposes namespace pollution adjustments. This can be
> > >>> optional?
> > >>>
> > >>> Memory leaks and improper locks can lead system to security issues or
> > >>> deadlocks, so it would be benefical if landed and MFC'ed BEFORE
> > >>> releng/14 branches.
> > >>>
> > >>> Is there any plan to do so? At least, existing deadlocks should be
> > >>> considered as SHOW-STOPPER and resolved.
> > >>>
> > >>
> > >> The plan is to get all of those patches in before releng/14.0, I believe.
> > >>
> > >> What are your thoughts, Warner?
> > >>
> > >
> > > Sounds like the reviews are done or nearly so. I've not had time to look
> > > closely to be sure... I'd planned on making time Tuesday morning.
> > >
> > 
> > Yes. All reviews are good to go.
> > 
> > Jake Freeland
> 
> Glad to know. Thanks!
> Looking forward to see them landed / MFC'ed before releng/14 branches.
> 
> Regards.
> 
> > 
> > 
> > >
> > > Warner
> > >
> > >
> > >> Thanks,
> > >> Jake Freeland
> > >>
> > >>
> > >>>
> > >>> I myself am bitten by several deadlocks on poudriere full builds after
> > >>> upgrading base from stable/13 to stable/14, finally finished with
> > >>> increasing kern.maxvnodes after powercycle on each deadlock and
> > >>> continue.
> > >>>
> > >>>
> > >>> Thanks in advance!
> > >>>
> > >>> [1]
> > >>>
> > >>> https://lists.freebsd.org/archives/freebsd-current/2023-August/004162.html
> > >>>
> > >>> [2]
> > >>>
> > >>> https://cgit.freebsd.org/src/commit/?id=02f534b57f84d6f4f97c337b05b383c8b3aaf18c
> > >>>
> > >>> [3]
> > >>>
> > >>> https://cgit.freebsd.org/src/commit/?id=5eab523053db79b4bd4f926c7d7ac04444d9c1da
> > >>>
> > >>> [4]
> > >>>
> > >>> https://cgit.freebsd.org/src/commit/?id=f4296cfb409a48de00bfa60e76f686c2b031876f
> > >>>
> > >>> [5] https://reviews.freebsd.org/D41600
> > >>>
> > >>> [6] https://reviews.freebsd.org/D41640
> > >>>
> > >>> [7] https://reviews.freebsd.org/D41641
> > >>>
> > >>> --
> > >>> Tomoaki AOKI    <junchoon@dec.sakura.ne.jp>
> 
> -- 
> Tomoaki AOKI    <junchoon@dec.sakura.ne.jp>

Hi. Thanks for your hard work on it.

I could confirm commits to main as below, but they are not yet
MFC'ed/MFS'/ed.
It would be nice these commits to be incorporated at worst on first RC.
Any plans for MFC and following MFS?

commit	02f534b57f84d6f4f97c337b05b383c8b3aaf18c
  timerfd: fix up a memory leak and missing locking

commit	5eab523053db79b4bd4f926c7d7ac04444d9c1da
  timerfd: compute fflags before calling falloc

commit	f4296cfb409a48de00bfa60e76f686c2b031876f
  timerfd: convert timerfd_list_lock from sx to mtx

commit	a1f506156c4db885d3cc177c93e9c8a28d535d30
  timerfd: Define a locking regime

commit	918966a27479b4fb7c4c8999c4926d83c2c081e5
  timerfd: Relocate 32-bit compat code

commit	fb5daae920bae84e3eec8175bf9e46304c3b2ae6
  timerfd: Namespace pollution adjustments


Note that first 3 commits are authord/committed by mjg@.
These are all I could confirm landed with commit histories of
sys/kern/sys_timerfd.c and sys/sys/timerfd.c, excluding
already-in-stable/14 one.

I've found a related commit to sys/compat/linux/linux_event.c but
intentionally excluded it, as it's already MFC'ed and MFS'ed.

And I found another request on dev-commits-src-main ML archive [1],
without any reply.

Attached is the hand-merged patch to cherry pick them to stable/14,
created before last 3 commits landed on main. HTH.

[1]
https://lists.freebsd.org/archives/dev-commits-src-main/2023-September/018407.html

Regards.

-- 
Tomoaki AOKI    <junchoon@dec.sakura.ne.jp>

--Multipart=_Sun__17_Sep_2023_09_39_50_+0900_e5eQYjc5MKn/Pcke
Content-Type: text/x-diff;
 name="MFC_git_02f534b57f84_5eab523053db_f4296cfb409a_D41600_D41640_D41641-Fix_up_memory_leak_and_missing_locking-kern_sys__timerfd.c.diff"
Content-Disposition: attachment;
 filename="MFC_git_02f534b57f84_5eab523053db_f4296cfb409a_D41600_D41640_D41641-Fix_up_memory_leak_and_missing_locking-kern_sys__timerfd.c.diff"
Content-Transfer-Encoding: 7bit

author	Mateusz Guzik <mjg@FreeBSD.org>	2023-08-25 14:21:39 +0000
committer	Mateusz Guzik <mjg@FreeBSD.org>	2023-08-25 14:46:48 +0000
commit	02f534b57f84d6f4f97c337b05b383c8b3aaf18c (patch)
tree	6fa7b496057ecf6bf50e6e3e90f59701784898c4
parent	1554ba03b651319ab0e1cde8492ea4516afc648b (diff)
download	src-02f534b57f84d6f4f97c337b05b383c8b3aaf18c.tar.gz
src-02f534b57f84d6f4f97c337b05b383c8b3aaf18c.zip
timerfd: fix up a memory leak and missing locking
timerfd01 from ltp passes (and some other don't), but none of the tests
crash the kernel.

This is a bare minimum patch to fix up the immediate regression.

Reported by:	yasu
Diffstat
-rw-r--r--	sys/kern/sys_timerfd.c	31	
		
1 files changed, 21 insertions, 10 deletions


author	Mateusz Guzik <mjg@FreeBSD.org>	2023-08-25 15:09:21 +0000
committer	Mateusz Guzik <mjg@FreeBSD.org>	2023-08-25 15:09:21 +0000
commit	5eab523053db79b4bd4f926c7d7ac04444d9c1da (patch)
tree	f02acc2778545722abe65a35a9866b45d8912970
parent	02f534b57f84d6f4f97c337b05b383c8b3aaf18c (diff)
download	src-5eab523053db79b4bd4f926c7d7ac04444d9c1da.tar.gz
src-5eab523053db79b4bd4f926c7d7ac04444d9c1da.zip
timerfd: compute fflags before calling falloc
While here dodge list locking in timerfd_adjust if empty.
Diffstat
-rw-r--r--	sys/kern/sys_timerfd.c	12	
		
1 files changed, 8 insertions, 4 deletions


Author	Mateusz Guzik <mjg@FreeBSD.org>	2023-09-02 09:55:50 +0000
committer	Mateusz Guzik <mjg@FreeBSD.org>	2023-09-02 09:55:50 +0000
commit	f4296cfb409a48de00bfa60e76f686c2b031876f (patch)
tree	0cc429e199d2e67c6067f668e277c3033c58b76d
parent	07bc20e4740d09f554c3787bb1940fc503300822 (diff)
download	src-f4296cfb409a48de00bfa60e76f686c2b031876f.tar.gz
src-f4296cfb409a48de00bfa60e76f686c2b031876f.zip
timerfd: convert timerfd_list_lock from sx to mtx
There was no good reason to use the former. This should prevent some
head-scratching by an interested and qualified reader.
Diffstat
-rw-r--r--	sys/kern/sys_timerfd.c	16	
		
1 files changed, 8 insertions, 8 deletions


Define a locking regime for the members of struct timerfd and document
it so future code can follow the standard. The lock legend can be found
in a comment above struct timerfd.

Additionally,
* Add assertions based on locking regime.
* Fill kn_data with the expiration count when EVFILT_READ is triggered.
* Report st_ctim for stat(2).
* Check if file has f_type == DTYPE_TIMERFD before assigning timerfd
  pointer to f_data.


32-bit compatibility code is conventionally stored in
sys/compat/freebsd32. Move freebsd32_timerfd_gettime() and
freebsd32_timerfd_settime() from sys/kern/sys_timerfd.c to
sys/compat/freebsd32/freebsd32_misc.c.


Do not pollute userspace with <sys/proc.h>, instead declare struct thread
when _KERNEL is defined.

Include <sys/time.h> instead of <sys/timespec.h>. This causes intentional
namespace pollution that mimics Linux. g/musl libcs include <time.h> in
their <sys/timerfd.h>, exposing timerfd_gettime() and CLOCK_ macro
constants. Ports like Chromium expect this namespace pollution and fail
without it.


diff --git a/sys/kern/sys_timerfd.c b/sys/kern/sys_timerfd.c
index 6948fa059b8c..c8b45a926b02 100644
--- a/sys/kern/sys_timerfd.c
+++ b/sys/kern/sys_timerfd.c
@@ -43,6 +43,7 @@
 #include <sys/queue.h>
 #include <sys/selinfo.h>
 #include <sys/stat.h>
+#include <sys/sx.h>
 #include <sys/sysctl.h>
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
@@ -53,13 +54,12 @@
 
 #include <security/audit/audit.h>
 
-#ifdef COMPAT_FREEBSD32
-#include <compat/freebsd32/freebsd32.h>
-#include <compat/freebsd32/freebsd32_proto.h>
-#endif
-
 static MALLOC_DEFINE(M_TIMERFD, "timerfd", "timerfd structures");
-static LIST_HEAD(, timerfd) timerfd_head;
+
+static struct mtx timerfd_list_lock;
+static LIST_HEAD(, timerfd) timerfd_list;
+MTX_SYSINIT(timerfd, &timerfd_list_lock, "timerfd_list_lock", MTX_DEF);
+
 static struct unrhdr64 tfdino_unr;
 
 #define	TFD_NOJUMP	0	/* Realtime clock has not jumped. */
@@ -68,28 +68,36 @@
 #define	TFD_CANCELED	4	/* Jumped, CANCEL_ON_SET=true. */
 #define	TFD_JUMPED	(TFD_ZREAD | TFD_CANCELED)
 
+/*
+ * One structure allocated per timerfd descriptor.
+ *
+ * Locking semantics:
+ * (t)	locked by tfd_lock mtx
+ * (l)	locked by timerfd_list_lock sx
+ * (c)	const until freeing
+ */
 struct timerfd {
 	/* User specified. */
-	struct itimerspec tfd_time;	/* tfd timer */
-	clockid_t	tfd_clockid;	/* timing base */
-	int		tfd_flags;	/* creation flags */
-	int		tfd_timflags;	/* timer flags */
+	struct itimerspec tfd_time;	/* (t) tfd timer */
+	clockid_t	tfd_clockid;	/* (c) timing base */
+	int		tfd_flags;	/* (c) creation flags */
+	int		tfd_timflags;	/* (t) timer flags */
 
 	/* Used internally. */
-	timerfd_t	tfd_count;	/* expiration count since last read */
-	bool		tfd_expired;	/* true upon initial expiration */
-	struct mtx	tfd_lock;	/* mtx lock */
-	struct callout	tfd_callout;	/* expiration notification */
-	struct selinfo	tfd_sel;	/* I/O alerts */
-	struct timespec	tfd_boottim;	/* cached boottime */
-	int		tfd_jumped;	/* timer jump status */
-	LIST_ENTRY(timerfd) entry;	/* entry in list */
+	timerfd_t	tfd_count;	/* (t) expiration count since read */
+	bool		tfd_expired;	/* (t) true upon initial expiration */
+	struct mtx	tfd_lock;	/* tfd mtx lock */
+	struct callout	tfd_callout;	/* (t) expiration notification */
+	struct selinfo	tfd_sel;	/* (t) I/O alerts */
+	struct timespec	tfd_boottim;	/* (t) cached boottime */
+	int		tfd_jumped;	/* (t) timer jump status */
+	LIST_ENTRY(timerfd) entry;	/* (l) entry in list */
 
 	/* For stat(2). */
-	ino_t		tfd_ino;	/* inode number */
-	struct timespec	tfd_atim;	/* time of last read */
-	struct timespec	tfd_mtim;	/* time of last settime */
-	struct timespec tfd_birthtim;	/* creation time */
+	ino_t		tfd_ino;	/* (c) inode number */
+	struct timespec	tfd_atim;	/* (t) time of last read */
+	struct timespec	tfd_mtim;	/* (t) time of last settime */
+	struct timespec tfd_birthtim;	/* (c) creation time */
 };
 
 static void
@@ -104,6 +112,7 @@
 timerfd_getboottime(struct timespec *ts)
 {
 	struct timeval tv;
+
 	getboottime(&tv);
 	TIMEVAL_TO_TIMESPEC(&tv, ts);
 }
@@ -124,8 +133,12 @@ timerfd_jumped(void)
 	struct timerfd *tfd;
 	struct timespec boottime, diff;
 
+	if (LIST_EMPTY(&timerfd_list))
+		return;
+
 	timerfd_getboottime(&boottime);
-	LIST_FOREACH(tfd, &timerfd_head, entry) {
+	mtx_lock(&timerfd_list_lock);
+	LIST_FOREACH(tfd, &timerfd_list, entry) {
 		mtx_lock(&tfd->tfd_lock);
 		if (tfd->tfd_clockid != CLOCK_REALTIME ||
 		    (tfd->tfd_timflags & TFD_TIMER_ABSTIME) == 0 ||
@@ -160,6 +170,7 @@ timerfd_jumped(void)
 		tfd->tfd_boottim = boottime;
 		mtx_unlock(&tfd->tfd_lock);
 	}
+	mtx_unlock(&timerfd_list_lock);
 }
 
 static int
@@ -264,6 +273,8 @@
 {
 	struct timerfd *tfd = kn->kn_hook;
 
+	mtx_assert(&tfd->tfd_lock, MA_OWNED);
+	kn->kn_data = (int64_t)tfd->tfd_count;
 	return (tfd->tfd_count > 0);
 }
 
@@ -298,13 +309,13 @@
 	sb->st_uid = fp->f_cred->cr_uid;
 	sb->st_gid = fp->f_cred->cr_gid;
 	sb->st_blksize = PAGE_SIZE;
-
 	mtx_lock(&tfd->tfd_lock);
-	sb->st_ino = tfd->tfd_ino;
 	sb->st_atim = tfd->tfd_atim;
 	sb->st_mtim = tfd->tfd_mtim;
-	sb->st_birthtim = tfd->tfd_birthtim;
 	mtx_unlock(&tfd->tfd_lock);
+	sb->st_ctim = sb->st_mtim;
+	sb->st_ino = tfd->tfd_ino;
+	sb->st_birthtim = tfd->tfd_birthtim;
 
 	return (0);
 }
@@ -314,11 +325,14 @@ timerfd_close(struct file *fp, struct thread *td)
 {
 	struct timerfd *tfd = fp->f_data;
 
+	mtx_lock(&timerfd_list_lock);
+	LIST_REMOVE(tfd, entry);
+	mtx_unlock(&timerfd_list_lock);
+
 	callout_drain(&tfd->tfd_callout);
 	seldrain(&tfd->tfd_sel);
 	knlist_destroy(&tfd->tfd_sel.si_note);
 	mtx_destroy(&tfd->tfd_lock);
-	LIST_REMOVE(tfd, entry);
 	free(tfd, M_TIMERFD);
 	fp->f_ops = &badfileops;
 
@@ -329,15 +340,12 @@
 timerfd_fill_kinfo(struct file *fp, struct kinfo_file *kif,
     struct filedesc *fdp)
 {
-
 	struct timerfd *tfd = fp->f_data;
 
 	kif->kf_type = KF_TYPE_TIMERFD;
-	mtx_lock(&tfd->tfd_lock);
 	kif->kf_un.kf_timerfd.kf_timerfd_clockid = tfd->tfd_clockid;
 	kif->kf_un.kf_timerfd.kf_timerfd_flags = tfd->tfd_flags;
 	kif->kf_un.kf_timerfd.kf_timerfd_addr = (uintptr_t)tfd;
-	mtx_unlock(&tfd->tfd_lock);
 
 	return (0);
 }
@@ -363,6 +371,7 @@
 {
 	struct timespec curr_value;
 
+	mtx_assert(&tfd->tfd_lock, MA_OWNED);
 	*old_value = tfd->tfd_time;
 	if (timespecisset(&tfd->tfd_time.it_value)) {
 		nanouptime(&curr_value);
@@ -408,7 +426,7 @@ kern_timerfd_create(struct thread *td, int clockid, int flags)
 {
 	struct file *fp;
 	struct timerfd *tfd;
-	int error, fd, fflags = 0;
+	int error, fd, fflags;
 
 	AUDIT_ARG_VALUE(clockid);
 	AUDIT_ARG_FFLAGS(flags);
@@ -417,12 +431,18 @@ kern_timerfd_create(struct thread *td, int clockid, int flags)
 		return (EINVAL);
 	if ((flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) != 0)
 		return (EINVAL);
+
+	fflags = FREAD;
 	if ((flags & TFD_CLOEXEC) != 0)
 		fflags |= O_CLOEXEC;
+	if ((flags & TFD_NONBLOCK) != 0)
+		fflags |= FNONBLOCK;
 
+	error = falloc(td, &fp, &fd, fflags);
+	if (error != 0)
+		return (error);
+
 	tfd = malloc(sizeof(*tfd), M_TIMERFD, M_WAITOK | M_ZERO);
-	if (tfd == NULL)
-		return (ENOMEM);
 	tfd->tfd_clockid = (clockid_t)clockid;
 	tfd->tfd_flags = flags;
 	tfd->tfd_ino = alloc_unr64(&tfdino_unr);
@@ -431,16 +447,12 @@ kern_timerfd_create(struct thread *td, int clockid, int flags)
 	knlist_init_mtx(&tfd->tfd_sel.si_note, &tfd->tfd_lock);
 	timerfd_getboottime(&tfd->tfd_boottim);
 	getnanotime(&tfd->tfd_birthtim);
-	LIST_INSERT_HEAD(&timerfd_head, tfd, entry);
+	mtx_lock(&timerfd_list_lock);
+	LIST_INSERT_HEAD(&timerfd_list, tfd, entry);
+	mtx_unlock(&timerfd_list_lock);
 
-	error = falloc(td, &fp, &fd, fflags);
-	if (error != 0)
-		return (error);
-	fflags = FREAD;
-	if ((flags & TFD_NONBLOCK) != 0)
-		fflags |= FNONBLOCK;
-
 	finit(fp, fflags, DTYPE_TIMERFD, tfd, &timerfdops);
+
 	fdrop(fp, td);
 
 	td->td_retval[0] = fd;
@@ -457,11 +466,11 @@
 	error = fget(td, fd, &cap_write_rights, &fp);
 	if (error != 0)
 		return (error);
-	tfd = fp->f_data;
-	if (tfd == NULL || fp->f_type != DTYPE_TIMERFD) {
+	if (fp->f_type != DTYPE_TIMERFD) {
 		fdrop(fp, td);
 		return (EINVAL);
 	}
+	tfd = fp->f_data;
 
 	mtx_lock(&tfd->tfd_lock);
 	timerfd_curval(tfd, curr_value);
@@ -489,11 +498,11 @@
 	error = fget(td, fd, &cap_write_rights, &fp);
 	if (error != 0)
 		return (error);
-	tfd = fp->f_data;
-	if (tfd == NULL || fp->f_type != DTYPE_TIMERFD) {
+	if (fp->f_type != DTYPE_TIMERFD) {
 		fdrop(fp, td);
 		return (EINVAL);
 	}
+	tfd = fp->f_data;
 
 	mtx_lock(&tfd->tfd_lock);
 	getnanotime(&tfd->tfd_mtim);
@@ -574,59 +570,3 @@
 	}
 	return (error);
 }
-
-#ifdef COMPAT_FREEBSD32
-int
-freebsd32_timerfd_gettime(struct thread *td,
-    struct freebsd32_timerfd_gettime_args *uap)
-{
-	struct itimerspec curr_value;
-	struct itimerspec32 curr_value32;
-	int error;
-
-	error = kern_timerfd_gettime(td, uap->fd, &curr_value);
-	if (error == 0) {
-		CP(curr_value, curr_value32, it_value.tv_sec);
-		CP(curr_value, curr_value32, it_value.tv_nsec);
-		CP(curr_value, curr_value32, it_interval.tv_sec);
-		CP(curr_value, curr_value32, it_interval.tv_nsec);
-		error = copyout(&curr_value32, uap->curr_value,
-		    sizeof(curr_value32));
-	}
-
-	return (error);
-}
-
-int
-freebsd32_timerfd_settime(struct thread *td,
-    struct freebsd32_timerfd_settime_args *uap)
-{
-	struct itimerspec new_value, old_value;
-	struct itimerspec32 new_value32, old_value32;
-	int error;
-
-	error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
-	if (error != 0)
-		return (error);
-	CP(new_value32, new_value, it_value.tv_sec);
-	CP(new_value32, new_value, it_value.tv_nsec);
-	CP(new_value32, new_value, it_interval.tv_sec);
-	CP(new_value32, new_value, it_interval.tv_nsec);
-	if (uap->old_value == NULL) {
-		error = kern_timerfd_settime(td, uap->fd, uap->flags,
-		    &new_value, NULL);
-	} else {
-		error = kern_timerfd_settime(td, uap->fd, uap->flags,
-		    &new_value, &old_value);
-		if (error == 0) {
-			CP(old_value, old_value32, it_value.tv_sec);
-			CP(old_value, old_value32, it_value.tv_nsec);
-			CP(old_value, old_value32, it_interval.tv_sec);
-			CP(old_value, old_value32, it_interval.tv_nsec);
-			error = copyout(&old_value32, uap->old_value,
-			    sizeof(old_value32));
-		}
-	}
-	return (error);
-}
-#endif
diff --git a/sys/sys/timerfd.h b/sys/sys/timerfd.h
--- a/sys/sys/timerfd.h
+++ b/sys/sys/timerfd.h
@@ -30,8 +30,7 @@
 
 #include <sys/types.h>
 #include <sys/fcntl.h>
-#include <sys/proc.h>
-#include <sys/timespec.h>
+#include <sys/time.h>
 
 typedef	uint64_t	timerfd_t;
 
@@ -54,6 +53,8 @@
 
 #else /* _KERNEL */
 
+struct thread;
+
 int kern_timerfd_create(struct thread *td, int clockid, int flags);
 int kern_timerfd_gettime(struct thread *td, int fd,
     struct itimerspec *curr_value);
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -82,6 +82,7 @@
 #include <sys/sysproto.h>
 #include <sys/systm.h>
 #include <sys/thr.h>
+#include <sys/timerfd.h>
 #include <sys/timex.h>
 #include <sys/unistd.h>
 #include <sys/ucontext.h>
@@ -3138,6 +3139,60 @@
 	return (error);
 }
 
+int
+freebsd32_timerfd_gettime(struct thread *td,
+    struct freebsd32_timerfd_gettime_args *uap)
+{
+	struct itimerspec curr_value;
+	struct itimerspec32 curr_value32;
+	int error;
+
+	error = kern_timerfd_gettime(td, uap->fd, &curr_value);
+	if (error == 0) {
+		CP(curr_value, curr_value32, it_value.tv_sec);
+		CP(curr_value, curr_value32, it_value.tv_nsec);
+		CP(curr_value, curr_value32, it_interval.tv_sec);
+		CP(curr_value, curr_value32, it_interval.tv_nsec);
+		error = copyout(&curr_value32, uap->curr_value,
+		    sizeof(curr_value32));
+	}
+
+	return (error);
+}
+
+int
+freebsd32_timerfd_settime(struct thread *td,
+    struct freebsd32_timerfd_settime_args *uap)
+{
+	struct itimerspec new_value, old_value;
+	struct itimerspec32 new_value32, old_value32;
+	int error;
+
+	error = copyin(uap->new_value, &new_value32, sizeof(new_value32));
+	if (error != 0)
+		return (error);
+	CP(new_value32, new_value, it_value.tv_sec);
+	CP(new_value32, new_value, it_value.tv_nsec);
+	CP(new_value32, new_value, it_interval.tv_sec);
+	CP(new_value32, new_value, it_interval.tv_nsec);
+	if (uap->old_value == NULL) {
+		error = kern_timerfd_settime(td, uap->fd, uap->flags,
+		    &new_value, NULL);
+	} else {
+		error = kern_timerfd_settime(td, uap->fd, uap->flags,
+		    &new_value, &old_value);
+		if (error == 0) {
+			CP(old_value, old_value32, it_value.tv_sec);
+			CP(old_value, old_value32, it_value.tv_nsec);
+			CP(old_value, old_value32, it_interval.tv_sec);
+			CP(old_value, old_value32, it_interval.tv_nsec);
+			error = copyout(&old_value32, uap->old_value,
+			    sizeof(old_value32));
+		}
+	}
+	return (error);
+}
+
 int
 freebsd32_clock_getcpuclockid2(struct thread *td,
     struct freebsd32_clock_getcpuclockid2_args *uap)

--Multipart=_Sun__17_Sep_2023_09_39_50_+0900_e5eQYjc5MKn/Pcke--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20230917093950.0dbe3eefb1c34d61dea8adef>