~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/mmc/card/mmc_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
 * @sectors: amount of sectors to check in one group
89
89
 * @ts: time values of transfer
90
90
 * @rate: calculated transfer rate
 
91
 * @iops: I/O operations per second (times 100)
91
92
 */
92
93
struct mmc_test_transfer_result {
93
94
        struct list_head link;
95
96
        unsigned int sectors;
96
97
        struct timespec ts;
97
98
        unsigned int rate;
 
99
        unsigned int iops;
98
100
};
99
101
 
100
102
/**
226
228
 
227
229
                if (!busy && mmc_test_busy(&cmd)) {
228
230
                        busy = 1;
229
 
                        printk(KERN_INFO "%s: Warning: Host did not "
230
 
                                "wait for busy state to end.\n",
231
 
                                mmc_hostname(test->card->host));
 
231
                        if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
 
232
                                printk(KERN_INFO "%s: Warning: Host did not "
 
233
                                        "wait for busy state to end.\n",
 
234
                                        mmc_hostname(test->card->host));
232
235
                }
233
236
        } while (mmc_test_busy(&cmd));
234
237
 
289
292
}
290
293
 
291
294
/*
292
 
 * Allocate a lot of memory, preferrably max_sz but at least min_sz.  In case
 
295
 * Allocate a lot of memory, preferably max_sz but at least min_sz.  In case
293
296
 * there isn't much memory do not exceed 1/16th total lowmem pages.  Also do
294
297
 * not exceed a maximum number of segments and try not to make segments much
295
298
 * bigger than maximum segment size.
494
497
 */
495
498
static void mmc_test_save_transfer_result(struct mmc_test_card *test,
496
499
        unsigned int count, unsigned int sectors, struct timespec ts,
497
 
        unsigned int rate)
 
500
        unsigned int rate, unsigned int iops)
498
501
{
499
502
        struct mmc_test_transfer_result *tr;
500
503
 
509
512
        tr->sectors = sectors;
510
513
        tr->ts = ts;
511
514
        tr->rate = rate;
 
515
        tr->iops = iops;
512
516
 
513
517
        list_add_tail(&tr->link, &test->gr->tr_lst);
514
518
}
519
523
static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes,
520
524
                                struct timespec *ts1, struct timespec *ts2)
521
525
{
522
 
        unsigned int rate, sectors = bytes >> 9;
 
526
        unsigned int rate, iops, sectors = bytes >> 9;
523
527
        struct timespec ts;
524
528
 
525
529
        ts = timespec_sub(*ts2, *ts1);
526
530
 
527
531
        rate = mmc_test_rate(bytes, &ts);
 
532
        iops = mmc_test_rate(100, &ts); /* I/O ops per sec x 100 */
528
533
 
529
534
        printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu "
530
 
                         "seconds (%u kB/s, %u KiB/s)\n",
 
535
                         "seconds (%u kB/s, %u KiB/s, %u.%02u IOPS)\n",
531
536
                         mmc_hostname(test->card->host), sectors, sectors >> 1,
532
537
                         (sectors & 1 ? ".5" : ""), (unsigned long)ts.tv_sec,
533
 
                         (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024);
 
538
                         (unsigned long)ts.tv_nsec, rate / 1000, rate / 1024,
 
539
                         iops / 100, iops % 100);
534
540
 
535
 
        mmc_test_save_transfer_result(test, 1, sectors, ts, rate);
 
541
        mmc_test_save_transfer_result(test, 1, sectors, ts, rate, iops);
536
542
}
537
543
 
538
544
/*
542
548
                                    unsigned int count, struct timespec *ts1,
543
549
                                    struct timespec *ts2)
544
550
{
545
 
        unsigned int rate, sectors = bytes >> 9;
 
551
        unsigned int rate, iops, sectors = bytes >> 9;
546
552
        uint64_t tot = bytes * count;
547
553
        struct timespec ts;
548
554
 
549
555
        ts = timespec_sub(*ts2, *ts1);
550
556
 
551
557
        rate = mmc_test_rate(tot, &ts);
 
558
        iops = mmc_test_rate(count * 100, &ts); /* I/O ops per sec x 100 */
552
559
 
553
560
        printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took "
554
 
                         "%lu.%09lu seconds (%u kB/s, %u KiB/s)\n",
 
