path: root/sys/compat/linuxkpi/common/include
diff options
authorHans Petter Selasky <hselasky@FreeBSD.org>2017-04-19 13:03:29 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2017-04-19 13:03:29 +0000
commitf3de9af63337e182649a4272828be3568153f454 (patch)
treee04fbdf58cc5c9dbea9200b48ab925dc9ca417f5 /sys/compat/linuxkpi/common/include
parent85ee43171a1a179f6e27ba365da76532111ba2a5 (diff)
Fix problem regarding priority inversion when using the concurrency
kit, CK, in the LinuxKPI. When threads are pinned to a CPU core or when there is only one CPU, it can happen that a higher priority thread can call the CK synchronize function while a lower priority thread holds the read lock. Because the CK's synchronize is a simple wait loop this can lead to a deadlock situation. To solve this problem use the recently introduced CK's wait callback function. When detecting a CK blocking condition figure out the lowest priority among the blockers and update the calling thread's priority and yield. If another CPU core is holding the read lock, pin the thread to the blocked CPU core and update the priority. The calling threads priority and CPU bindings are restored before return. If a thread holding a CK read lock is detected to be sleeping, pause() will be used instead of yield(). MFC after: 1 week Sponsored by: Mellanox Technologies
Notes: svn path=/head/; revision=317137
Diffstat (limited to 'sys/compat/linuxkpi/common/include')
2 files changed, 3 insertions, 3 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index 4de6f9e28238..59900c12ab1d 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -37,7 +37,7 @@
#include <sys/sched.h>
#include <sys/sleepqueue.h>
-#include <linux/types.h>
+#include <linux/list.h>
#include <linux/compat.h>
#include <linux/completion.h>
#include <linux/pid.h>
@@ -72,6 +72,8 @@ struct task_struct {
unsigned bsd_ioctl_len;
struct completion parked;
struct completion exited;
+ TAILQ_ENTRY(task_struct) rcu_entry;
+ int rcu_recurse;
#define current ({ \
diff --git a/sys/compat/linuxkpi/common/include/linux/srcu.h b/sys/compat/linuxkpi/common/include/linux/srcu.h
index 90e2378a858e..f89fc82a8e1e 100644
--- a/sys/compat/linuxkpi/common/include/linux/srcu.h
+++ b/sys/compat/linuxkpi/common/include/linux/srcu.h
@@ -29,9 +29,7 @@
#ifndef _LINUX_SRCU_H_
#define _LINUX_SRCU_H_
-struct srcu_epoch_record;
struct srcu_struct {
- struct srcu_epoch_record *ss_epoch_record;
#define srcu_dereference(ptr,srcu) ((__typeof(*(ptr)) *)(ptr))