1092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov# Use of this source code is governed by a BSD-style license that can be
3092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov# found in the LICENSE file.
4092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov
502e63522f995a93f0d2ca569a587f08c14b421b1Hung-Te Linimport logging, re, struct, sys, time
6092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov
7092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkovfrom autotest_lib.client.bin import test, utils
8092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkovfrom autotest_lib.client.common_lib import error
9092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov
1058ed26dde0afc9039fed682c0640027e2509efb3Nick Sandersdef memory_channel_args_snb_bdw(channel_modules):
116d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou    """Add arguments for memory testing.
1258ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders    Works on sandybridge, ivybridge, broadwell. Maybe others?
136d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou
146d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou    @param channel_modules: channel names.
156d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou    """
166d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou
17733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    with open('/proc/bus/pci/00/00.0', 'r', 0) as fd:
18733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        fd.seek(0x48)
19733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        mchbar = struct.unpack('=I', fd.read(4))[0]
20733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    if not mchbar & 1:
21733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        raise error.TestError('Host Memory Mapped Register Range not enabled.')
22733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    mchbar &= ~1
23733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
24733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    with open('/dev/mem', 'r', 0) as fd:
25733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        fd.seek(mchbar + 0x5000)
26733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        mad_chnl = struct.unpack('=I', fd.read(4))[0]
27733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        fd.seek(mchbar + 0x5024)
28733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        channel_hash = struct.unpack('=I', fd.read(4))[0]
29733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
30733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    if (mad_chnl >> 4) & 3 != 2:
31733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        raise error.TestError('This test does not support triple-channel mode.')
32733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    if mad_chnl & 3 == 0 and (mad_chnl >> 2) & 3 == 1:
33733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        channel_order = [0, 1]
34733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    elif mad_chnl & 3 == 1 and (mad_chnl >> 2) & 3 == 0:
3504be2bd5e4666a5c253e9c30ab20555e04286032Ilja H. Friedel        logging.warning('Non-default memory channel configuration... please '
36733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                     'double-check that this is correct and intended.')
37733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        channel_order = [1, 0]
38733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    else:
39733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        raise error.TestError('Invalid channel configuration: %x' % mad_chnl)
40733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
41733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    if not channel_hash & (1 << 23):
4204be2bd5e4666a5c253e9c30ab20555e04286032Ilja H. Friedel        logging.warning('Memory channel_hash deactivated... going with cache-line '
43733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                     'sized ping-pong as a wild guess.')
44733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner        channel_hash = 1
45733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    channel_hash = (channel_hash & 0x3FFF) << 6
46733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
47733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner    return (' --memory_channel %s --memory_channel %s --channel_hash 0x%x'
48733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner            ' --channel_width 64' % (
49733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                    ','.join(channel_modules[channel_order[0]]),
50733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                    ','.join(channel_modules[channel_order[1]]),
51733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                    channel_hash))
52733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
53733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
5436f1a65e6eb9ab85144d0e917380d2c695e14fe8Ken Mixterclass hardware_SAT(test.test):
556d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou    """Run SAT."""
566d16720261053844ada8df7547d09b6d698fbd60Gwendal Grignou
57092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov    version = 1
58092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov
59092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov
6005724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang    def run_once(self, seconds=60, free_memory_fraction=0.95, wait_secs=0,
6105724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang                 disk_thread=True):
62a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        '''
63a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        Args:
64a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz          free_memory_fraction: Fraction of free memory (as determined by
65a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz            utils.freememtotal()) to use.
6642e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang          wait_secs: time to wait in seconds before executing stressapptest.
6705724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang          disk_thread: also stress disk using -f argument of stressapptest.
68a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        '''
69a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        assert free_memory_fraction > 0
70a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        assert free_memory_fraction < 1
71a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz
7242e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang        # Wait other parallel tests memory usage to settle to a stable value, so
7342e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang        # stressapptest will not claim too much memory.
7442e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang        if wait_secs:
7542e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang            time.sleep(wait_secs)
7642e511a30dd0cbfee77870590f0b708972876874Cheng-Yi Chiang
773e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # Allow shmem access to all of memory. This is used for 32 bit
783e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # access to > 1.4G. Virtual address space limitation prevents
793e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # directly mapping the memory.
803e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        utils.run('mount -o remount,size=100% /dev/shm')
81092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov        cpus = max(utils.count_cpus(), 1)
82a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz        mbytes = max(int(utils.freememtotal() * free_memory_fraction / 1024),
83a8f7dd358bb67f69118a297bf5054363baaefaecJon Salz                     512)
848a94f6dbf1505582f356c60d5c73a35715cd9446Paul Taysom        # Even though shared memory allows us to go past the 1.4G
858a94f6dbf1505582f356c60d5c73a35715cd9446Paul Taysom        # limit, ftruncate still limits us to 2G max on 32 bit systems.
868a94f6dbf1505582f356c60d5c73a35715cd9446Paul Taysom        if sys.maxsize < 2**32 and mbytes > 2047:
87733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner            mbytes = 2047
883e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # SAT should use as much memory as possible, while still
893e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # avoiding OOMs and allowing the kernel to run, so that
903e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # the maximum amoun tof memory can be tested.
9109fa9ef202ab5d9258308e56102992d6bc007d59Darin Petkov        args = ' -M %d' % mbytes  # megabytes to test
923e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # The number of seconds under test can be chosen to fit into
933e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # manufacturing or test flow. 60 seconds gives several
943e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # passes and several patterns over each memory location
953e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # and should catch clearly fautly memeory. 4 hours
963e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # is an effective runin test, to catch lower frequency errors.
9709fa9ef202ab5d9258308e56102992d6bc007d59Darin Petkov        args += ' -s %d' % seconds  # seconds to run
983e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # One memory copy thread per CPU should keep the memory bus
993e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # as saturated as possible, while keeping each CPU busy as well.
1003e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        args += ' -m %d' % cpus  # memory copy threads.
1013e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # SSE copy and checksum increases the rate at which the CPUs
1023e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # can drive memory, as well as stressing the CPU.
1035234491b8d73a61e9f4ed78e68cdfac03344c4f4Nick Sanders        args += ' -W'  # Use SSE optimizatin in memory threads.
1043e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # File IO threads allow stressful transactions over the
1053e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # south bridge and SATA, as well as potentially finding SSD
1063e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # or disk cache problems. Two threads ensure multiple
1073e80452f0fa9b7011751878d1a6c3c27ec498db8Nick Sanders        # outstanding transactions to the disk, if supported.
10805724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang        if disk_thread:
10905724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang            args += ' -f sat.diskthread.a'  # disk thread
11005724ca2d899d1d3f41b3aa40a2d3c66b2a0fedaCheng-Yi Chiang            args += ' -f sat.diskthread.b'
11109fa9ef202ab5d9258308e56102992d6bc007d59Darin Petkov
11295c654bf995f60a0f44684702553d868d57fe2b4Julius Werner        if utils.get_board() == 'link':
11358ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders            args += memory_channel_args_snb_bdw([
114733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                    ['U1', 'U2', 'U3', 'U4'],
115733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner                    ['U6', 'U5', 'U7', 'U8']])  # yes, U6 is actually before U5
116733186471ef7ed9c9cf3824c89b298b4c997fa9cJulius Werner
11758ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders        if utils.get_board() == 'samus':
11858ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders            args += memory_channel_args_snb_bdw([
11958ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders                    ['U11', 'U12'],
12058ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders                    ['U13', 'U14']])
12158ed26dde0afc9039fed682c0640027e2509efb3Nick Sanders
12202e63522f995a93f0d2ca569a587f08c14b421b1Hung-Te Lin        # 'stressapptest' is provided by dev-util/stressapptest, pre-installed
12302e63522f995a93f0d2ca569a587f08c14b421b1Hung-Te Lin        # in test images.
12402e63522f995a93f0d2ca569a587f08c14b421b1Hung-Te Lin        sat = utils.run('stressapptest' + args)
125092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov        logging.debug(sat.stdout)
126092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov        if not re.search('Status: PASS', sat.stdout):
127092291e650f18938a76b6bcae33a0214b90c06cbDarin Petkov            raise error.TestFail(sat.stdout)
128