Created
November 30, 2015 21:43
-
-
Save tuxoko/45c0686cfe845552e792 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/sys/taskq.h b/include/sys/taskq.h | |
index a43a86d..6d3e6d6 100644 | |
--- a/include/sys/taskq.h | |
+++ b/include/sys/taskq.h | |
@@ -124,7 +124,7 @@ extern void taskq_wait_id(taskq_t *, taskqid_t); | |
extern void taskq_wait_outstanding(taskq_t *, taskqid_t); | |
extern void taskq_wait(taskq_t *); | |
extern int taskq_cancel_id(taskq_t *, taskqid_t); | |
-extern int taskq_member(taskq_t *, void *); | |
+extern int taskq_member(taskq_t *, kthread_t *); | |
#define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \ | |
taskq_create(name, nthreads, pri, min, max, flags) | |
diff --git a/include/sys/tsd.h b/include/sys/tsd.h | |
index ebc55b0..1894a82 100644 | |
--- a/include/sys/tsd.h | |
+++ b/include/sys/tsd.h | |
@@ -35,6 +35,7 @@ typedef void (*dtor_func_t)(void *); | |
extern int tsd_set(uint_t, void *); | |
extern void *tsd_get(uint_t); | |
+extern void *tsd_get_by_thread(uint_t, kthread_t *); | |
extern void tsd_create(uint_t *, dtor_func_t); | |
extern void tsd_destroy(uint_t *); | |
extern void tsd_exit(void); | |
diff --git a/module/spl/spl-generic.c b/module/spl/spl-generic.c | |
index 4d9846c..a5b7a13 100644 | |
--- a/module/spl/spl-generic.c | |
+++ b/module/spl/spl-generic.c | |
@@ -532,19 +532,19 @@ spl_init(void) | |
if ((rc = spl_rw_init())) | |
goto out3; | |
- if ((rc = spl_taskq_init())) | |
+ if ((rc = spl_tsd_init())) | |
goto out4; | |
- if ((rc = spl_vn_init())) | |
+ if ((rc = spl_taskq_init())) | |
goto out5; | |
- if ((rc = spl_proc_init())) | |
+ if ((rc = spl_vn_init())) | |
goto out6; | |
- if ((rc = spl_kstat_init())) | |
+ if ((rc = spl_proc_init())) | |
goto out7; | |
- if ((rc = spl_tsd_init())) | |
+ if ((rc = spl_kstat_init())) | |
goto out8; | |
if ((rc = spl_zlib_init())) | |
@@ -555,15 +555,15 @@ spl_init(void) | |
return (rc); | |
out9: | |
- spl_tsd_fini(); | |
-out8: | |
spl_kstat_fini(); | |
-out7: | |
+out8: | |
spl_proc_fini(); | |
-out6: | |
+out7: | |
spl_vn_fini(); | |
-out5: | |
+out6: | |
spl_taskq_fini(); | |
+out5: | |
+ spl_tsd_fini(); | |
out4: | |
spl_rw_fini(); | |
out3: | |
@@ -584,11 +584,11 @@ spl_fini(void) | |
printk(KERN_NOTICE "SPL: Unloaded module v%s-%s%s\n", | |
SPL_META_VERSION, SPL_META_RELEASE, SPL_DEBUG_STR); | |
spl_zlib_fini(); | |
- spl_tsd_fini(); | |
spl_kstat_fini(); | |
spl_proc_fini(); | |
spl_vn_fini(); | |
spl_taskq_fini(); | |
+ spl_tsd_fini(); | |
spl_rw_fini(); | |
spl_mutex_fini(); | |
spl_kvmem_fini(); | |
diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c | |
index 2c2e3ad..5d053b7 100644 | |
--- a/module/spl/spl-taskq.c | |
+++ b/module/spl/spl-taskq.c | |
@@ -26,6 +26,7 @@ | |
#include <sys/taskq.h> | |
#include <sys/kmem.h> | |
+#include <sys/tsd.h> | |
int spl_taskq_thread_bind = 0; | |
module_param(spl_taskq_thread_bind, int, 0644); | |
@@ -54,6 +55,8 @@ EXPORT_SYMBOL(system_taskq); | |
static taskq_t *dynamic_taskq; | |
static taskq_thread_t *taskq_thread_create(taskq_t *); | |
+static uint_t taskq_tsd; | |
+ | |
static int | |
task_km_flags(uint_t flags) | |
{ | |
@@ -448,37 +451,10 @@ taskq_wait(taskq_t *tq) | |
} | |
EXPORT_SYMBOL(taskq_wait); | |
-static int | |
-taskq_member_impl(taskq_t *tq, void *t) | |
-{ | |
- struct list_head *l; | |
- taskq_thread_t *tqt; | |
- int found = 0; | |
- | |
- ASSERT(tq); | |
- ASSERT(t); | |
- ASSERT(spin_is_locked(&tq->tq_lock)); | |
- | |
- list_for_each(l, &tq->tq_thread_list) { | |
- tqt = list_entry(l, taskq_thread_t, tqt_thread_list); | |
- if (tqt->tqt_thread == (struct task_struct *)t) { | |
- found = 1; | |
- break; | |
- } | |
- } | |
- return (found); | |
-} | |
- | |
int | |
-taskq_member(taskq_t *tq, void *t) | |
+taskq_member(taskq_t *tq, kthread_t *t) | |
{ | |
- int found; | |
- | |
- spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); | |
- found = taskq_member_impl(tq, t); | |
- spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); | |
- | |
- return (found); | |
+ return (tq == (taskq_t *)tsd_get_by_thread(taskq_tsd, t)); | |
} | |
EXPORT_SYMBOL(taskq_member); | |
@@ -821,6 +797,8 @@ taskq_thread(void *args) | |
sigprocmask(SIG_BLOCK, &blocked, NULL); | |
flush_signals(current); | |
+ tsd_set(taskq_tsd, tq); | |
+ | |
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags); | |
/* Immediately exit if more threads than allowed were created. */ | |
@@ -917,6 +895,8 @@ error: | |
kmem_free(tqt, sizeof (taskq_thread_t)); | |
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags); | |
+ tsd_set(taskq_tsd, NULL); | |
+ | |
return (0); | |
} | |
@@ -1101,6 +1081,8 @@ EXPORT_SYMBOL(taskq_destroy); | |
int | |
spl_taskq_init(void) | |
{ | |
+ tsd_create(&taskq_tsd, NULL); | |
+ | |
system_taskq = taskq_create("spl_system_taskq", MAX(boot_ncpus, 64), | |
maxclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC); | |
if (system_taskq == NULL) | |
@@ -1124,4 +1106,6 @@ spl_taskq_fini(void) | |
taskq_destroy(system_taskq); | |
system_taskq = NULL; | |
+ | |
+ tsd_destroy(&taskq_tsd); | |
} | |
diff --git a/module/spl/spl-tsd.c b/module/spl/spl-tsd.c | |
index 4d0800e..1d06e2b 100644 | |
--- a/module/spl/spl-tsd.c | |
+++ b/module/spl/spl-tsd.c | |
@@ -528,6 +528,33 @@ tsd_get(uint_t key) | |
EXPORT_SYMBOL(tsd_get); | |
/* | |
+ * tsd_get_thread - get thread specific data for specified thread | |
+ * @key: lookup key | |
+ * @thread: thread to lookup | |
+ * | |
+ * Caller must prevent racing tsd_create() or tsd_destroy(). This | |
+ * implementation is designed to be fast and scalable, it does not | |
+ * lock the entire table only a single hash bin. | |
+ */ | |
+void * | |
+tsd_get_by_thread(uint_t key, kthread_t *thread) | |
+{ | |
+ tsd_hash_entry_t *entry; | |
+ | |
+ ASSERT3P(tsd_hash_table, !=, NULL); | |
+ | |
+ if ((key == 0) || (key > TSD_KEYS_MAX)) | |
+ return (NULL); | |
+ | |
+ entry = tsd_hash_search(tsd_hash_table, key, thread->pid); | |
+ if (entry == NULL) | |
+ return (NULL); | |
+ | |
+ return (entry->he_value); | |
+} | |
+EXPORT_SYMBOL(tsd_get_by_thread); | |
+ | |
+/* | |
* tsd_create - create thread specific data key | |
* @keyp: lookup key address | |
* @dtor: destructor called during tsd_destroy() or tsd_exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment