From e3927a0b950bbb60fbb48069d035a16f30140375 Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Fri, 5 Feb 2021 09:39:07 +0900 Subject: [PATCH] uti: futex: McKernel waker sends IPI to Linux waiter CPU Change-Id: I6f725b3a6b1b26b9f553d8c58132c0c0a4416683 --- executer/kernel/mcctrl/futex.c | 1 + executer/kernel/mcctrl/include/futex.h | 3 +++ kernel/futex.c | 19 +++++++++++++++---- kernel/host.c | 2 +- kernel/include/futex.h | 3 +++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/executer/kernel/mcctrl/futex.c b/executer/kernel/mcctrl/futex.c index 060f90bb..9d887f9d 100644 --- a/executer/kernel/mcctrl/futex.c +++ b/executer/kernel/mcctrl/futex.c @@ -813,6 +813,7 @@ static int futex_wait(uint32_t __user *uaddr, int fshared, q->bitset = bitset; q->requeue_pi_key = NULL; q->uti_futex_resp = uti_info->uti_futex_resp; + q->linux_cpu = ihk_ikc_get_processor_id(); retry: /* Prepare to wait on uaddr. */ diff --git a/executer/kernel/mcctrl/include/futex.h b/executer/kernel/mcctrl/include/futex.h index 3ab83081..317f449a 100644 --- a/executer/kernel/mcctrl/include/futex.h +++ b/executer/kernel/mcctrl/include/futex.h @@ -140,6 +140,9 @@ struct futex_q { /* Used to wake-up a thread running on a Linux CPU */ void *uti_futex_resp; + /* Used to send IPI directly to the waiter CPU */ + int linux_cpu; + /* Used to wake-up a thread running on a McKernel from Linux */ void *th_spin_sleep; void *th_status; diff --git a/kernel/futex.c b/kernel/futex.c index 7b5a91f9..fb47db78 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -73,12 +73,15 @@ #include #include #include +#include unsigned long ihk_mc_get_ns_per_tsc(void); struct futex_hash_bucket *futex_queues; +extern struct ihk_ikc_channel_desc **ikc2linuxs; + struct futex_hash_bucket *get_futex_queues(void) { return futex_queues; @@ -238,11 +241,19 @@ static void wake_futex(struct futex_q *q) if (q->uti_futex_resp) { int rc; - dkprintf("%s: waking up migrated-to-Linux thread (tid %d),uti_futex_resp=%p\n", - __func__, p->tid, q->uti_futex_resp); - struct ikc_scd_packet pckt; - struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux); + struct ihk_ikc_channel_desc *resp_channel; + + dkprintf("%s: waking up migrated-to-Linux thread (tid %d),uti_futex_resp=%p,linux_cpu: %d\n", + __func__, p->tid, q->uti_futex_resp, q->linux_cpu); + + /* does this Linux CPU have a connected channel? */ + if (ikc2linuxs[q->linux_cpu]) { + resp_channel = ikc2linuxs[q->linux_cpu]; + } else { + resp_channel = cpu_local_var(ikc2linux); + } + pckt.msg = SCD_MSG_FUTEX_WAKE; pckt.futex.resp = q->uti_futex_resp; pckt.futex.spin_sleep = &p->spin_sleep; diff --git a/kernel/host.c b/kernel/host.c index 64f6a7b6..05766ad9 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -43,7 +43,7 @@ #endif /* Linux channel table, indexec by Linux CPU id */ -static struct ihk_ikc_channel_desc **ikc2linuxs = NULL; +struct ihk_ikc_channel_desc **ikc2linuxs; void check_mapping_for_proc(struct thread *thread, unsigned long addr) { diff --git a/kernel/include/futex.h b/kernel/include/futex.h index 5eb047a8..14b9012e 100644 --- a/kernel/include/futex.h +++ b/kernel/include/futex.h @@ -216,6 +216,9 @@ struct futex_q { /* Used to wake-up a thread running on a Linux CPU */ void *uti_futex_resp; + /* Used to send IPI directly to the waiter CPU */ + int linux_cpu; + /* Used to wake-up a thread running on a McKernel from Linux */ void *th_spin_sleep; void *th_status;