lkml.org 
[lkml]   [2011]   [Jun]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 11/12] mmc: test: add random fault injection in core.c
    Date
    This simple fault injection proved to be very useful to
    test the error handling in the block.c rw_rq(). It may
    still be useful to test if the host driver handle
    pre_req() and post_req() correctly in case of errors.

    Signed-off-by: Per Forlin <per.forlin@linaro.org>
    ---
    drivers/mmc/core/core.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
    drivers/mmc/core/debugfs.c | 5 ++++
    include/linux/mmc/host.h | 3 ++
    lib/Kconfig.debug | 11 +++++++++
    4 files changed, 73 insertions(+), 0 deletions(-)

    diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
    index 3538166..9128054 100644
    --- a/drivers/mmc/core/core.c
    +++ b/drivers/mmc/core/core.c
    @@ -23,6 +23,8 @@
    #include <linux/log2.h>
    #include <linux/regulator/consumer.h>
    #include <linux/pm_runtime.h>
    +#include <linux/fault-inject.h>
    +#include <linux/random.h>

    #include <linux/mmc/card.h>
    #include <linux/mmc/host.h>
    @@ -82,6 +84,56 @@ static void mmc_flush_scheduled_work(void)
    flush_workqueue(workqueue);
    }

    +#ifdef CONFIG_FAIL_MMC_REQUEST
    +
    +static DECLARE_FAULT_ATTR(fail_mmc_request);
    +
    +static int __init setup_fail_mmc_request(char *str)
    +{
    + return setup_fault_attr(&fail_mmc_request, str);
    +}
    +__setup("fail_mmc_request=", setup_fail_mmc_request);
    +
    +static void mmc_should_fail_request(struct mmc_host *host,
    + struct mmc_request *mrq)
    +{
    + struct mmc_command *cmd = mrq->cmd;
    + struct mmc_data *data = mrq->data;
    + static const int data_errors[] = {
    + -ETIMEDOUT,
    + -EILSEQ,
    + -EIO,
    + };
    +
    + if (!data)
    + return;
    +
    + if (cmd->error || data->error || !host->make_it_fail ||
    + !should_fail(&fail_mmc_request, data->blksz * data->blocks))
    + return;
    +
    + data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
    + data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
    +}
    +
    +static int __init fail_mmc_request_debugfs(void)
    +{
    + return init_fault_attr_dentries(&fail_mmc_request,
    + "fail_mmc_request");
    +}
    +
    +late_initcall(fail_mmc_request_debugfs);
    +
    +#else /* CONFIG_FAIL_MMC_REQUEST */
    +
    +static void mmc_should_fail_request(struct mmc_host *host,
    + struct mmc_request *mrq)
    +{
    +}
    +
    +#endif /* CONFIG_FAIL_MMC_REQUEST */
    +
    +
    /**
    * mmc_request_done - finish processing an MMC request
    * @host: MMC host which completed request
    @@ -108,6 +160,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
    cmd->error = 0;
    host->ops->request(host, mrq);
    } else {
    + mmc_should_fail_request(host, mrq);
    +
    led_trigger_event(host->led, LED_OFF);

    pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
    diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
    index 998797e..588e76f 100644
    --- a/drivers/mmc/core/debugfs.c
    +++ b/drivers/mmc/core/debugfs.c
    @@ -188,6 +188,11 @@ void mmc_add_host_debugfs(struct mmc_host *host)
    root, &host->clk_delay))
    goto err_node;
    #endif
    +#ifdef CONFIG_FAIL_MMC_REQUEST
    + if (!debugfs_create_u8("make-it-fail", S_IRUSR | S_IWUSR,
    + root, &host->make_it_fail))
    + goto err_node;
    +#endif
    return;

    err_node:
    diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
    index 01e7d2b..58414d1d 100644
    --- a/include/linux/mmc/host.h
    +++ b/include/linux/mmc/host.h
    @@ -302,6 +302,9 @@ struct mmc_host {

    struct mmc_async_req *areq; /* active async req */

    +#ifdef CONFIG_FAIL_MMC_REQUEST
    + u8 make_it_fail;
    +#endif
    unsigned long private[0] ____cacheline_aligned;
    };

    diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
    index dd373c8..04f50d8 100644
    --- a/lib/Kconfig.debug
    +++ b/lib/Kconfig.debug
    @@ -1067,6 +1067,17 @@ config FAIL_IO_TIMEOUT
    Only works with drivers that use the generic timeout handling,
    for others it wont do anything.

    +config FAIL_MMC_REQUEST
    + bool "Fault-injection capability for MMC IO"
    + select DEBUG_FS
    + depends on FAULT_INJECTION
    + help
    + Provide fault-injection capability for MMC IO.
    + This will make the mmc core return data errors. This is
    + useful for testing the error handling in the mmc block device
    + and how the mmc host driver handle retries from
    + the block device.
    +
    config FAULT_INJECTION_DEBUG_FS
    bool "Debugfs entries for fault-injection capabilities"
    depends on FAULT_INJECTION && SYSFS && DEBUG_FS
    --
    1.7.4.1


    \
     
     \ /
      Last update: 2011-06-18 22:59    [W:0.060 / U:30.108 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site