1# Lint as: python2, python3 2# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging, re, struct, sys, time 7 8from autotest_lib.client.bin import test, utils 9from autotest_lib.client.common_lib import error 10 11def memory_channel_args_snb_bdw(channel_modules): 12 """Add arguments for memory testing. 13 Works on sandybridge, ivybridge, broadwell. Maybe others? 14 15 @param channel_modules: channel names. 16 """ 17 18 with open('/proc/bus/pci/00/00.0', 'r', 0) as fd: 19 fd.seek(0x48) 20 mchbar = struct.unpack('=I', fd.read(4))[0] 21 if not mchbar & 1: 22 raise error.TestError('Host Memory Mapped Register Range not enabled.') 23 mchbar &= ~1 24 25 with open('/dev/mem', 'r', 0) as fd: 26 fd.seek(mchbar + 0x5000) 27 mad_chnl = struct.unpack('=I', fd.read(4))[0] 28 fd.seek(mchbar + 0x5024) 29 channel_hash = struct.unpack('=I', fd.read(4))[0] 30 31 if (mad_chnl >> 4) & 3 != 2: 32 raise error.TestError('This test does not support triple-channel mode.') 33 if mad_chnl & 3 == 0 and (mad_chnl >> 2) & 3 == 1: 34 channel_order = [0, 1] 35 elif mad_chnl & 3 == 1 and (mad_chnl >> 2) & 3 == 0: 36 logging.warning('Non-default memory channel configuration... please ' 37 'double-check that this is correct and intended.') 38 channel_order = [1, 0] 39 else: 40 raise error.TestError('Invalid channel configuration: %x' % mad_chnl) 41 42 if not channel_hash & (1 << 23): 43 logging.warning('Memory channel_hash deactivated... going with cache-line ' 44 'sized ping-pong as a wild guess.') 45 channel_hash = 1 46 channel_hash = (channel_hash & 0x3FFF) << 6 47 48 return (' --memory_channel %s --memory_channel %s --channel_hash 0x%x' 49 ' --channel_width 64' % ( 50 ','.join(channel_modules[channel_order[0]]), 51 ','.join(channel_modules[channel_order[1]]), 52 channel_hash)) 53 54 55class hardware_SAT(test.test): 56 """Run SAT.""" 57 58 version = 1 59 60 61 def run_once(self, seconds=60, free_memory_fraction=0.95, wait_secs=0, 62 disk_thread=True): 63 ''' 64 Args: 65 free_memory_fraction: Fraction of free memory (as determined by 66 utils.freememtotal()) to use. 67 wait_secs: time to wait in seconds before executing stressapptest. 68 disk_thread: also stress disk using -f argument of stressapptest. 69 ''' 70 assert free_memory_fraction > 0 71 assert free_memory_fraction < 1 72 73 # Wait other parallel tests memory usage to settle to a stable value, so 74 # stressapptest will not claim too much memory. 75 if wait_secs: 76 time.sleep(wait_secs) 77 78 # Allow shmem access to all of memory. This is used for 32 bit 79 # access to > 1.4G. Virtual address space limitation prevents 80 # directly mapping the memory. 81 utils.run('mount -o remount,size=100% /dev/shm') 82 cpus = max(utils.count_cpus(), 1) 83 mbytes = max(int(utils.freememtotal() * free_memory_fraction / 1024), 84 512) 85 # Even though shared memory allows us to go past the 1.4G 86 # limit, ftruncate still limits us to 2G max on 32 bit systems. 87 if sys.maxsize < 2**32 and mbytes > 2047: 88 mbytes = 2047 89 # SAT should use as much memory as possible, while still 90 # avoiding OOMs and allowing the kernel to run, so that 91 # the maximum amoun tof memory can be tested. 92 args = ' -M %d' % mbytes # megabytes to test 93 # The number of seconds under test can be chosen to fit into 94 # manufacturing or test flow. 60 seconds gives several 95 # passes and several patterns over each memory location 96 # and should catch clearly fautly memeory. 4 hours 97 # is an effective runin test, to catch lower frequency errors. 98 args += ' -s %d' % seconds # seconds to run 99 # One memory copy thread per CPU should keep the memory bus 100 # as saturated as possible, while keeping each CPU busy as well. 101 args += ' -m %d' % cpus # memory copy threads. 102 # SSE copy and checksum increases the rate at which the CPUs 103 # can drive memory, as well as stressing the CPU. 104 args += ' -W' # Use SSE optimizatin in memory threads. 105 # File IO threads allow stressful transactions over the 106 # south bridge and SATA, as well as potentially finding SSD 107 # or disk cache problems. Two threads ensure multiple 108 # outstanding transactions to the disk, if supported. 109 if disk_thread: 110 args += ' -f sat.diskthread.a' # disk thread 111 args += ' -f sat.diskthread.b' 112 113 if utils.get_board() == 'link': 114 args += memory_channel_args_snb_bdw([ 115 ['U1', 'U2', 'U3', 'U4'], 116 ['U6', 'U5', 'U7', 'U8']]) # yes, U6 is actually before U5 117 118 if utils.get_board() == 'samus': 119 args += memory_channel_args_snb_bdw([ 120 ['U11', 'U12'], 121 ['U13', 'U14']]) 122 123 # 'stressapptest' is provided by dev-util/stressapptest, pre-installed 124 # in test images. 125 sat = utils.run('stressapptest' + args) 126 logging.debug(sat.stdout) 127 if not re.search('Status: PASS', sat.stdout): 128 raise error.TestFail(sat.stdout) 129