diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-08-15 11:11:58 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2017-08-30 09:03:37 -0400 |
commit | 098dc66adeba4aaa8797124c10c2a77fd2e89584 (patch) | |
tree | 60250235eba31bbe97b02ae8cfca61e33819dd7d /drivers/mmc/core/mmc_test.c | |
parent | 2f3110cc89c29a790c8b31c7983603d60b9ede49 (diff) |
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: cd8084f91c02 ("locking/lockdep: Apply crossrelease to completions")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/core/mmc_test.c')
-rw-r--r-- | drivers/mmc/core/mmc_test.c | 97 |
1 files 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, | |||
800 | return ret; | 800 | return ret; |
801 | } | 801 | } |
802 | 802 | ||
803 | struct mmc_test_req { | ||
804 | struct mmc_request mrq; | ||
805 | struct mmc_command sbc; | ||
806 | struct mmc_command cmd; | ||
807 | struct mmc_command stop; | ||
808 | struct mmc_command status; | ||
809 | struct mmc_data data; | ||
810 | }; | ||
811 | |||
803 | /* | 812 | /* |
804 | * Tests nonblock transfer with certain parameters | 813 | * Tests nonblock transfer with certain parameters |
805 | */ | 814 | */ |
806 | static void mmc_test_nonblock_reset(struct mmc_request *mrq, | 815 | static void mmc_test_req_reset(struct mmc_test_req *rq) |
807 | struct mmc_command *cmd, | 816 | { |
808 | struct mmc_command *stop, | 817 | memset(rq, 0, sizeof(struct mmc_test_req)); |
809 | struct mmc_data *data) | 818 | |
819 | rq->mrq.cmd = &rq->cmd; | ||
820 | rq->mrq.data = &rq->data; | ||
821 | rq->mrq.stop = &rq->stop; | ||
822 | } | ||
823 | |||
824 | static struct mmc_test_req *mmc_test_req_alloc(void) | ||
810 | { | 825 | { |
811 | memset(mrq, 0, sizeof(struct mmc_request)); | 826 | struct mmc_test_req *rq = kmalloc(sizeof(*rq), GFP_KERNEL); |
812 | memset(cmd, 0, sizeof(struct mmc_command)); | ||
813 | memset(data, 0, sizeof(struct mmc_data)); | ||
814 | memset(stop, 0, sizeof(struct mmc_command)); | ||
815 | 827 | ||
816 | mrq->cmd = cmd; | 828 | if (rq) |
817 | mrq->data = data; | 829 | mmc_test_req_reset(rq); |
818 | mrq->stop = stop; | 830 | |
831 | return rq; | ||
819 | } | 832 | } |
833 | |||
834 | |||
820 | static int mmc_test_nonblock_transfer(struct mmc_test_card *test, | 835 | static int mmc_test_nonblock_transfer(struct mmc_test_card *test, |
821 | struct scatterlist *sg, unsigned sg_len, | 836 | struct scatterlist *sg, unsigned sg_len, |
822 | unsigned dev_addr, unsigned blocks, | 837 | unsigned dev_addr, unsigned blocks, |
823 | unsigned blksz, int write, int count) | 838 | unsigned blksz, int write, int count) |
824 | { | 839 | { |
825 | struct mmc_request mrq1; | 840 | struct mmc_test_req *rq1, *rq2; |
826 | struct mmc_command cmd1; | ||
827 | struct mmc_command stop1; | ||
828 | struct mmc_data data1; | ||
829 | |||
830 | struct mmc_request mrq2; | ||
831 | struct mmc_command cmd2; | ||
832 | struct mmc_command stop2; | ||
833 | struct mmc_data data2; | ||
834 | |||
835 | struct mmc_test_async_req test_areq[2]; | 841 | struct mmc_test_async_req test_areq[2]; |
836 | struct mmc_async_req *done_areq; | 842 | struct mmc_async_req *done_areq; |
837 | struct mmc_async_req *cur_areq = &test_areq[0].areq; | 843 | 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 | test_areq[0].test = test; | 849 | test_areq[0].test = test; |
844 | test_areq[1].test = test; | 850 | test_areq[1].test = test; |
845 | 851 | ||
846 | mmc_test_nonblock_reset(&mrq1, &cmd1, &stop1, &data1); | 852 | rq1 = mmc_test_req_alloc(); |
847 | mmc_test_nonblock_reset(&mrq2, &cmd2, &stop2, &data2); | 853 | rq2 = mmc_test_req_alloc(); |
854 | if (!rq1 || !rq2) { | ||
855 | ret = RESULT_FAIL; | ||
856 | goto err; | ||
857 | } | ||
848 | 858 | ||
849 | cur_areq->mrq = &mrq1; | 859 | cur_areq->mrq = &rq1->mrq; |
850 | cur_areq->err_check = mmc_test_check_result_async; | 860 | cur_areq->err_check = mmc_test_check_result_async; |
851 | other_areq->mrq = &mrq2; | 861 | other_areq->mrq = &rq2->mrq; |
852 | other_areq->err_check = mmc_test_check_result_async; | 862 | other_areq->err_check = mmc_test_check_result_async; |
853 | 863 | ||
854 | for (i = 0; i < count; i++) { | 864 | for (i = 0; i < count; i++) { |
@@ -861,14 +871,10 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, | |||
861 | goto err; | 871 | goto err; |
862 | } | 872 | } |
863 | 873 | ||
864 | if (done_areq) { | 874 | if (done_areq) |
865 | if (done_areq->mrq == &mrq2) | 875 | mmc_test_req_reset(container_of(done_areq->mrq, |
866 | mmc_test_nonblock_reset(&mrq2, &cmd2, | 876 | struct mmc_test_req, mrq)); |
867 | &stop2, &data2); | 877 | |
868 | else | ||
869 | mmc_test_nonblock_reset(&mrq1, &cmd1, | ||
870 | &stop1, &data1); | ||
871 | } | ||
872 | swap(cur_areq, other_areq); | 878 | swap(cur_areq, other_areq); |
873 | dev_addr += blocks; | 879 | dev_addr += blocks; |
874 | } | 880 | } |
@@ -877,8 +883,9 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, | |||
877 | if (status != MMC_BLK_SUCCESS) | 883 | if (status != MMC_BLK_SUCCESS) |
878 | ret = RESULT_FAIL; | 884 | ret = RESULT_FAIL; |
879 | 885 | ||
880 | return ret; | ||
881 | err: | 886 | err: |
887 | kfree(rq1); | ||
888 | kfree(rq2); | ||
882 | return ret; | 889 | return ret; |
883 | } | 890 | } |
884 | 891 | ||
@@ -2329,28 +2336,6 @@ static int mmc_test_reset(struct mmc_test_card *test) | |||
2329 | return RESULT_FAIL; | 2336 | return RESULT_FAIL; |
2330 | } | 2337 | } |
2331 | 2338 | ||
2332 | struct mmc_test_req { | ||
2333 | struct mmc_request mrq; | ||
2334 | struct mmc_command sbc; | ||
2335 | struct mmc_command cmd; | ||
2336 | struct mmc_command stop; | ||
2337 | struct mmc_command status; | ||
2338 | struct mmc_data data; | ||
2339 | }; | ||
2340 | |||
2341 | static struct mmc_test_req *mmc_test_req_alloc(void) | ||
2342 | { | ||
2343 | struct mmc_test_req *rq = kzalloc(sizeof(*rq), GFP_KERNEL); | ||
2344 | |||
2345 | if (rq) { | ||
2346 | rq->mrq.cmd = &rq->cmd; | ||
2347 | rq->mrq.data = &rq->data; | ||
2348 | rq->mrq.stop = &rq->stop; | ||
2349 | } | ||
2350 | |||
2351 | return rq; | ||
2352 | } | ||
2353 | |||
2354 | static int mmc_test_send_status(struct mmc_test_card *test, | 2339 | static int mmc_test_send_status(struct mmc_test_card *test, |
2355 | struct mmc_command *cmd) | 2340 | struct mmc_command *cmd) |
2356 | { | 2341 | { |