[PATCH] acpica: fwts_acpica: force indefinite AML Wait() to timeout

IvanHu ivan.hu at canonical.com
Mon Jan 14 10:08:25 UTC 2013


On 01/05/2013 01:46 AM, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> Quite a few _EJ0 implementations make the ACPI method test block
> forever because they are using an AML Wait() that is waiting
> indefinitely for an external event (which fwts cannot generate).
> Instead of the test waiting forever for the event, make these
> waits timeout after 20 seconds.  We force this by causing an alarm
> signal which interrupts the blocked sem_wait and we can detect this
> and report back to the user that we aborted the wait.  This is ugly
> but effective.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>   src/acpica/fwts_acpica.c | 35 ++++++++++++++++++++++++++++++++++-
>   1 file changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/src/acpica/fwts_acpica.c b/src/acpica/fwts_acpica.c
> index 26b6a13..65caa18 100644
> --- a/src/acpica/fwts_acpica.c
> +++ b/src/acpica/fwts_acpica.c
> @@ -55,6 +55,8 @@ static pthread_mutex_t mutex_thread_info;
>   #define MAX_SEMAPHORES		(1024)
>   #define MAX_THREADS		(128)
>
> +#define MAX_WAIT_TIMEOUT	(20)	/* Seconds */
> +
>   typedef struct {
>   	sem_t		sem;	/* Semaphore handle */
>   	int		count;	/* count > 0 if acquired */
> @@ -546,6 +548,10 @@ ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)
>   	return ret;
>   }
>
> +static void sem_alarm(int dummy)
> +{
> +	/* Do nothing apart from interrupt sem_wait() */
> +}
>
>   /*
>    *  AcpiOsWaitSemaphore()
> @@ -556,6 +562,7 @@ ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE handle, UINT32 Units, UINT16 Timeout
>   {
>   	sem_info *sem = (sem_info *)handle;
>   	struct timespec	tm;
> +	struct sigaction sa;
>
>   	if (!handle)
>   		return AE_BAD_PARAMETER;
> @@ -567,8 +574,34 @@ ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE handle, UINT32 Units, UINT16 Timeout
>   		break;
>
>   	case ACPI_WAIT_FOREVER:
> -		if (sem_wait(&sem->sem))
> +		/*
> +		 *  The semantics are "wait forever", but
> +		 *  really we actually detect a lock up
> +		 *  after a long wait and break out rather
> +		 *  than waiting for the sun to turn into
> +		 *  a lump of coal.  This allows us to
> +		 *  handle controls such as _EJ0 that may
> +		 *  be waiting forever for a event to signal
> +		 *  control to continue.  It is evil.
> +		 */
> +		sa.sa_handler = sem_alarm;
> +		sa.sa_flags = 0;
> +		sigaction(SIGALRM, &sa, NULL);
> +		alarm(MAX_WAIT_TIMEOUT);
> +
> +		if (sem_wait(&sem->sem)) {
> +			alarm(0);
> +			if (errno == EINTR)
> +				fwts_log_info(fwts_acpica_fw,
> +					"AML was blocked waiting for "
> +					"an external event, fwts detected "
> +					"this and forced a timeout after "
> +					"%d seconds on a Wait() that had "
> +					"an indefinite timeout.",
> +					MAX_WAIT_TIMEOUT);
>   			return AE_TIME;
> +		}
> +		alarm(0);
>   		break;
>   	default:
>   		tm.tv_sec = Timeout / 1000;
>

Acked-by: Ivan Hu <ivan.hu at canonical.com>



More information about the fwts-devel mailing list