Skip to content

Instantly share code, notes, and snippets.

@tuxoko
Created November 30, 2015 21:43
Show Gist options
  • Save tuxoko/45c0686cfe845552e792 to your computer and use it in GitHub Desktop.
Save tuxoko/45c0686cfe845552e792 to your computer and use it in GitHub Desktop.
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