561
                         "%lu.%09lu seconds (%u kB/s, %u KiB/s, "
 
562
                         "%u.%02u IOPS)\n",
555
563
                         mmc_hostname(test->card->host), count, sectors, count,
556
564
                         sectors >> 1, (sectors & 1 ? ".5" : ""),
557
565
                         (unsigned long)ts.tv_sec, (unsigned long)ts.tv_nsec,
558
 
                         rate / 1000, rate / 1024);
 
566
                         rate / 1000, rate / 1024, iops / 100, iops % 100);
559
567
 
560
 
        mmc_test_save_transfer_result(test, count, sectors, ts, rate);
 
568
        mmc_test_save_transfer_result(test, count, sectors, ts, rate, iops);
561
569
}
562
570
 
563
571
/*
1425
1433
}
1426
1434
 
1427
1435
/*
1428
 
 * Initialize an area for testing large transfers.  The size of the area is the
1429
 
 * preferred erase size which is a good size for optimal transfer speed.  Note
1430
 
 * that is typically 4MiB for modern cards.  The test area is set to the middle
1431
 
 * of the card because cards may have different charateristics at the front
1432
 
 * (for FAT file system optimization).  Optionally, the area is erased (if the
1433
 
 * card supports it) which may improve write performance.  Optionally, the area
1434
 
 * is filled with data for subsequent read tests.
 
1436
 * Initialize an area for testing large transfers.  The test area is set to the
 
1437
 * middle of the card because cards may have different charateristics at the
 
1438
 * front (for FAT file system optimization).  Optionally, the area is erased
 
1439
 * (if the card supports it) which may improve write performance.  Optionally,
 
1440
 * the area is filled with data for subsequent read tests.
1435
1441
 */
1436
1442
static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill)
1437
1443
{
1438
1444
        struct mmc_test_area *t = &test->area;
1439
 
        unsigned long min_sz = 64 * 1024;
 
1445
        unsigned long min_sz = 64 * 1024, sz;
1440
1446
        int ret;
1441
1447
 
1442
1448
        ret = mmc_test_set_blksize(test, 512);
1443
1449
        if (ret)
1444
1450
                return ret;
1445
1451
 
1446
 
        if (test->card->pref_erase > TEST_AREA_MAX_SIZE >> 9)
1447
 
                t->max_sz = TEST_AREA_MAX_SIZE;
1448
 
        else
1449
 
                t->max_sz = (unsigned long)test->card->pref_erase << 9;
 
1452
        /* Make the test area size about 4MiB */
 
1453
        sz = (unsigned long)test->card->pref_erase << 9;
 
1454
        t->max_sz = sz;
 
1455
        while (t->max_sz < 4 * 1024 * 1024)
 
1456
                t->max_sz += sz;
 
1457
        while (t->max_sz > TEST_AREA_MAX_SIZE && t->max_sz > sz)
 
1458
                t->max_sz -= sz;
1450
1459
 
1451
1460
        t->max_segs = test->card->host->max_segs;
1452
1461
        t->max_seg_sz = test->card->host->max_seg_size;
1766
1775
        return 0;
1767
1776
}
1768
1777
 
 
1778
static unsigned int rnd_next = 1;
 
1779
 
 
1780
static unsigned int mmc_test_rnd_num(unsigned int rnd_cnt)
 
1781
{
 
1782
        uint64_t r;
 
1783
 
 
1784
        rnd_next = rnd_next * 1103515245 + 12345;
 
1785
        r = (rnd_next >> 16) & 0x7fff;
 
1786
        return (r * rnd_cnt) >> 15;
 
1787
}
 
1788
 
 
1789
static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
 
1790
                             unsigned long sz)
 
