Hi Daniel,

Have you noticed this on any platform yet with this test?

Regards,
Amit


On Tue, Apr 8, 2014 at 4:05 PM, Daniel Lezcano <daniel.lezc...@linaro.org>wrote:

> As pointed by Lorenzo, when a cpu powers down, the L1 cache must be flushed
> before, otherwise:
>
>  * data cachelines are not empty and the other cpu may fetch data
>  * cpu will lost some data leading to a memory corruption
>
> Note this bug is very difficult to reproduce and this test will not spot
> the
> issue everytime.
>
> Signed-off-by: Daniel Lezcano <daniel.lezc...@linaro.org>
> ---
>  cpuidle/cpuidle-l1.c   |   72
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  cpuidle/cpuidle_05.sh  |   42 ++++++++++++++++++++++++++++
>  cpuidle/cpuidle_05.txt |    1 +
>  3 files changed, 115 insertions(+)
>  create mode 100644 cpuidle/cpuidle-l1.c
>  create mode 100755 cpuidle/cpuidle_05.sh
>  create mode 100644 cpuidle/cpuidle_05.txt
>
> diff --git a/cpuidle/cpuidle-l1.c b/cpuidle/cpuidle-l1.c
> new file mode 100644
> index 0000000..bbcde28
> --- /dev/null
> +++ b/cpuidle/cpuidle-l1.c
> @@ -0,0 +1,72 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <unistd.h>
> +#include <pthread.h>
> +#define BUFSIZE (4*1024)
> +#define DEADBEEF 0xDEADBEEF
> +static int buffer[BUFSIZE];
> +
> +static pthread_t threads[64];
> +
> +void *thread_routine(void *arg)
> +{
> +       int i, display = *(int *)arg;
> +       int dummy;
> +
> +       for (i = 0; i < 100; i++) {
> +
> +               int j;
> +
> +               for (j = 0; j < BUFSIZE * 1000; j++) {
> +                       dummy = buffer[j % BUFSIZE];
> +                       dummy++;
> +               }
> +
> +               usleep(200000);
> +
> +               if (buffer[i] != DEADBEEF) {
> +                       fprintf(stderr, "memory corruption\n");
> +                       return (void *)-1;
> +               }
> +
> +               if (display == 0)
> +                       printf("%d%%%s", i, i < 10 ? "\b\b" : "\b\b\b");
> +       }
> +
> +       if (display == 0)
> +               printf("    \b\b\b\b");
> +
> +       return NULL;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +       int i, ret = 0;
> +       int nrcpus = sysconf(_SC_NPROCESSORS_ONLN);
> +
> +       for (i = 0; i < BUFSIZE; i++)
> +               buffer[i] = DEADBEEF;
> +
> +       setbuf(stdout, NULL);
> +
> +       for(i = 0; i < nrcpus; i++) {
> +
> +               if (pthread_create(&threads[i], NULL, thread_routine, &i))
> {
> +                       perror("pthread_create");
> +                       return 1;
> +               }
> +
> +       }
> +
> +       for (i = 0; i < nrcpus; i++) {
> +               void *result;
> +               pthread_join(threads[i], &result);
> +
> +               if (result == (void *)-1)
> +                       ret = 1;
> +       }
> +
> +       return ret;
> +}
> diff --git a/cpuidle/cpuidle_05.sh b/cpuidle/cpuidle_05.sh
> new file mode 100755
> index 0000000..679439d
> --- /dev/null
> +++ b/cpuidle/cpuidle_05.sh
> @@ -0,0 +1,42 @@
> +#!/bin/bash
> +#
> +# PM-QA validation test suite for the power management on Linux
> +#
> +# Copyright (C) 2011, Linaro Limited.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License
> +# as published by the Free Software Foundation; either version 2
> +# of the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>  02110-1301, USA.
> +#
> +# Contributors:
> +#     Daniel Lezcano <daniel.lezc...@linaro.org> (IBM Corporation)
> +#       - initial API and implementation
> +#
> +
> +# URL :
> https://wiki.linaro.org/WorkingGroups/PowerManagement/Resources/TestSuite/PmQaSpecification#cpuidle_05
> +
> +source ../include/functions.sh
> +
> +CPUIDLE_L1=./cpuidle-l1
> +
> +if [ $(id -u) -ne 0 ]; then
> +    log_skip "run as non-root"
> +    exit 0
> +fi
> +
> +check_cpuidle_l1() {
> +    check "Fill L1 cache and sleep" "./$CPUIDLE_L1"
> +}
> +
> +check_cpuidle_l1
> +test_status_show
> diff --git a/cpuidle/cpuidle_05.txt b/cpuidle/cpuidle_05.txt
> new file mode 100644
> index 0000000..1f80e36
> --- /dev/null
> +++ b/cpuidle/cpuidle_05.txt
> @@ -0,0 +1 @@
> +Run cpuidle L1 test program to catch L1 flush missing vs cpu power down
> --
> 1.7.9.5
>
>
_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to