Commit 098dc66a authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Ulf Hansson

mmc: test: reduce stack usage in mmc_test_nonblock_transfer

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: cd8084f9 ("locking/lockdep: Apply crossrelease to completions")
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Tested-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 2f3110cc
...@@ -800,38 +800,44 @@ static int mmc_test_check_broken_result(struct mmc_test_card *test, ...@@ -800,38 +800,44 @@ static int mmc_test_check_broken_result(struct mmc_test_card *test,
return ret; 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 * Tests nonblock transfer with certain parameters
*/ */
static void mmc_test_nonblock_reset(struct mmc_request *mrq, static void mmc_test_req_reset(struct mmc_test_req *rq)
struct mmc_command *cmd, {
struct mmc_command *stop, memset(rq, 0, sizeof(struct mmc_test_req));
struct mmc_data *data)
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)); struct mmc_test_req *rq = kmalloc(sizeof(*rq), GFP_KERNEL);
memset(cmd, 0, sizeof(struct mmc_command));
memset(data, 0, sizeof(struct mmc_data));
memset(stop, 0, sizeof(struct mmc_command));
mrq->cmd = cmd; if (rq)
mrq->data = data; mmc_test_req_reset(rq);
mrq->stop = stop;
return rq;
} }
static int mmc_test_nonblock_transfer(struct mmc_test_card *test, static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
struct scatterlist *sg, unsigned sg_len, struct scatterlist *sg, unsigned sg_len,
unsigned dev_addr, unsigned blocks, unsigned dev_addr, unsigned blocks,
unsigned blksz, int write, int count) unsigned blksz, int write, int count)
{ {
struct mmc_request mrq1; struct mmc_test_req *rq1, *rq2;
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_async_req test_areq[2]; struct mmc_test_async_req test_areq[2];
struct mmc_async_req *done_areq; struct mmc_async_req *done_areq;
struct mmc_async_req *cur_areq = &test_areq[0].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, ...@@ -843,12 +849,16 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
test_areq[0].test = test; test_areq[0].test = test;
test_areq[1].test = test; test_areq[1].test = test;
mmc_test_nonblock_reset(&mrq1, &cmd1, &stop1, &data1); rq1 = mmc_test_req_alloc();
mmc_test_nonblock_reset(&mrq2, &cmd2, &stop2, &data2); 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; 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; other_areq->err_check = mmc_test_check_result_async;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -861,14 +871,10 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, ...@@ -861,14 +871,10 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
goto err; goto err;
} }
if (done_areq) { if (done_areq)
if (done_areq->mrq == &mrq2) mmc_test_req_reset(container_of(done_areq->mrq,
mmc_test_nonblock_reset(&mrq2, &cmd2, struct mmc_test_req, mrq));
&stop2, &data2);
else
mmc_test_nonblock_reset(&mrq1, &cmd1,
&stop1, &data1);
}
swap(cur_areq, other_areq); swap(cur_areq, other_areq);
dev_addr += blocks; dev_addr += blocks;
} }
...@@ -877,8 +883,9 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, ...@@ -877,8 +883,9 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
if (status != MMC_BLK_SUCCESS) if (status != MMC_BLK_SUCCESS)
ret = RESULT_FAIL; ret = RESULT_FAIL;
return ret;
err: err:
kfree(rq1);
kfree(rq2);
return ret; return ret;
} }
...@@ -2329,28 +2336,6 @@ static int mmc_test_reset(struct mmc_test_card *test) ...@@ -2329,28 +2336,6 @@ static int mmc_test_reset(struct mmc_test_card *test)
return RESULT_FAIL; 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, static int mmc_test_send_status(struct mmc_test_card *test,
struct mmc_command *cmd) struct mmc_command *cmd)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment