• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python2
2#
3# Copyright (c) 2010 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# Note: this test has been ported to hardware.MemCheck Tast test.
8# Any change made here should be applied to the Tast test as well.
9
10__author__ = 'kdlucas@chromium.org (Kelly Lucas)'
11
12import logging, re
13
14from autotest_lib.client.bin import utils, test
15from autotest_lib.client.common_lib import error
16
17
18class platform_MemCheck(test.test):
19    """
20    Verify memory usage looks correct.
21    """
22    version = 1
23    swap_disksize_file = '/sys/block/zram0/disksize'
24
25    def run_once(self):
26        errors = 0
27        keyval = dict()
28        # The total memory will shrink if the system bios grabs more of the
29        # reserved memory. We derived the value below by giving a small
30        # cushion to allow for more system BIOS usage of ram. The memref value
31        # is driven by the supported netbook model with the least amount of
32        # total memory.  ARM and x86 values differ considerably.
33        cpuType = utils.get_cpu_arch()
34        memref = 986392
35        vmemref = 102400
36        if cpuType == "arm":
37            memref = 700000
38            vmemref = 210000
39
40        speedref = 1333
41        os_reserve_min = 600000
42        os_reserve_ratio = 0.04
43
44        # size reported in /sys/block/zram0/disksize is in byte
45        swapref = int(utils.read_one_line(self.swap_disksize_file)) / 1024
46
47        less_refs = ['MemTotal', 'VmallocTotal']
48        approx_refs = ['SwapTotal']
49
50        # read physical HW size from mosys and adjust memref if need
51        cmd = 'mosys memory spd print geometry -s size_mb'
52        phy_size_run = utils.run(cmd)
53        phy_size = 0
54        for line in phy_size_run.stdout.split():
55            phy_size += int(line)
56        # memref is in KB but phy_size is in MB
57        phy_size *= 1024
58        keyval['PhysicalSize'] = phy_size
59
60        # scale OS reserve size with memory size
61        os_reserve = max(os_reserve_min, int(phy_size * os_reserve_ratio))
62        memref = max(memref, phy_size - os_reserve)
63
64        ref = {'MemTotal': memref,
65               'SwapTotal': swapref,
66               'VmallocTotal': vmemref,
67              }
68
69        board = utils.get_board()
70        logging.info('board: %s, phy_size: %d memref: %d',
71                      board, phy_size, memref)
72
73        error_list = []
74
75        for k in ref:
76            value = utils.read_from_meminfo(k)
77            keyval[k] = value
78            if k in less_refs:
79                if value < ref[k]:
80                    logging.warning('%s is %d', k, value)
81                    logging.warning('%s should be at least %d', k, ref[k])
82                    errors += 1
83                    error_list += [k]
84            elif k in approx_refs:
85                if value < ref[k] * 0.9 or ref[k] * 1.1 < value:
86                    logging.warning('%s is %d', k, value)
87                    logging.warning('%s should be within 10%% of %d', k, ref[k])
88                    errors += 1
89                    error_list += [k]
90
91        # read spd timings
92        cmd = 'mosys memory spd print timings -s speeds'
93        # result example
94        # DDR3-800, DDR3-1066, DDR3-1333, DDR3-1600
95        pattern = '[A-Z]*DDR([3-9]|[1-9]\d+)[A-Z]*-(?P<speed>\d+)'
96        timing_run = utils.run(cmd)
97
98        keyval['speedref'] = speedref
99        for dimm, line in enumerate(timing_run.stdout.split('\n')):
100            if not line:
101                continue
102            max_timing = line.split(', ')[-1]
103            keyval['timing_dimm_%d' % dimm] = max_timing
104            m = re.match(pattern, max_timing)
105            if not m:
106                logging.warning('Error parsing timings for dimm #%d (%s)',
107                             dimm, max_timing)
108                errors += 1
109                continue
110            logging.info('dimm #%d timings: %s', dimm, max_timing)
111            max_speed = int(m.group('speed'))
112            keyval['speed_dimm_%d' % dimm] = max_speed
113            if max_speed < speedref:
114                logging.warning('ram speed is %s', max_timing)
115                logging.warning('ram speed should be at least %d', speedref)
116                error_list += ['speed_dimm_%d' % dimm]
117                errors += 1
118
119        # Log memory ids
120        cmd = 'mosys memory spd print id'
121        # result example (1 module of memory per result line)
122        # 0 | 1-45: SK Hynix (Hyundai) | 128d057e | HMT425S6CFR6A-PB
123        # 1 | 1-45: SK Hynix (Hyundai) | 121d0581 | HMT425S6CFR6A-PB
124        mem_ids = utils.run(cmd).stdout.split('\n')
125        for dimm, line in enumerate(mem_ids):
126            if not line:
127                continue
128            keyval['memory_id_dimm_%d' % dimm] = line
129
130        if board.startswith('rambi') or board.startswith('expresso'):
131            logging.info('Skipping test on rambi and expresso, '
132                         'see crbug.com/411401')
133        elif errors > 0:
134            # If self.error is not zero, there were errors.
135            error_list_str = ', '.join(error_list)
136            raise error.TestFail('Found incorrect values: %s' % error_list_str)
137
138        self.write_perf_keyval(keyval)
139