aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linuxkpi/common')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/sched.h5
-rw-r--r--sys/compat/linuxkpi/common/src/linux_rcu.c18
2 files changed, 14 insertions, 9 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h
index 0545710a61d7..da38d89eb639 100644
--- a/sys/compat/linuxkpi/common/include/linux/sched.h
+++ b/sys/compat/linuxkpi/common/include/linux/sched.h
@@ -76,8 +76,9 @@ struct task_struct {
unsigned bsd_ioctl_len;
struct completion parked;
struct completion exited;
- TAILQ_ENTRY(task_struct) rcu_entry;
- int rcu_recurse;
+#define TS_RCU_TYPE_MAX 2
+ TAILQ_ENTRY(task_struct) rcu_entry[TS_RCU_TYPE_MAX];
+ int rcu_recurse[TS_RCU_TYPE_MAX];
int bsd_interrupt_value;
struct work_struct *work; /* current work struct, if set */
struct task_struct *group_leader;
diff --git a/sys/compat/linuxkpi/common/src/linux_rcu.c b/sys/compat/linuxkpi/common/src/linux_rcu.c
index 32ace5cf0c99..5e698739ab09 100644
--- a/sys/compat/linuxkpi/common/src/linux_rcu.c
+++ b/sys/compat/linuxkpi/common/src/linux_rcu.c
@@ -74,6 +74,7 @@ struct linux_epoch_record {
ck_epoch_record_t epoch_record;
TAILQ_HEAD(, task_struct) ts_head;
int cpuid;
+ int type;
} __aligned(CACHE_LINE_SIZE);
/*
@@ -90,6 +91,8 @@ CTASSERT(sizeof(struct rcu_head) == sizeof(struct callback_head));
*/
CTASSERT(offsetof(struct linux_epoch_record, epoch_record) == 0);
+CTASSERT(TS_RCU_TYPE_MAX == RCU_TYPE_MAX);
+
static ck_epoch_t linux_epoch[RCU_TYPE_MAX];
static struct linux_epoch_head linux_epoch_head[RCU_TYPE_MAX];
DPCPU_DEFINE_STATIC(struct linux_epoch_record, linux_epoch_record[RCU_TYPE_MAX]);
@@ -118,6 +121,7 @@ linux_rcu_runtime_init(void *arg __unused)
record = &DPCPU_ID_GET(i, linux_epoch_record[j]);
record->cpuid = i;
+ record->type = j;
ck_epoch_register(&linux_epoch[j],
&record->epoch_record, NULL);
TAILQ_INIT(&record->ts_head);
@@ -201,9 +205,9 @@ linux_rcu_read_lock(unsigned type)
*/
critical_enter();
ck_epoch_begin(&record->epoch_record, NULL);
- ts->rcu_recurse++;
- if (ts->rcu_recurse == 1)
- TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry);
+ ts->rcu_recurse[type]++;
+ if (ts->rcu_recurse[type] == 1)
+ TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry[type]);
critical_exit();
}
@@ -227,9 +231,9 @@ linux_rcu_read_unlock(unsigned type)
*/
critical_enter();
ck_epoch_end(&record->epoch_record, NULL);
- ts->rcu_recurse--;
- if (ts->rcu_recurse == 0)
- TAILQ_REMOVE(&record->ts_head, ts, rcu_entry);
+ ts->rcu_recurse[type]--;
+ if (ts->rcu_recurse[type] == 0)
+ TAILQ_REMOVE(&record->ts_head, ts, rcu_entry[type]);
critical_exit();
sched_unpin();
@@ -254,7 +258,7 @@ linux_synchronize_rcu_cb(ck_epoch_t *epoch __unused, ck_epoch_record_t *epoch_re
* the threads in the queue are CPU-pinned and cannot
* go anywhere while the current thread is locked.
*/
- TAILQ_FOREACH(ts, &record->ts_head, rcu_entry) {
+ TAILQ_FOREACH(ts, &record->ts_head, rcu_entry[record->type]) {
if (ts->task_thread->td_priority > prio)
prio = ts->task_thread->td_priority;
is_sleeping |= (ts->task_thread->td_inhibitors != 0);