mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
lx_emul: shadow cpu_relax to update jiffies
There are rare use-cases where cpu_relax is used inside a busy loop (i2c bus functions), which only will break when the jiffies counter reaches a specific value. Because of the cooperative scheduling done in lx_emul, no timer interrupt will break such a loop. As a workaround, we check for necessary jiffies updates inside cpu_relax if interrupts are enabled. Ref genodelabs/genode#4778
This commit is contained in:
parent
7e2c546d8e
commit
50541c68ec
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* \brief Shadow copy of asm/vdso/processor.h
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2023-03-02
|
||||
*/
|
||||
|
||||
#ifndef _LX_EMUL__SHADOW__ARCH__ARM__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
#define _LX_EMUL__SHADOW__ARCH__ARM__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include_next <asm/vdso/processor.h>
|
||||
|
||||
static inline void __original_linux_cpu_relax(void)
|
||||
{
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
#undef cpu_relax
|
||||
|
||||
#include <lx_emul/irq.h>
|
||||
#include <lx_emul/time.h>
|
||||
|
||||
static inline void cpu_relax(void)
|
||||
{
|
||||
__original_linux_cpu_relax();
|
||||
|
||||
/*
|
||||
* When irqs are enabled, update jiffies to break potential
|
||||
* endless busy loops like:
|
||||
* - slchi() in drivers/i2c/algos/i2c-algo-bit.c
|
||||
*/
|
||||
if (!lx_emul_irq_state()) lx_emul_time_update_jiffies();
|
||||
}
|
||||
|
||||
#endif /* _LX_EMUL__SHADOW__ARCH__ARM__INCLUDE__ASM__VDSO__PROCESSOR_H_ */
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* \brief Shadow copy of asm/vdso/processor.h
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2023-03-02
|
||||
*/
|
||||
|
||||
#ifndef _LX_EMUL__SHADOW__ARCH__ARM64__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
#define _LX_EMUL__SHADOW__ARCH__ARM64__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
|
||||
#define cpu_relax __original_linux_cpu_relax
|
||||
#include_next <asm/vdso/processor.h>
|
||||
#undef cpu_relax
|
||||
|
||||
#include <lx_emul/irq.h>
|
||||
#include <lx_emul/time.h>
|
||||
|
||||
static __always_inline void cpu_relax(void)
|
||||
{
|
||||
__original_linux_cpu_relax();
|
||||
|
||||
/*
|
||||
* When irqs are enabled, update jiffies to break potential
|
||||
* endless busy loops like:
|
||||
* - slchi() in drivers/i2c/algos/i2c-algo-bit.c
|
||||
*/
|
||||
if (!lx_emul_irq_state()) lx_emul_time_update_jiffies();
|
||||
}
|
||||
|
||||
#endif /* _LX_EMUL__SHADOW__ARCH__ARM64__INCLUDE__ASM__VDSO__PROCESSOR_H_ */
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* \brief Shadow copy of asm/vdso/processor.h
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2023-03-02
|
||||
*/
|
||||
|
||||
#ifndef _LX_EMUL__SHADOW__ARCH__X86__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
#define _LX_EMUL__SHADOW__ARCH__X86__INCLUDE__ASM__VDSO__PROCESSOR_H_
|
||||
|
||||
#define cpu_relax __original_linux_cpu_relax
|
||||
#include_next <asm/vdso/processor.h>
|
||||
#undef cpu_relax
|
||||
|
||||
#include <lx_emul/irq.h>
|
||||
#include <lx_emul/time.h>
|
||||
|
||||
static __always_inline void cpu_relax(void)
|
||||
{
|
||||
__original_linux_cpu_relax();
|
||||
|
||||
/*
|
||||
* When irqs are enabled, update jiffies to break potential
|
||||
* endless busy loops like:
|
||||
* - slchi() in drivers/i2c/algos/i2c-algo-bit.c
|
||||
*/
|
||||
if (!lx_emul_irq_state()) lx_emul_time_update_jiffies();
|
||||
}
|
||||
|
||||
#endif /* _LX_EMUL__SHADOW__ARCH__X86__INCLUDE__ASM__VDSO__PROCESSOR_H_ */
|
@ -1,38 +0,0 @@
|
||||
/**
|
||||
* \brief Shadow copy of asm/vdso/processor.h
|
||||
* \author Alexander Boettcher
|
||||
* \date 2022-03-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __ASM_VDSO_PROCESSOR_H
|
||||
#define __ASM_VDSO_PROCESSOR_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
static __always_inline void rep_nop(void)
|
||||
{
|
||||
asm volatile("rep; nop" ::: "memory");
|
||||
}
|
||||
|
||||
|
||||
static __always_inline void cpu_relax(void)
|
||||
{
|
||||
/* break busy loop of slchi() in drivers/i2c/algos/i2c-algo-bit.c */
|
||||
__udelay(100);
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_PROCESSOR_H */
|
@ -6,7 +6,6 @@ TARGET := pc_intel_fb_drv
|
||||
LIBS := base pc_lx_emul blit jitterentropy
|
||||
|
||||
INC_DIR += $(REL_PRG_DIR)
|
||||
INC_DIR += $(REL_PRG_DIR)/shadow
|
||||
|
||||
SRC_CC += main.cc
|
||||
SRC_CC += emul.cc
|
||||
|
Loading…
x
Reference in New Issue
Block a user