summaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linuxkpi')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/completion.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/device.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/fs.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/hrtimer.h79
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io-mapping.h53
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kernel.h3
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kobject.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/kthread.h31
-rw-r--r--sys/compat/linuxkpi/common/include/linux/ktime.h9
-rw-r--r--sys/compat/linuxkpi/common/include/linux/lockdep.h17
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm.h10
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm_types.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/module.h1
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h2
-rw-r--r--sys/compat/linuxkpi/common/src/linux_compat.c7
-rw-r--r--sys/compat/linuxkpi/common/src/linux_current.c3
-rw-r--r--sys/compat/linuxkpi/common/src/linux_hrtimer.c108
-rw-r--r--sys/compat/linuxkpi/common/src/linux_kthread.c59
18 files changed, 348 insertions, 48 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/completion.h b/sys/compat/linuxkpi/common/include/linux/completion.h
index 73c1a99dfc44..92ccc61f38da 100644
--- a/sys/compat/linuxkpi/common/include/linux/completion.h
+++ b/sys/compat/linuxkpi/common/include/linux/completion.h
@@ -32,7 +32,6 @@
#define _LINUX_COMPLETION_H_
#include <linux/errno.h>
-#include <linux/wait.h>
struct completion {
unsigned int done;
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h
index af69fa05e2e6..f868c32d5656 100644
--- a/sys/compat/linuxkpi/common/include/linux/device.h
+++ b/sys/compat/linuxkpi/common/include/linux/device.h
@@ -69,6 +69,7 @@ struct dev_pm_ops {
int (*freeze)(struct device *dev);
int (*freeze_late)(struct device *dev);
int (*thaw)(struct device *dev);
+ int (*thaw_early)(struct device *dev);
int (*poweroff)(struct device *dev);
int (*poweroff_late)(struct device *dev);
int (*restore)(struct device *dev);
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
index cc475ba2807e..ef5d1cc265e1 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -261,7 +261,15 @@ iput(struct inode *inode)
static inline loff_t
no_llseek(struct file *file, loff_t offset, int whence)
{
- return -ESPIPE;
+
+ return (-ESPIPE);
+}
+
+static inline loff_t
+noop_llseek(struct linux_file *file, loff_t offset, int whence)
+{
+
+ return (file->_file->f_offset);
}
#endif /* _LINUX_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/hrtimer.h b/sys/compat/linuxkpi/common/include/linux/hrtimer.h
new file mode 100644
index 000000000000..658a5407771e
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/hrtimer.h
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_HRTIMER_H_
+#define _LINUX_HRTIMER_H_
+
+#include <sys/_callout.h>
+#include <sys/_mutex.h>
+
+#include <linux/ktime.h>
+#include <linux/timer.h>
+
+enum hrtimer_mode {
+ HRTIMER_MODE_REL,
+};
+
+enum hrtimer_restart {
+ HRTIMER_RESTART,
+ HRTIMER_NORESTART,
+};
+
+struct hrtimer {
+ enum hrtimer_restart (*function)(struct hrtimer *);
+ struct mtx mtx;
+ struct callout callout;
+ uint32_t flags;
+};
+
+#define hrtimer_active(hrtimer) linux_hrtimer_active(hrtimer)
+#define hrtimer_cancel(hrtimer) linux_hrtimer_cancel(hrtimer)
+#define hrtimer_init(hrtimer, clock, mode) do { \
+ CTASSERT((clock) == CLOCK_MONOTONIC); \
+ CTASSERT((mode) == HRTIMER_MODE_REL); \
+ linux_hrtimer_init(hrtimer); \
+} while (0)
+#define hrtimer_set_expires(hrtimer, time) \
+ linux_hrtimer_set_expires(hrtimer, time)
+#define hrtimer_start(hrtimer, time, mode) do { \
+ CTASSERT((mode) == HRTIMER_MODE_REL); \
+ linux_hrtimer_start(hrtimer, time); \
+} while (0)
+#define hrtimer_start_range_ns(hrtimer, time, prec, mode) do { \
+ CTASSERT((mode) == HRTIMER_MODE_REL); \
+ linux_hrtimer_start_range_ns(hrtimer, time, prec); \
+} while (0)
+
+bool linux_hrtimer_active(struct hrtimer *);
+int linux_hrtimer_cancel(struct hrtimer *);
+void linux_hrtimer_init(struct hrtimer *);
+void linux_hrtimer_set_expires(struct hrtimer *, ktime_t);
+void linux_hrtimer_start(struct hrtimer *, ktime_t);
+void linux_hrtimer_start_range_ns(struct hrtimer *, ktime_t, int64_t);
+
+#endif /* _LINUX_HRTIMER_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/io-mapping.h b/sys/compat/linuxkpi/common/include/linux/io-mapping.h
index 8650dba65e6b..7c92c50d637a 100644
--- a/sys/compat/linuxkpi/common/include/linux/io-mapping.h
+++ b/sys/compat/linuxkpi/common/include/linux/io-mapping.h
@@ -28,52 +28,85 @@
*
* $FreeBSD$
*/
-#ifndef _LINUX_IO_MAPPING_H_
+
+#ifndef _LINUX_IO_MAPPING_H_
#define _LINUX_IO_MAPPING_H_
+#include <sys/types.h>
+#include <machine/vm.h>
+
#include <linux/types.h>
#include <linux/io.h>
+#include <linux/slab.h>
-struct io_mapping;
+struct io_mapping {
+ unsigned long base;
+ unsigned long size;
+ void *mem;
+ vm_memattr_t attr;
+};
+
+static inline struct io_mapping *
+io_mapping_init_wc(struct io_mapping *mapping, resource_size_t base,
+ unsigned long size)
+{
+
+ mapping->base = base;
+ mapping->size = size;
+ mapping->mem = ioremap_wc(base, size);
+ mapping->attr = VM_MEMATTR_WRITE_COMBINING;
+ return (mapping);
+}
static inline struct io_mapping *
io_mapping_create_wc(resource_size_t base, unsigned long size)
{
+ struct io_mapping *mapping;
- return ioremap_wc(base, size);
+ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
+ if (mapping == NULL)
+ return (NULL);
+ return (io_mapping_init_wc(mapping, base, size));
+}
+
+static inline void
+io_mapping_fini(struct io_mapping *mapping)
+{
+
+ iounmap(mapping->mem);
}
static inline void
io_mapping_free(struct io_mapping *mapping)
{
- iounmap(mapping);
+ io_mapping_fini(mapping->mem);
+ kfree(mapping);
}
static inline void *
io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
{
- return (((char *)mapping) + offset);
+ return ((char *)mapping->mem + offset);
}
static inline void
io_mapping_unmap_atomic(void *vaddr)
{
-
}
static inline void *
-io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
+io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset,
+ unsigned long size)
{
- return (((char *) mapping) + offset);
+ return ((char *)mapping->mem + offset);
}
static inline void
io_mapping_unmap(void *vaddr)
{
-
}
-#endif /* _LINUX_IO_MAPPING_H_ */
+#endif /* _LINUX_IO_MAPPING_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/kernel.h b/sys/compat/linuxkpi/common/include/linux/kernel.h
index 3631ba5f2428..c2641320871c 100644
--- a/sys/compat/linuxkpi/common/include/linux/kernel.h
+++ b/sys/compat/linuxkpi/common/include/linux/kernel.h
@@ -49,7 +49,6 @@
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/jiffies.h>
-#include <linux/wait.h>
#include <linux/log2.h>
#include <asm/byteorder.h>
@@ -261,6 +260,8 @@ scnprintf(char *buf, size_t size, const char *fmt, ...)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define u64_to_user_ptr(val) ((void *)(uintptr_t)(val))
+
static inline unsigned long long
simple_strtoull(const char *cp, char **endp, unsigned int base)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h
index a000c4eebc10..261f35539469 100644
--- a/sys/compat/linuxkpi/common/include/linux/kobject.h
+++ b/sys/compat/linuxkpi/common/include/linux/kobject.h
@@ -35,6 +35,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
+#include <linux/list.h>
#include <linux/slab.h>
struct kobject;
diff --git a/sys/compat/linuxkpi/common/include/linux/kthread.h b/sys/compat/linuxkpi/common/include/linux/kthread.h
index 8c7e3c899829..3afd21dc9356 100644
--- a/sys/compat/linuxkpi/common/include/linux/kthread.h
+++ b/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);
+
+#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)
-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 in_atomic() linux_in_atomic()
-#endif /* _LINUX_KTHREAD_H_ */
+#endif /* _LINUX_KTHREAD_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/ktime.h b/sys/compat/linuxkpi/common/include/linux/ktime.h
index 7c6c40fe1a8e..e2fd977a7cc5 100644
--- a/sys/compat/linuxkpi/common/include/linux/ktime.h
+++ b/sys/compat/linuxkpi/common/include/linux/ktime.h
@@ -51,6 +51,15 @@ ktime_to_ns(ktime_t kt)
return kt.tv64;
}
+static inline ktime_t
+ns_to_ktime(uint64_t nsec)
+{
+ ktime_t kt;
+
+ kt.tv64 = nsec;
+ return (kt);
+}
+
static inline int64_t
ktime_divns(const ktime_t kt, int64_t div)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/lockdep.h b/sys/compat/linuxkpi/common/include/linux/lockdep.h
index 27386935bbe6..ef562e300cd9 100644
--- a/sys/compat/linuxkpi/common/include/linux/lockdep.h
+++ b/sys/compat/linuxkpi/common/include/linux/lockdep.h
@@ -28,14 +28,23 @@
*
* $FreeBSD$
*/
-#ifndef _LINUX_LOCKDEP_H_
+
+#ifndef _LINUX_LOCKDEP_H_
#define _LINUX_LOCKDEP_H_
struct lock_class_key {
};
-#define lockdep_set_class(lock, key)
+#define lockdep_set_class(lock, key)
+
+#define lockdep_set_class_and_name(lock, key, name)
+
+#define lockdep_assert_held(m) \
+ sx_assert(&(m)->sx, SA_XLOCKED)
+
+#define lockdep_assert_held_once(m) \
+ sx_assert(&(m)->sx, SA_XLOCKED | SA_NOTRECURSED)
-#define lockdep_set_class_and_name(lock, key, name)
+#define lockdep_is_held(m) (sx_xholder(&(m)->sx) == curthread)
-#endif /* _LINUX_LOCKDEP_H_ */
+#endif /* _LINUX_LOCKDEP_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h
index 6f67a0ba4b41..c2ccb4cb96ad 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm.h
@@ -257,16 +257,6 @@ vm_get_page_prot(unsigned long vm_flags)
return (vm_flags & VM_PROT_ALL);
}
-extern int vm_insert_mixed(struct vm_area_struct *, unsigned long addr, pfn_t pfn);
-
-extern int
-vm_insert_pfn(struct vm_area_struct *, unsigned long addr,
- unsigned long pfn);
-
-extern int
-vm_insert_pfn_prot(struct vm_area_struct *, unsigned long addr,
- unsigned long pfn, pgprot_t pgprot);
-
static inline vm_page_t
vmalloc_to_page(const void *addr)
{
diff --git a/sys/compat/linuxkpi/common/include/linux/mm_types.h b/sys/compat/linuxkpi/common/include/linux/mm_types.h
index 6b13dfd9b62c..44aad34c9ba2 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm_types.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm_types.h
@@ -30,7 +30,6 @@
#define _LINUX_MM_TYPES_H_
#include <linux/types.h>
-#include <linux/list.h>
#include <linux/page.h>
#include <linux/rwsem.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/module.h b/sys/compat/linuxkpi/common/include/linux/module.h
index 59c30a7ab77c..13e5e0012d82 100644
--- a/sys/compat/linuxkpi/common/include/linux/module.h
+++ b/sys/compat/linuxkpi/common/include/linux/module.h
@@ -37,6 +37,7 @@
#include <linux/list.h>
#include <linux/compiler.h>
+#include <linux/kmod.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/moduleparam.h>
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index 01d44a0ce1e7..589c0f1e50db 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -37,7 +37,6 @@
#include <sys/sched.h>
#include <sys/sleepqueue.h>
-#include <linux/list.h>
#include <linux/compat.h>
#include <linux/completion.h>
#include <linux/pid.h>
@@ -55,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;
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
index 8df5de6329b6..a802ef999472 100644
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -497,7 +497,7 @@ linux_cdev_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type,
VM_OBJECT_WUNLOCK(vm_obj);
down_write(&vmap->vm_mm->mmap_sem);
- if (unlikely(vmap->vm_ops == NULL)) {
+ if (unlikely(vmap->vm_ops == NULL || vmap->vm_ops->fault == NULL)) {
err = VM_FAULT_SIGBUS;
} else {
vmap->vm_pfn_count = 0;
@@ -1173,8 +1173,7 @@ linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset,
if (vmap->vm_ops != NULL) {
void *vm_private_data;
- if (vmap->vm_ops->fault == NULL ||
- vmap->vm_ops->open == NULL ||
+ if (vmap->vm_ops->open == NULL ||
vmap->vm_ops->close == NULL ||
vmap->vm_private_data == NULL) {
linux_cdev_handle_free(vmap);
@@ -2027,6 +2026,8 @@ linux_compat_uninit(void *arg)
linux_kobject_kfree_name(&linux_root_device.kobj);
linux_kobject_kfree_name(&linux_class_misc.kobj);
+ mtx_destroy(&vmmaplock);
+ spin_lock_destroy(&pci_lock);
rw_destroy(&linux_vma_lock);
}
SYSUNINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_uninit, NULL);
diff --git a/sys/compat/linuxkpi/common/src/linux_current.c b/sys/compat/linuxkpi/common/src/linux_current.c
index f64c8c731947..f0d1e199e816 100644
--- a/sys/compat/linuxkpi/common/src/linux_current.c
+++ b/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 @@ 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;
diff --git a/sys/compat/linuxkpi/common/src/linux_hrtimer.c b/sys/compat/linuxkpi/common/src/linux_hrtimer.c
new file mode 100644
index 000000000000..42b2a9f978d3
--- /dev/null
+++ b/sys/compat/linuxkpi/common/src/linux_hrtimer.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/time.h>
+
+#include <machine/cpu.h>
+
+#include <linux/hrtimer.h>
+
+/* hrtimer flags */
+#define HRTIMER_ACTIVE 0x01
+
+static void
+hrtimer_call_handler(void *arg)
+{
+ struct hrtimer *hrtimer;
+ enum hrtimer_restart ret;
+
+ hrtimer = arg;
+ ret = hrtimer->function(hrtimer);
+ MPASS(ret == HRTIMER_NORESTART);
+ hrtimer->flags &= ~HRTIMER_ACTIVE;
+}
+
+bool
+linux_hrtimer_active(struct hrtimer *hrtimer)
+{
+ bool ret;
+
+ mtx_lock(&hrtimer->mtx);
+ ret = (hrtimer->flags & HRTIMER_ACTIVE) != 0;
+ mtx_unlock(&hrtimer->mtx);
+ return (ret);
+}
+
+int
+linux_hrtimer_cancel(struct hrtimer *hrtimer)
+{
+
+ if (!hrtimer_active(hrtimer))
+ return (0);
+ (void)callout_drain(&hrtimer->callout);
+ return (1);
+}
+
+void
+linux_hrtimer_init(struct hrtimer *hrtimer)
+{
+
+ hrtimer->function = NULL;
+ hrtimer->flags = 0;
+ mtx_init(&hrtimer->mtx, "hrtimer", NULL, MTX_DEF | MTX_RECURSE);
+ callout_init_mtx(&hrtimer->callout, &hrtimer->mtx, 0);
+}
+
+void
+linux_hrtimer_set_expires(struct hrtimer *hrtimer __unused,
+ ktime_t time __unused)
+{
+}
+
+void
+linux_hrtimer_start(struct hrtimer *hrtimer, ktime_t time)
+{
+
+ linux_hrtimer_start_range_ns(hrtimer, time, 0);
+}
+
+void
+linux_hrtimer_start_range_ns(struct hrtimer *hrtimer, ktime_t time, int64_t nsec)
+{
+
+ mtx_lock(&hrtimer->mtx);
+ callout_reset_sbt(&hrtimer->callout, time.tv64 * SBT_1NS,
+ nsec * SBT_1NS, hrtimer_call_handler, hrtimer, 0);
+ hrtimer->flags |= HRTIMER_ACTIVE;
+ mtx_unlock(&hrtimer->mtx);
+}
diff --git a/sys/compat/linuxkpi/common/src/linux_kthread.c b/sys/compat/linuxkpi/common/src/linux_kthread.c
index aa24e30d61f2..198082615076 100644
--- a/sys/compat/linuxkpi/common/src/linux_kthread.c
+++ b/sys/compat/linuxkpi/common/src/linux_kthread.c
@@ -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(&current->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();
}
-