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>
This commit is contained in:
Adrian Hunter 2023-12-14 11:09:02 +02:00 committed by Ulf Hansson
parent 84a6be7db9
commit b062136d0d

View file

@ -1904,7 +1904,7 @@ static unsigned int mmc_test_rnd_num(unsigned int rnd_cnt)
}
static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
unsigned long sz)
unsigned long sz, int secs, int force_retuning)
{
unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea;
unsigned int ssz;
@ -1921,7 +1921,7 @@ static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
for (cnt = 0; cnt < UINT_MAX; cnt++) {
ktime_get_ts64(&ts2);
ts = timespec64_sub(ts2, ts1);
if (ts.tv_sec >= 10)
if (ts.tv_sec >= secs)
break;
ea = mmc_test_rnd_num(range1);
if (ea == last_ea)
@ -1929,6 +1929,8 @@ static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
last_ea = ea;
dev_addr = rnd_addr + test->card->pref_erase * ea +
ssz * mmc_test_rnd_num(range2);
if (force_retuning)
mmc_retune_needed(test->card->host);
ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0);
if (ret)
return ret;
@ -1953,24 +1955,35 @@ static int mmc_test_random_perf(struct mmc_test_card *test, int write)
*/
if (write) {
next = rnd_next;
ret = mmc_test_rnd_perf(test, write, 0, sz);
ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0);
if (ret)
return ret;
rnd_next = next;
}
ret = mmc_test_rnd_perf(test, write, 1, sz);
ret = mmc_test_rnd_perf(test, write, 1, sz, 10, 0);
if (ret)
return ret;
}
sz = t->max_tfr;
if (write) {
next = rnd_next;
ret = mmc_test_rnd_perf(test, write, 0, sz);
ret = mmc_test_rnd_perf(test, write, 0, sz, 10, 0);
if (ret)
return ret;
rnd_next = next;
}
return mmc_test_rnd_perf(test, write, 1, sz);
return mmc_test_rnd_perf(test, write, 1, sz, 10, 0);
}
static int mmc_test_retuning(struct mmc_test_card *test)
{
if (!mmc_can_retune(test->card->host)) {
pr_info("%s: No retuning - test skipped\n",
mmc_hostname(test->card->host));
return RESULT_UNSUP_HOST;
}
return mmc_test_rnd_perf(test, 0, 0, 8192, 30, 1);
}
/*
@ -2921,6 +2934,14 @@ static const struct mmc_test_case mmc_test_cases[] = {
.run = mmc_test_cmds_during_write_cmd23_nonblock,
.cleanup = mmc_test_area_cleanup,
},
{
.name = "Re-tuning reliability",
.prepare = mmc_test_area_prepare,
.run = mmc_test_retuning,
.cleanup = mmc_test_area_cleanup,
},
};
static DEFINE_MUTEX(mmc_test_lock);