mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-27 10:24:22 +03:00
Update the thread shim to use the current kernel threading API.
We need to use kthread_create() here for a few reasons. First off to old kernel_thread() API functioin will be going away. Secondly, and more importantly if I use kthread_create() we can then properly implement a thread_exit() function which terminates the kernel thread at any point with do_exit(). This fixes our cleanup bug which was caused by dropping a mutex twice after thread_exit() didn't really exit. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@66 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
parent
996faa6869
commit
968eccd1d1
@ -8,6 +8,7 @@ extern "C" {
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
@ -30,14 +31,14 @@ typedef void (*thread_func_t)(void *);
|
|||||||
|
|
||||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||||
__thread_create(stk, stksize, (thread_func_t)func, \
|
__thread_create(stk, stksize, (thread_func_t)func, \
|
||||||
arg, len, pp, state, pri)
|
#func, arg, len, pp, state, pri)
|
||||||
#define thread_exit() __thread_exit()
|
#define thread_exit() __thread_exit()
|
||||||
#define curthread get_current()
|
#define curthread get_current()
|
||||||
|
|
||||||
extern kthread_t *__thread_create(caddr_t stk, size_t stksize,
|
extern kthread_t *__thread_create(caddr_t stk, size_t stksize,
|
||||||
thread_func_t func, void *args,
|
thread_func_t func, const char *name,
|
||||||
size_t len, int *pp, int state,
|
void *args, size_t len, int *pp,
|
||||||
pri_t pri);
|
int state, pri_t pri);
|
||||||
extern void __thread_exit(void);
|
extern void __thread_exit(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -21,11 +21,6 @@ thread_generic_wrapper(void *arg)
|
|||||||
thread_priv_t *tp = (thread_priv_t *)arg;
|
thread_priv_t *tp = (thread_priv_t *)arg;
|
||||||
void (*func)(void *);
|
void (*func)(void *);
|
||||||
void *args;
|
void *args;
|
||||||
char name[16];
|
|
||||||
|
|
||||||
/* Use the truncated function name as thread name */
|
|
||||||
snprintf(name, sizeof(name), "%s", "kthread");
|
|
||||||
daemonize(name);
|
|
||||||
|
|
||||||
spin_lock(&tp->tp_lock);
|
spin_lock(&tp->tp_lock);
|
||||||
BUG_ON(tp->tp_magic != TP_MAGIC);
|
BUG_ON(tp->tp_magic != TP_MAGIC);
|
||||||
@ -51,6 +46,7 @@ thread_generic_wrapper(void *arg)
|
|||||||
void
|
void
|
||||||
__thread_exit(void)
|
__thread_exit(void)
|
||||||
{
|
{
|
||||||
|
do_exit(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__thread_exit);
|
EXPORT_SYMBOL(__thread_exit);
|
||||||
@ -60,11 +56,12 @@ EXPORT_SYMBOL(__thread_exit);
|
|||||||
* style callers likely never check for... since it can't fail. */
|
* style callers likely never check for... since it can't fail. */
|
||||||
kthread_t *
|
kthread_t *
|
||||||
__thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
__thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||||
void *args, size_t len, int *pp, int state, pri_t pri)
|
const char *name, void *args, size_t len, int *pp,
|
||||||
|
int state, pri_t pri)
|
||||||
{
|
{
|
||||||
thread_priv_t tp;
|
thread_priv_t tp;
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
long pid;
|
struct task_struct *tsk;
|
||||||
|
|
||||||
/* Option pp is simply ignored */
|
/* Option pp is simply ignored */
|
||||||
/* Variable stack size unsupported */
|
/* Variable stack size unsupported */
|
||||||
@ -88,9 +85,13 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
|||||||
|
|
||||||
spin_lock(&tp.tp_lock);
|
spin_lock(&tp.tp_lock);
|
||||||
|
|
||||||
/* Solaris says this must never fail so we try forever */
|
tsk = kthread_create(thread_generic_wrapper, (void *)&tp, "%s", name);
|
||||||
while ((pid = kernel_thread(thread_generic_wrapper, (void *)&tp, 0)) < 0)
|
if (IS_ERR(tsk)) {
|
||||||
printk(KERN_ERR "spl: Error unable to create thread; pid = %ld\n", pid);
|
printk("spl: Failed to create thread: %ld\n", PTR_ERR(tsk));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wake_up_process(tsk);
|
||||||
|
|
||||||
/* All signals are ignored due to sleeping TASK_UNINTERRUPTIBLE */
|
/* All signals are ignored due to sleeping TASK_UNINTERRUPTIBLE */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -103,9 +104,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
|||||||
spin_lock(&tp.tp_lock);
|
spin_lock(&tp.tp_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify the pid retunred matches the pid in the task struct */
|
BUG_ON(tsk != tp.tp_task); /* Extra paranoia */
|
||||||
BUG_ON(pid != (tp.tp_task)->pid);
|
|
||||||
|
|
||||||
spin_unlock(&tp.tp_lock);
|
spin_unlock(&tp.tp_lock);
|
||||||
|
|
||||||
return (kthread_t *)tp.tp_task;
|
return (kthread_t *)tp.tp_task;
|
||||||
|
Loading…
Reference in New Issue
Block a user