diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index 8ed7f125f..08d939f09 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -37,6 +37,7 @@ nvgpu-y := \
common/linux/soc.o \
common/linux/driver_common.o \
common/linux/firmware.o \
+ common/linux/thread.o \
common/mm/nvgpu_allocator.o \
common/mm/bitmap_allocator.o \
common/mm/buddy_allocator.o \
diff --git a/drivers/gpu/nvgpu/common/linux/thread.c b/drivers/gpu/nvgpu/common/linux/thread.c
new file mode 100644
index 000000000..d37b2a10b
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/thread.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+
+int nvgpu_thread_create(struct nvgpu_thread *thread,
+ void *data,
+ int (*threadfn)(void *data), const char *name)
+{
+ struct task_struct *task = kthread_create(threadfn, data, name);
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+
+ thread->task = task;
+ wake_up_process(task);
+ return 0;
+};
+
+void nvgpu_thread_stop(struct nvgpu_thread *thread)
+{
+ kthread_stop(thread->task);
+};
+
+bool nvgpu_thread_should_stop(struct nvgpu_thread *thread)
+{
+ return kthread_should_stop();
+};
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/thread.h b/drivers/gpu/nvgpu/include/nvgpu/linux/thread.h
new file mode 100644
index 000000000..13f295157
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/linux/thread.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __NVGPU_THREAD_LINUX_H__
+#define __NVGPU_THREAD_LINUX_H__
+
+struct task_struct;
+
+struct nvgpu_thread {
+ struct task_struct *task;
+};
+
+#endif /* __NVGPU_THREAD_LINUX_H__ */
diff --git a/drivers/gpu/nvgpu/include/nvgpu/thread.h b/drivers/gpu/nvgpu/include/nvgpu/thread.h
new file mode 100644
index 000000000..81dac7ca2
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/thread.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __NVGPU_THREAD_H__
+#define __NVGPU_THREAD_H__
+
+#ifdef __KERNEL__
+#include
+#endif
+
+/**
+ * nvgpu_thread_create - Create and run a new thread.
+ *
+ * @thread - thread structure to use
+ * @data - data to pass to threadfn
+ * @threadfn - Thread function
+ * @name - name of the thread
+ *
+ * Create a thread and run threadfn in it. The thread stays alive as long as
+ * threadfn is running. As soon as threadfn returns the thread is destroyed.
+ *
+ * threadfn needs to continuously poll nvgpu_thread_should_stop() to determine
+ * if it should exit.
+ */
+int nvgpu_thread_create(struct nvgpu_thread *thread,
+ void *data,
+ int (*threadfn)(void *data), const char *name);
+
+/**
+ * nvgpu_thread_stop - Destroy or request to destroy a thread
+ *
+ * @thread - thread to stop
+ *
+ * Request a thread to stop by setting nvgpu_thread_should_stop() to
+ * true and wait for thread to exit.
+ */
+void nvgpu_thread_stop(struct nvgpu_thread *thread);
+
+/**
+ * nvgpu_thread_should_stop - Query if thread should stop
+ *
+ * @thread
+ *
+ * Return true if thread should exit. Can be run only in the thread's own
+ * context and with the thread as parameter.
+ */
+bool nvgpu_thread_should_stop(struct nvgpu_thread *thread);
+
+#endif /* __NVGPU_THREAD_H__ */