Date: Sun, 18 Jun 2017 19:22:05 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320078 - in head/sys/compat/linuxkpi/common: include/linux src Message-ID: <201706181922.v5IJM5x2007763@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Sun Jun 18 19:22:05 2017 New Revision: 320078 URL: https://svnweb.freebsd.org/changeset/base/320078 Log: Add kthread parking support to the LinuxKPI. Submitted by: kmacy (original version) Reviewed by: hselasky MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D11264 Modified: head/sys/compat/linuxkpi/common/include/linux/kthread.h head/sys/compat/linuxkpi/common/include/linux/sched.h head/sys/compat/linuxkpi/common/src/linux_current.c head/sys/compat/linuxkpi/common/src/linux_kthread.c Modified: head/sys/compat/linuxkpi/common/include/linux/kthread.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/kthread.h Sun Jun 18 18:23:39 2017 (r320077) +++ head/sys/compat/linuxkpi/common/include/linux/kthread.h Sun Jun 18 19:22:05 2017 (r320078) @@ -48,15 +48,26 @@ __task; \ }) -#define in_atomic() ({ \ - linux_in_atomic(); \ -}) +int linux_kthread_stop(struct task_struct *); +bool linux_kthread_should_stop_task(struct task_struct *); +bool linux_kthread_should_stop(void); +int linux_kthread_park(struct task_struct *); +void linux_kthread_parkme(void); +bool linux_kthread_should_park(void); +void linux_kthread_unpark(struct task_struct *); +void linux_kthread_fn(void *); +struct task_struct *linux_kthread_setup_and_run(struct thread *, + linux_task_fn_t *, void *arg); +int linux_in_atomic(void); -extern int kthread_stop(struct task_struct *); -extern bool kthread_should_stop_task(struct task_struct *); -extern bool kthread_should_stop(void); -extern void linux_kthread_fn(void *); -extern struct task_struct *linux_kthread_setup_and_run(struct thread *, linux_task_fn_t *, void *arg); -extern int linux_in_atomic(void); +#define kthread_stop(task) linux_kthread_stop(task) +#define kthread_should_stop() linux_kthread_should_stop() +#define kthread_should_stop_task(task) linux_kthread_should_stop_task(task) +#define kthread_park(task) linux_kthread_park(task) +#define kthread_parkme() linux_kthread_parkme() +#define kthread_should_park() linux_kthread_should_park() +#define kthread_unpark(task) linux_kthread_unpark(task) -#endif /* _LINUX_KTHREAD_H_ */ +#define in_atomic() linux_in_atomic() + +#endif /* _LINUX_KTHREAD_H_ */ Modified: head/sys/compat/linuxkpi/common/include/linux/sched.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/sched.h Sun Jun 18 18:23:39 2017 (r320077) +++ head/sys/compat/linuxkpi/common/include/linux/sched.h Sun Jun 18 19:22:05 2017 (r320078) @@ -54,6 +54,7 @@ #define TASK_UNINTERRUPTIBLE 0x0002 #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) #define TASK_WAKING 0x0100 +#define TASK_PARKED 0x0200 struct task_struct { struct thread *task_thread; Modified: head/sys/compat/linuxkpi/common/src/linux_current.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_current.c Sun Jun 18 18:23:39 2017 (r320077) +++ head/sys/compat/linuxkpi/common/src/linux_current.c Sun Jun 18 19:22:05 2017 (r320078) @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include <linux/compat.h> +#include <linux/completion.h> #include <linux/mm.h> #include <linux/kthread.h> @@ -68,6 +69,8 @@ linux_alloc_current(struct thread *td, int flags) ts->pid = td->td_tid; atomic_set(&ts->usage, 1); ts->state = TASK_RUNNING; + init_completion(&ts->parked); + init_completion(&ts->exited); proc = td->td_proc; Modified: head/sys/compat/linuxkpi/common/src/linux_kthread.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_kthread.c Sun Jun 18 18:23:39 2017 (r320077) +++ head/sys/compat/linuxkpi/common/src/linux_kthread.c Sun Jun 18 19:22:05 2017 (r320078) @@ -43,21 +43,21 @@ enum { }; bool -kthread_should_stop_task(struct task_struct *task) +linux_kthread_should_stop_task(struct task_struct *task) { return (atomic_read(&task->kthread_flags) & KTHREAD_SHOULD_STOP_MASK); } bool -kthread_should_stop(void) +linux_kthread_should_stop(void) { return (atomic_read(¤t->kthread_flags) & KTHREAD_SHOULD_STOP_MASK); } int -kthread_stop(struct task_struct *task) +linux_kthread_stop(struct task_struct *task) { int retval; @@ -66,6 +66,7 @@ kthread_stop(struct task_struct *task) * kthread_stop(): */ atomic_or(KTHREAD_SHOULD_STOP_MASK, &task->kthread_flags); + kthread_unpark(task); wake_up_process(task); wait_for_completion(&task->exited); @@ -78,6 +79,53 @@ kthread_stop(struct task_struct *task) return (retval); } +int +linux_kthread_park(struct task_struct *task) +{ + + atomic_or(KTHREAD_SHOULD_PARK_MASK, &task->kthread_flags); + wake_up_process(task); + wait_for_completion(&task->parked); + return (0); +} + +void +linux_kthread_parkme(void) +{ + struct task_struct *task; + + task = current; + set_task_state(task, TASK_PARKED | TASK_UNINTERRUPTIBLE); + while (linux_kthread_should_park()) { + while ((atomic_fetch_or(KTHREAD_IS_PARKED_MASK, + &task->kthread_flags) & KTHREAD_IS_PARKED_MASK) == 0) + complete(&task->parked); + schedule(); + set_task_state(task, TASK_PARKED | TASK_UNINTERRUPTIBLE); + } + atomic_andnot(KTHREAD_IS_PARKED_MASK, &task->kthread_flags); + set_task_state(task, TASK_RUNNING); +} + +bool +linux_kthread_should_park(void) +{ + struct task_struct *task; + + task = current; + return (atomic_read(&task->kthread_flags) & KTHREAD_SHOULD_PARK_MASK); +} + +void +linux_kthread_unpark(struct task_struct *task) +{ + + atomic_andnot(KTHREAD_SHOULD_PARK_MASK, &task->kthread_flags); + if ((atomic_fetch_andnot(KTHREAD_IS_PARKED_MASK, &task->kthread_flags) & + KTHREAD_IS_PARKED_MASK) != 0) + wake_up_state(task, TASK_PARKED); +} + struct task_struct * linux_kthread_setup_and_run(struct thread *td, linux_task_fn_t *task_fn, void *arg) { @@ -104,10 +152,10 @@ linux_kthread_fn(void *arg __unused) { struct task_struct *task = current; - if (kthread_should_stop_task(task) == 0) + if (linux_kthread_should_stop_task(task) == 0) task->task_ret = task->task_fn(task->task_data); - if (kthread_should_stop_task(task) != 0) { + if (linux_kthread_should_stop_task(task) != 0) { struct thread *td = curthread; /* let kthread_stop() free data */ @@ -118,4 +166,3 @@ linux_kthread_fn(void *arg __unused) } kthread_exit(); } -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706181922.v5IJM5x2007763>