Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: mmc_test: Add re-tuning test

Add a test to repeatedly re-tune in between random reads. The test is
non-destructive of data on the card and runs for 30 seconds. It can be
repeated to test for longer durations.

If re-tuning is not supported, the test is skipped.

Example:

# echo 'mmc1:0001' > /sys/bus/mmc/drivers/mmcblk/unbind
# echo 'mmc1:0001' > /sys/bus/mmc/drivers/mmc_test/bind
[ 36.642257] mmc_test mmc1:0001: Card claimed for testing.
# cat /sys/kernel/debug/mmc1/mmc1\:0001/testlist | grep tuning
52: Re-tuning reliability
# echo 52 > /sys/kernel/debug/mmc1/mmc1\:0001/test
[ 91.522555] mmc1: Starting tests of card mmc1:0001...
[ 91.528425] mmc1: Test case 52. Re-tuning reliability...
[ 121.536682] mmc1: Result: OK
[ 121.539572] mmc1: Tests completed.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20231214090902.43628-1-adrian.hunter@intel.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Adrian Hunter and committed by
Ulf Hansson
b062136d 84a6be7d

+27 -6
+27 -6
drivers/mmc/core/mmc_test.c
··· 1904 1904 } 1905 1905 1906 1906 static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print, 1907 - unsigned long sz) 1907 + unsigned long sz, int secs, int force_retuning) 1908 1908 { 1909 1909 unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea; 1910 1910 unsigned int ssz; ··· 1921 1921 for (cnt = 0; cnt < UINT_MAX; cnt++) { 1922 1922 ktime_get_ts64(&ts2); 1923 1923 ts = timespec64_sub(ts2, ts1); 1924 - if (ts.tv_sec >= 10) 1924 + if (ts.tv_sec >= secs) 1925 1925 break; 1926 1926 ea = mmc_test_rnd_num(range1); 1927 1927 if (ea == last_ea) ··· 1929 1929 last_ea = ea; 1930 1930 dev_addr = rnd_addr + test->card->pref_erase * ea + 1931 1931 ssz * mmc_test_rnd_num(range2); 1932 + if (force_retuning) 1933 + mmc_retune_needed(test->card->host); 1932 1934 ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0); 1933 1935 if (ret) 1934 1936 return ret; ··· 1955 1953 */ 1956 1954 if (write) { 1957 1955 next = rnd_next; 1958 - ret = mmc_test_rnd_perf(test, write, 0, sz); 1956 + ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0); 1959 1957 if (ret) 1960 1958 return ret; 1961 1959 rnd_next = next; 1962 1960 } 1963 - ret = mmc_test_rnd_perf(test, write, 1, sz); 1961 + ret = mmc_test_rnd_perf(test, write, 1, sz, 10, 0); 1964 1962 if (ret) 1965 1963 return ret; 1966 1964 } 1967 1965 sz = t->max_tfr; 1968 1966 if (write) { 1969 1967 next = rnd_next; 1970 - ret = mmc_test_rnd_perf(test, write, 0, sz); 1968 + ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0); 1971 1969 if (ret) 1972 1970 return ret; 1973 1971 rnd_next = next; 1974 1972 } 1975 - return mmc_test_rnd_perf(test, write, 1, sz); 1973 + return mmc_test_rnd_perf(test, write, 1, sz, 10, 0); 1974 + } 1975 + 1976 + static int mmc_test_retuning(struct mmc_test_card *test) 1977 + { 1978 + if (!mmc_can_retune(test->card->host)) { 1979 + pr_info("%s: No retuning - test skipped\n", 1980 + mmc_hostname(test->card->host)); 1981 + return RESULT_UNSUP_HOST; 1982 + } 1983 + 1984 + return mmc_test_rnd_perf(test, 0, 0, 8192, 30, 1); 1976 1985 } 1977 1986 1978 1987 /* ··· 2934 2921 .run = mmc_test_cmds_during_write_cmd23_nonblock, 2935 2922 .cleanup = mmc_test_area_cleanup, 2936 2923 }, 2924 + 2925 + { 2926 + .name = "Re-tuning reliability", 2927 + .prepare = mmc_test_area_prepare, 2928 + .run = mmc_test_retuning, 2929 + .cleanup = mmc_test_area_cleanup, 2930 + }, 2931 + 2937 2932 }; 2938 2933 2939 2934 static DEFINE_MUTEX(mmc_test_lock);