1791
{
 
1792
        unsigned int dev_addr, cnt, rnd_addr, range1, range2, last_ea = 0, ea;
 
1793
        unsigned int ssz;
 
1794
        struct timespec ts1, ts2, ts;
 
1795
        int ret;
 
1796
 
 
1797
        ssz = sz >> 9;
 
1798
 
 
1799
        rnd_addr = mmc_test_capacity(test->card) / 4;
 
1800
        range1 = rnd_addr / test->card->pref_erase;
 
1801
        range2 = range1 / ssz;
 
1802
 
 
1803
        getnstimeofday(&ts1);
 
1804
        for (cnt = 0; cnt < UINT_MAX; cnt++) {
 
1805
                getnstimeofday(&ts2);
 
1806
                ts = timespec_sub(ts2, ts1);
 
1807
                if (ts.tv_sec >= 10)
 
1808
                        break;
 
1809
                ea = mmc_test_rnd_num(range1);
 
1810
                if (ea == last_ea)
 
1811
                        ea -= 1;
 
1812
                last_ea = ea;
 
1813
                dev_addr = rnd_addr + test->card->pref_erase * ea +
 
1814
                           ssz * mmc_test_rnd_num(range2);
 
1815
                ret = mmc_test_area_io(test, sz, dev_addr, write, 0, 0);
 
1816
                if (ret)
 
1817
                        return ret;
 
1818
        }
 
1819
        if (print)
 
1820
                mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
 
1821
        return 0;
 
1822
}
 
1823
 
 
1824
static int mmc_test_random_perf(struct mmc_test_card *test, int write)
 
1825
{
 
1826
        unsigned int next;
 
1827
        unsigned long sz;
 
1828
        int ret;
 
1829
 
 
1830
        for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
 
1831
                /*
 
1832
                 * When writing, try to get more consistent results by running
 
1833
                 * the test twice with exactly the same I/O but outputting the
 
1834
                 * results only for the 2nd run.
 
1835
                 */
 
1836
                if (write) {
 
1837
                        next = rnd_next;
 
1838
                        ret = mmc_test_rnd_perf(test, write, 0, sz);
 
1839
                        if (ret)
 
1840
                                return ret;
 
1841
                        rnd_next = next;
 
1842
                }
 
1843
                ret = mmc_test_rnd_perf(test, write, 1, sz);
 
1844
                if (ret)
 
1845
                        return ret;
 
1846
        }
 
1847
        sz = test->area.max_tfr;
 
1848
        if (write) {
 
1849
                next = rnd_next;
 
1850
                ret = mmc_test_rnd_perf(test, write, 0, sz);
 
1851
                if (ret)
 
1852
                        return ret;
 
1853
                rnd_next = next;
 
1854
        }
 
1855
        return mmc_test_rnd_perf(test, write, 1, sz);
 
1856
}
 
1857
 
 
1858
/*
 
1859
 * Random read performance by transfer size.
 
1860
 */
 
1861
static int mmc_test_random_read_perf(struct mmc_test_card *test)
 
1862
{
 
1863
        return mmc_test_random_perf(test, 0);
 
1864
}
 
1865
 
 
1866
/*
 
1867
 * Random write performance by transfer size.
 
1868
 */
 
1869
static int mmc_test_random_write_perf(struct mmc_test_card *test)
 
1870
{
 
1871
        return mmc_test_random_perf(test, 1);
 
1872
}
 
1873
 
 
1874
static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
 
1875
                             unsigned int tot_sz, int max_scatter)
 
1876
{
 
1877
        unsigned int dev_addr, i, cnt, sz, ssz;
 
1878
        struct timespec ts1, ts2;
 
1879
        int ret;
 
1880
 
 
1881
        sz = test->area.max_tfr;
 
1882
        /*
 
1883
         * In the case of a maximally scattered transfer, the maximum transfer
 
1884
         * size is further limited by using PAGE_SIZE segments.
 
1885
         */
 
1886
        if (max_scatter) {
 
1887
                struct mmc_test_area *t = &test->area;
 
1888
                unsigned long max_tfr;
 
1889
 
 
1890
                if (t->max_seg_sz >= PAGE_SIZE)
 
1891
                        max_tfr = t->max_segs * PAGE_SIZE;
 
1892
                else
 
1893
                        max_tfr = t->max_segs * t->max_seg_sz;
 
1894
                if (sz > max_tfr)
 
1895
                        sz = max_tfr;
 
1896
        }
 
1897
 
 
1898
        ssz = sz >> 9;
 
1899
        dev_addr = mmc_test_capacity(test->card) / 4;
 
1900
        if (tot_sz > dev_addr << 9)
 
1901
                tot_sz = dev_addr << 9;
 
1902
        cnt = tot_sz / sz;
 
1903
        dev_addr &= 0xffff0000; /* Round to 64MiB boundary */
 
1904
 
 
1905
        getnstimeofday(&ts1);
 
1906
        for (i = 0; i < cnt; i++) {
 
1907
                ret = mmc_test_area_io(test, sz, dev_addr, write,
 
1908
                                       max_scatter, 0);
 
1909
                if (ret)
 
1910
                        return ret;
 
1911
                dev_addr += ssz;
 
1912
        }
 
1913
        getnstimeofday(&ts2);
 
1914
 
 
1915
        mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
 
1916
 
 
1917
        return 0;
 
1918
}
 
