On 15/08/17 18:11, Arnd Bergmann wrote:
> The new lockdep annotations for completions cause a warning in the
> mmc test module, in a function that now has four 150 byte structures
> on the stack:
> 
> drivers/mmc/core/mmc_test.c: In function 
> 'mmc_test_nonblock_transfer.constprop':
> drivers/mmc/core/mmc_test.c:892:1: error: the frame size of 1360 bytes is 
> larger than 1024 bytes [-Werror=frame-larger-than=]
> 
> The mmc_test_ongoing_transfer function evidently had a similar problem,
> and worked around it by using dynamic allocation.
> 
> This generalizes the approach used by mmc_test_ongoing_transfer() and
> applies it to mmc_test_nonblock_transfer() as well.
> 
> Fixes: cd8084f91c02 ("locking/lockdep: Apply crossrelease to completions")
> Signed-off-by: Arnd Bergmann <[email protected]>

Apart from duplicate blank line pointed out below:

Acked-by: Adrian Hunter <[email protected]>
Tested-by: Adrian Hunter <[email protected]>

> ---
> The patch causing this is currently part of linux-next, scheduled for
> 4.14, so it would be good to have this in the same release.
> 
> Since the change is not entirely trivial, please test this before applying.
> ---
>  drivers/mmc/core/mmc_test.c | 97 
> +++++++++++++++++++--------------------------
>  1 file changed, 41 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
> index 7a304a6e5bf1..478869805b96 100644
> --- a/drivers/mmc/core/mmc_test.c
> +++ b/drivers/mmc/core/mmc_test.c
> @@ -800,38 +800,44 @@ static int mmc_test_check_broken_result(struct 
> mmc_test_card *test,
>       return ret;
>  }
>  
> +struct mmc_test_req {
> +     struct mmc_request mrq;
> +     struct mmc_command sbc;
> +     struct mmc_command cmd;
> +     struct mmc_command stop;
> +     struct mmc_command status;
> +     struct mmc_data data;
> +};
> +
>  /*
>   * Tests nonblock transfer with certain parameters
>   */
> -static void mmc_test_nonblock_reset(struct mmc_request *mrq,
> -                                 struct mmc_command *cmd,
> -                                 struct mmc_command *stop,
> -                                 struct mmc_data *data)
> +static void mmc_test_req_reset(struct mmc_test_req *rq)
> +{
> +     memset(rq, 0, sizeof(struct mmc_test_req));
> +
> +     rq->mrq.cmd = &rq->cmd;
> +     rq->mrq.data = &rq->data;
> +     rq->mrq.stop = &rq->stop;
> +}
> +
> +static struct mmc_test_req *mmc_test_req_alloc(void)
>  {
> -     memset(mrq, 0, sizeof(struct mmc_request));
> -     memset(cmd, 0, sizeof(struct mmc_command));
> -     memset(data, 0, sizeof(struct mmc_data));
> -     memset(stop, 0, sizeof(struct mmc_command));
> +     struct mmc_test_req *rq = kmalloc(sizeof(*rq), GFP_KERNEL);
>  
> -     mrq->cmd = cmd;
> -     mrq->data = data;
> -     mrq->stop = stop;
> +     if (rq)
> +             mmc_test_req_reset(rq);
> +
> +     return rq;
>  }
> +
> +

Duplicate blank line

>  static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
>                                     struct scatterlist *sg, unsigned sg_len,
>                                     unsigned dev_addr, unsigned blocks,
>                                     unsigned blksz, int write, int count)
>  {
> -     struct mmc_request mrq1;
> -     struct mmc_command cmd1;
> -     struct mmc_command stop1;
> -     struct mmc_data data1;
> -
> -     struct mmc_request mrq2;
> -     struct mmc_command cmd2;
> -     struct mmc_command stop2;
> -     struct mmc_data data2;
> -
> +     struct mmc_test_req *rq1, *rq2;
>       struct mmc_test_async_req test_areq[2];
>       struct mmc_async_req *done_areq;
>       struct mmc_async_req *cur_areq = &test_areq[0].areq;
> @@ -843,12 +849,16 @@ static int mmc_test_nonblock_transfer(struct 
> mmc_test_card *test,
>       test_areq[0].test = test;
>       test_areq[1].test = test;
>  
> -     mmc_test_nonblock_reset(&mrq1, &cmd1, &stop1, &data1);
> -     mmc_test_nonblock_reset(&mrq2, &cmd2, &stop2, &data2);
> +     rq1 = mmc_test_req_alloc();
> +     rq2 = mmc_test_req_alloc();
> +     if (!rq1 || !rq2) {
> +             ret = RESULT_FAIL;
> +             goto err;
> +     }
>  
> -     cur_areq->mrq = &mrq1;
> +     cur_areq->mrq = &rq1->mrq;
>       cur_areq->err_check = mmc_test_check_result_async;
> -     other_areq->mrq = &mrq2;
> +     other_areq->mrq = &rq2->mrq;
>       other_areq->err_check = mmc_test_check_result_async;
>  
>       for (i = 0; i < count; i++) {
> @@ -861,14 +871,10 @@ static int mmc_test_nonblock_transfer(struct 
> mmc_test_card *test,
>                       goto err;
>               }
>  
> -             if (done_areq) {
> -                     if (done_areq->mrq == &mrq2)
> -                             mmc_test_nonblock_reset(&mrq2, &cmd2,
> -                                                     &stop2, &data2);
> -                     else
> -                             mmc_test_nonblock_reset(&mrq1, &cmd1,
> -                                                     &stop1, &data1);
> -             }
> +             if (done_areq)
> +                     mmc_test_req_reset(container_of(done_areq->mrq,
> +                                             struct mmc_test_req, mrq));
> +
>               swap(cur_areq, other_areq);
>               dev_addr += blocks;
>       }
> @@ -877,8 +883,9 @@ static int mmc_test_nonblock_transfer(struct 
> mmc_test_card *test,
>       if (status != MMC_BLK_SUCCESS)
>               ret = RESULT_FAIL;
>  
> -     return ret;
>  err:
> +     kfree(rq1);
> +     kfree(rq2);
>       return ret;
>  }
>  
> @@ -2329,28 +2336,6 @@ static int mmc_test_reset(struct mmc_test_card *test)
>       return RESULT_FAIL;
>  }
>  
> -struct mmc_test_req {
> -     struct mmc_request mrq;
> -     struct mmc_command sbc;
> -     struct mmc_command cmd;
> -     struct mmc_command stop;
> -     struct mmc_command status;
> -     struct mmc_data data;
> -};
> -
> -static struct mmc_test_req *mmc_test_req_alloc(void)
> -{
> -     struct mmc_test_req *rq = kzalloc(sizeof(*rq), GFP_KERNEL);
> -
> -     if (rq) {
> -             rq->mrq.cmd = &rq->cmd;
> -             rq->mrq.data = &rq->data;
> -             rq->mrq.stop = &rq->stop;
> -     }
> -
> -     return rq;
> -}
> -
>  static int mmc_test_send_status(struct mmc_test_card *test,
>                               struct mmc_command *cmd)
>  {
> 

Reply via email to