Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105743939
D11264.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D11264.id.diff
View Options
Index: head/sys/compat/linuxkpi/common/include/linux/kthread.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/kthread.h
+++ head/sys/compat/linuxkpi/common/include/linux/kthread.h
@@ -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_ */
Index: head/sys/compat/linuxkpi/common/include/linux/sched.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/sched.h
+++ head/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -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;
Index: head/sys/compat/linuxkpi/common/src/linux_current.c
===================================================================
--- head/sys/compat/linuxkpi/common/src/linux_current.c
+++ head/sys/compat/linuxkpi/common/src/linux_current.c
@@ -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 @@
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;
Index: head/sys/compat/linuxkpi/common/src/linux_kthread.c
===================================================================
--- head/sys/compat/linuxkpi/common/src/linux_kthread.c
+++ head/sys/compat/linuxkpi/common/src/linux_kthread.c
@@ -43,21 +43,21 @@
};
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():
*/
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 @@
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 @@
{
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 @@
}
kthread_exit();
}
-
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 12:44 AM (16 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15536548
Default Alt Text
D11264.id.diff (5 KB)
Attached To
Mode
D11264: Implement kthread parking support in the LinuxKPI
Attached
Detach File
Event Timeline
Log In to Comment