Index: head/sys/compat/linuxkpi/common/include/linux/pid.h =================================================================== --- head/sys/compat/linuxkpi/common/include/linux/pid.h (nonexistent) +++ head/sys/compat/linuxkpi/common/include/linux/pid.h (revision 315457) @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2017 Mellanox Technologies, Ltd. + * 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_PID_H_ +#define _LINUX_PID_H_ + +#include +#include +#include + +enum pid_type { + PIDTYPE_PID, + PIDTYPE_PGID, + PIDTYPE_SID, + PIDTYPE_MAX +}; + +#define pid_nr(n) (n) +#define pid_vnr(n) (n) +#define from_kuid_munged(a, uid) (uid) + +#define pid_task(pid, type) ({ \ + struct task_struct *__ts; \ + CTASSERT((type) == PIDTYPE_PID); \ + __ts = linux_pid_task(pid); \ + __ts; \ +}) + +#define get_pid_task(pid, type) ({ \ + struct task_struct *__ts; \ + CTASSERT((type) == PIDTYPE_PID); \ + __ts = linux_get_pid_task(pid); \ + __ts; \ +}) + +struct task_struct; +extern struct task_struct *linux_pid_task(pid_t); +extern struct task_struct *linux_get_pid_task(pid_t); + +#endif /* _LINUX_PID_H_ */ Property changes on: head/sys/compat/linuxkpi/common/include/linux/pid.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/compat/linuxkpi/common/include/linux/sched.h =================================================================== --- head/sys/compat/linuxkpi/common/include/linux/sched.h (revision 315456) +++ head/sys/compat/linuxkpi/common/include/linux/sched.h (revision 315457) @@ -1,132 +1,149 @@ /*- * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2017 Mellanox Technologies, Ltd. * 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_SCHED_H_ #define _LINUX_SCHED_H_ #include #include #include #include #include #include +#include #include +#include #include #include #include #define MAX_SCHEDULE_TIMEOUT LONG_MAX #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 #define TASK_DEAD 64 #define TASK_WAKEKILL 128 #define TASK_WAKING 256 struct task_struct { struct thread *task_thread; struct mm_struct *mm; linux_task_fn_t *task_fn; void *task_data; int task_ret; + atomic_t usage; int state; atomic_t kthread_flags; - pid_t pid; + pid_t pid; /* BSD thread ID */ const char *comm; void *bsd_ioctl_data; unsigned bsd_ioctl_len; struct completion parked; struct completion exited; }; #define current ((struct task_struct *)curthread->td_lkpi_task) -#define task_pid(task) ((task)->task_thread->td_proc->p_pid) -#define task_pid_nr(task) ((task)->task_thread->td_tid) -#define get_pid(x) (x) -#define put_pid(x) +#define task_pid_group_leader(task) \ + FIRST_THREAD_IN_PROC((task)->task_thread->td_proc)->td_tid +#define task_pid(task) ((task)->pid) +#define task_pid_nr(task) ((task)->pid) +#define get_pid(x) (x) +#define put_pid(x) do { } while (0) #define current_euid() (curthread->td_ucred->cr_uid) #define set_current_state(x) \ atomic_store_rel_int((volatile int *)¤t->state, (x)) #define __set_current_state(x) current->state = (x) +static inline void +get_task_struct(struct task_struct *task) +{ + atomic_inc(&task->usage); +} + +static inline void +put_task_struct(struct task_struct *task) +{ + if (atomic_dec_and_test(&task->usage)) + linux_free_current(task); +} #define schedule() \ do { \ void *c; \ \ if (cold || SCHEDULER_STOPPED()) \ break; \ c = curthread; \ sleepq_lock(c); \ if (current->state == TASK_INTERRUPTIBLE || \ current->state == TASK_UNINTERRUPTIBLE) { \ sleepq_add(c, NULL, "task", SLEEPQ_SLEEP, 0); \ sleepq_wait(c, 0); \ } else { \ sleepq_release(c); \ sched_relinquish(curthread); \ } \ } while (0) #define wake_up_process(x) \ do { \ int wakeup_swapper; \ void *c; \ \ c = (x)->task_thread; \ sleepq_lock(c); \ (x)->state = TASK_RUNNING; \ wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0); \ sleepq_release(c); \ if (wakeup_swapper) \ kick_proc0(); \ } while (0) #define cond_resched() if (!cold) sched_relinquish(curthread) #define sched_yield() sched_relinquish(curthread) static inline long schedule_timeout(signed long timeout) { if (timeout < 0) return 0; pause("lstim", timeout); return 0; } #endif /* _LINUX_SCHED_H_ */ Index: head/sys/compat/linuxkpi/common/src/linux_current.c =================================================================== --- head/sys/compat/linuxkpi/common/src/linux_current.c (revision 315456) +++ head/sys/compat/linuxkpi/common/src/linux_current.c (revision 315457) @@ -1,132 +1,163 @@ /*- * Copyright (c) 2017 Hans Petter Selasky * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include static eventhandler_tag linuxkpi_thread_dtor_tag; static MALLOC_DEFINE(M_LINUX_CURRENT, "linuxcurrent", "LinuxKPI task structure"); int linux_alloc_current(struct thread *td, int flags) { struct task_struct *ts; struct mm_struct *mm; MPASS(td->td_lkpi_task == NULL); ts = malloc(sizeof(*ts), M_LINUX_CURRENT, flags | M_ZERO); if (ts == NULL) return (ENOMEM); mm = malloc(sizeof(*mm), M_LINUX_CURRENT, flags | M_ZERO); if (mm == NULL) { free(ts, M_LINUX_CURRENT); return (ENOMEM); } atomic_set(&ts->kthread_flags, 0); ts->task_thread = td; ts->comm = td->td_name; ts->pid = td->td_tid; ts->mm = mm; + atomic_set(&ts->usage, 1); ts->state = TASK_RUNNING; /* setup mm_struct */ init_rwsem(&mm->mmap_sem); atomic_set(&mm->mm_count, 1); atomic_set(&mm->mm_users, 1); mm->vmspace = vmspace_acquire_ref(td->td_proc); /* store pointer to task struct */ td->td_lkpi_task = ts; return (0); } struct mm_struct * linux_get_task_mm(struct task_struct *task) { struct mm_struct *mm; mm = task->mm; if (mm != NULL && mm->vmspace != NULL) { atomic_inc(&mm->mm_users); return (mm); } return (NULL); } void linux_mm_dtor(struct mm_struct *mm) { if (mm->vmspace != NULL) vmspace_free(mm->vmspace); free(mm, M_LINUX_CURRENT); } void linux_free_current(struct task_struct *ts) { mmput(ts->mm); free(ts, M_LINUX_CURRENT); } static void linuxkpi_thread_dtor(void *arg __unused, struct thread *td) { struct task_struct *ts; ts = td->td_lkpi_task; if (ts == NULL) return; td->td_lkpi_task = NULL; - linux_free_current(ts); + put_task_struct(ts); +} + +struct task_struct * +linux_pid_task(pid_t pid) +{ + struct thread *td; + + td = tdfind(pid, -1); + if (td != NULL) { + struct task_struct *ts = td->td_lkpi_task; + PROC_UNLOCK(td->td_proc); + return (ts); + } + return (NULL); +} + +struct task_struct * +linux_get_pid_task(pid_t pid) +{ + struct thread *td; + + td = tdfind(pid, -1); + if (td != NULL) { + struct task_struct *ts = td->td_lkpi_task; + if (ts != NULL) + get_task_struct(ts); + PROC_UNLOCK(td->td_proc); + return (ts); + } + return (NULL); } static void linux_current_init(void *arg __unused) { linuxkpi_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, linuxkpi_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); } SYSINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_init, NULL); static void linux_current_uninit(void *arg __unused) { EVENTHANDLER_DEREGISTER(thread_dtor, linuxkpi_thread_dtor_tag); } SYSUNINIT(linux_current, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_current_uninit, NULL); Index: head/sys/compat/linuxkpi/common/src/linux_kthread.c =================================================================== --- head/sys/compat/linuxkpi/common/src/linux_kthread.c (revision 315456) +++ head/sys/compat/linuxkpi/common/src/linux_kthread.c (revision 315457) @@ -1,120 +1,120 @@ /*- * Copyright (c) 2017 Hans Petter Selasky * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include enum { KTHREAD_SHOULD_STOP_MASK = (1 << 0), KTHREAD_SHOULD_PARK_MASK = (1 << 1), KTHREAD_IS_PARKED_MASK = (1 << 2), }; bool kthread_should_stop_task(struct task_struct *task) { return (atomic_read(&task->kthread_flags) & KTHREAD_SHOULD_STOP_MASK); } bool kthread_should_stop(void) { return (atomic_read(¤t->kthread_flags) & KTHREAD_SHOULD_STOP_MASK); } int kthread_stop(struct task_struct *task) { int retval; /* * Assume task is still alive else caller should not call * kthread_stop(): */ atomic_or(KTHREAD_SHOULD_STOP_MASK, &task->kthread_flags); wake_up_process(task); wait_for_completion(&task->exited); /* * Get return code and free task structure: */ retval = task->task_ret; - linux_free_current(task); + put_task_struct(task); return (retval); } struct task_struct * linux_kthread_setup_and_run(struct thread *td, linux_task_fn_t *task_fn, void *arg) { struct task_struct *task; linux_set_current(td); task = td->td_lkpi_task; task->task_fn = task_fn; task->task_data = arg; thread_lock(td); /* make sure the scheduler priority is raised */ sched_prio(td, PI_SWI(SWI_NET)); /* put thread into run-queue */ sched_add(td, SRQ_BORING); thread_unlock(td); return (task); } void linux_kthread_fn(void *arg __unused) { struct task_struct *task = current; if (kthread_should_stop_task(task) == 0) task->task_ret = task->task_fn(task->task_data); if (kthread_should_stop_task(task) != 0) { struct thread *td = curthread; /* let kthread_stop() free data */ td->td_lkpi_task = NULL; /* wakeup kthread_stop() */ complete(&task->exited); } kthread_exit(); }