1919
 
 
1920
static int mmc_test_large_seq_perf(struct mmc_test_card *test, int write)
 
1921
{
 
1922
        int ret, i;
 
1923
 
 
1924
        for (i = 0; i < 10; i++) {
 
1925
                ret = mmc_test_seq_perf(test, write, 10 * 1024 * 1024, 1);
 
1926
                if (ret)
 
1927
                        return ret;
 
1928
        }
 
1929
        for (i = 0; i < 5; i++) {
 
1930
                ret = mmc_test_seq_perf(test, write, 100 * 1024 * 1024, 1);
 
1931
                if (ret)
 
1932
                        return ret;
 
1933
        }
 
1934
        for (i = 0; i < 3; i++) {
 
1935
                ret = mmc_test_seq_perf(test, write, 1000 * 1024 * 1024, 1);
 
1936
                if (ret)
 
1937
                        return ret;
 
1938
        }
 
1939
 
 
1940
        return ret;
 
1941
}
 
1942
 
 
1943
/*
 
1944
 * Large sequential read performance.
 
1945
 */
 
1946
static int mmc_test_large_seq_read_perf(struct mmc_test_card *test)
 
1947
{
 
1948
        return mmc_test_large_seq_perf(test, 0);
 
1949
}
 
1950
 
 
1951
/*
 
1952
 * Large sequential write performance.
 
1953
 */
 
1954
static int mmc_test_large_seq_write_perf(struct mmc_test_card *test)
 
1955
{
 
1956
        return mmc_test_large_seq_perf(test, 1);
 
1957
}
 
1958
 
1769
1959
static const struct mmc_test_case mmc_test_cases[] = {
1770
1960
        {
1771
1961
                .name = "Basic write (no data verification)",
2005
2195
                .cleanup = mmc_test_area_cleanup,
2006
2196
        },
2007
2197
 
 
2198
        {
 
2199
                .name = "Random read performance by transfer size",
 
2200
                .prepare = mmc_test_area_prepare,
 
2201
                .run = mmc_test_random_read_perf,
 
2202
                .cleanup = mmc_test_area_cleanup,
 
2203
        },
 
2204
 
 
2205
        {
 
2206
                .name = "Random write performance by transfer size",
 
2207
                .prepare = mmc_test_area_prepare,
 
2208
                .run = mmc_test_random_write_perf,
 
2209
                .cleanup = mmc_test_area_cleanup,
 
2210
        },
 
2211
 
 
2212
        {
 
2213
                .name = "Large sequential read into scattered pages",
 
2214
                .prepare = mmc_test_area_prepare,
 
2215
                .run = mmc_test_large_seq_read_perf,
 
2216
                .cleanup = mmc_test_area_cleanup,
 
2217
        },
 
2218
 
 
2219
        {
 
2220
                .name = "Large sequential write from scattered pages",
 
2221
                .prepare = mmc_test_area_prepare,
 
2222
                .run = mmc_test_large_seq_write_perf,
 
2223
                .cleanup = mmc_test_area_cleanup,
 
2224
        },
 
2225
 
2008
2226
};
2009
2227
 
2010
2228
static DEFINE_MUTEX(mmc_test_lock);
2148
2366
                seq_printf(sf, "Test %d: %d\n", gr->testcase + 1, gr->result);
2149
2367
 
2150
2368
                list_for_each_entry(tr, &gr->tr_lst, link) {
2151
 
                        seq_printf(sf, "%u %d %lu.%09lu %u\n",
 
2369
                        seq_printf(sf, "%u %d %lu.%09lu %u %u.%02u\n",
2152
2370
                                tr->count, tr->sectors,
2153
2371
                                (unsigned long)tr->ts.tv_sec,
2154
2372
                                (unsigned long)tr->ts.tv_nsec,
2155
 
                                tr->rate);
 
2373
                                tr->rate, tr->iops / 100, tr->iops % 100);
2156
2374
                }
2157
2375
        }
2158
2376