diff --git a/arch/x86_64/tools/mcreboot-smp-x86.sh.in b/arch/x86_64/tools/mcreboot-smp-x86.sh.in index 4a87b10b..0f63c403 100644 --- a/arch/x86_64/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86_64/tools/mcreboot-smp-x86.sh.in @@ -44,8 +44,9 @@ fi turbo="" ihk_irq="" umask_old=`umask` +idle_halt="" -while getopts :tk:c:m:o:f:r:q:i:d:e: OPT +while getopts :tk:c:m:o:f:r:q:i:d:e:h OPT do case ${OPT} in f) facility=${OPTARG} @@ -70,6 +71,8 @@ do ;; i) mon_interval=${OPTARG} ;; + h) idle_halt="idle_halt" + ;; *) echo "invalid option -${OPT}" >&2 exit 1 esac @@ -408,7 +411,7 @@ if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then fi # Set kernel arguments -if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo dump_level=${DUMP_LEVEL} $extra_kopts"; then +if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo $idle_halt dump_level=${DUMP_LEVEL} $extra_kopts"; then echo "error: setting kernel arguments" >&2 error_exit "os_created" fi diff --git a/kernel/futex.c b/kernel/futex.c index 495ee506..ee728d1c 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -673,9 +673,11 @@ static uint64_t futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q xchg4(&(cpu_local_var(current)->status), PS_INTERRUPTIBLE); /* Indicate spin sleep */ - irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock); - thread->spin_sleep = 1; - ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate); + if (!idle_halt) { + irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock); + thread->spin_sleep = 1; + ihk_mc_spinlock_unlock(&thread->spin_sleep_lock, irqstate); + } queue_me(q, hb); diff --git a/kernel/include/process.h b/kernel/include/process.h index 432289fe..1bd70e17 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -277,6 +277,7 @@ struct resource_set { extern struct list_head resource_set_list; extern mcs_rwlock_lock_t resource_set_lock; +extern int idle_halt; struct process_hash { struct list_head list[HASH_SIZE]; diff --git a/kernel/init.c b/kernel/init.c index 1dfba803..36f58d98 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -144,6 +144,12 @@ static void parse_kargs(void) } } ihk_mc_set_dump_level(dump_level); + + /* idle_halt option */ + ptr = find_command_line("idle_halt"); + if (ptr) { + idle_halt = 1; + } } extern void ihk_mc_get_boot_time(unsigned long *tv_sec, unsigned long *tv_nsec); diff --git a/kernel/process.c b/kernel/process.c index 2bfff206..76c5ac1d 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -100,6 +100,8 @@ extern void perf_reset(struct mc_perf_event *event); struct list_head resource_set_list; mcs_rwlock_lock_t resource_set_lock; +int idle_halt = 0; + void init_process(struct process *proc, struct process *parent) { @@ -3044,6 +3046,12 @@ void spin_sleep_or_schedule(void) int woken = 0; long irqstate; + /* Spinning disabled explicitly */ + if (idle_halt) { + dkprintf("%s: idle_halt -> schedule()\n", __FUNCTION__); + goto out_schedule; + } + /* Try to spin sleep */ irqstate = ihk_mc_spinlock_lock(&thread->spin_sleep_lock); if (thread->spin_sleep == 0) { @@ -3092,6 +3100,7 @@ void spin_sleep_or_schedule(void) cpu_pause(); } +out_schedule: schedule(); }