def get_lwkmem(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 units = ['K', 'M', 'G', 'T', 'P', 'E'] total_size = 0 for token in op.split(): if token.startswith('lwkmem='): f, m, l = token.partition('=') l = l.strip() if l != '': for node_spec in l.split(','): node, delimiter, size = node_spec.partition(':') if delimiter == '': size = node size = size.strip() if size != '': multiplier = 1 if size.endswith(('K', 'M', 'G', 'T', 'P', 'E')): for u in units: index = size.find(u) if index != -1: multiplier = 1024**(1 + units.index(u)) break size = size.strip('KMGTPE') total_size += int(size) * multiplier return total_size
def test_invalid_spec(self): v = '3' if ARGS.test_debug else '0' spec = Spec() lwkcpus_spec = spec.create_lwkcpu_spec(0.90) self.assertNotEqual(lwkcpus_spec, 'lwkcpus=', 'Failed to create LWK partition spec') lwkmem_spec = spec.create_lwkmem_spec(0.90) self.assertNotEqual(lwkmem_spec, 'lwkmem=', 'Failed to create LWKMEM partition spec') invalid_lwkcpu_spec = [ lwkcpus_spec.strip('lwkcpus='), # Missing lwkcpus= lwkcpus_spec.strip('lwkcpus'), # Missing lwkcpus lwkcpus_spec.replace('lwkcpus', 'lwkcpu'), # Typo in lwkcpus lwkcpus_spec.replace('=', ' '), # Missing '=' sign lwkcpus_spec.replace('.', ',', 1), # Missing utility CPU to LWK CPU mapping lwkcpus_spec.replace(lwkcpus_spec, '@*$^)_!#'), # Total garbage ] if lwkcpus_spec.find(':') != -1: invalid_lwkcpu_spec += [lwkcpus_spec.replace( ':', ',', 1)] # Missing delimiter ':' between mappings ] for s in invalid_lwkcpu_spec: s = '{} {}'.format(s, lwkmem_spec) logging.debug('Testing spec: ' + s) out, rc = run(['lwkctl', '-v', v, '-c', s], requiresRoot=True) self.assertFalse( rc == 0, 'Created LWK partition for invalid spec: {}'.format(s))
def get_profile(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 for token in op.split(): if token.startswith('lwkcpu_profile='): f, m, l = token.partition('lwkcpu_profile=') return l return ''
def create_lwkmem_spec(self, ratio): def get_node_spec(node, size): if size <= 0: return '' unit = ['K', 'M', 'G', 'T', 'P', 'E'] q = size for i in range(0, len(unit)): q, r = divmod(q, 1024) if q == 0 or r != 0: break if i != 0: return '{}:{}{}'.format(int(node), size // (1 << (10 * i)), unit[i - 1]) else: return '{}:{}'.format(int(node), size) if lwkmem_static: op, rc = run(['lwkctl', '-v', '0', '-s', '-r']) for token in op.split(): if token.startswith('lwkmem='): if token != 'lwkmem=': return token return '' lwkmem_spec = 'lwkmem=' movable_mem = [] fname = '/proc/buddyinfo' for line in fileinput.input(fname, mode='r'): if line.startswith('Node'): tokens = line.split() if tokens[0] == 'Node' and tokens[3] == 'Movable': order = pages = 0 for t in tokens[4:]: pages += int(t) * (1 << order) order += 1 node = int(tokens[1].strip(' ,')) movable_mem += [(node, math.floor(pages * 4096 * ratio))] fileinput.close() for node, size in movable_mem: node_spec = get_node_spec(node, size) if node_spec != '': if lwkmem_spec != 'lwkmem=': lwkmem_spec += ',' lwkmem_spec += node_spec if lwkmem_spec == 'lwkmem=': return '' else: return lwkmem_spec
def test_busy_with_job(self): v = '3' if ARGS.test_debug else '0' lwkcpus_spec, utilcpus, lwkcpus = spec.create_lwkcpu_spec(0.90) self.assertNotEqual(lwkcpus_spec, 'lwkcpus=', 'Failed to create LWKCPU partition spec') # Request memory above what is available lwkmem_spec = spec.create_lwkmem_spec(0.9, True) self.assertNotEqual(lwkmem_spec, 'lwkmem=', 'Failed to create LWKMEM partition spec') # Insert a jobid into the RAS subsystem: rc = spec.write_to_ras_file('jobid', '1234567') self.assertTrue(rc, 'Could not write to jobid file.') # Try to create a partition with larger memory than available s = '{} {}'.format(lwkcpus_spec, lwkmem_spec) logging.debug('Testing LWK partition: {}'.format(s)) out, rc = run([ 'lwkctl', '-v', v, '-c', s, ], requiresRoot=True) self.assertFalse(rc == 0, 'Created LWK partition even though job is active.') out, rc = run(['lwkctl', '-v', v, '-c', s, '--force'], requiresRoot=True) self.assertTrue(rc == 0, 'Could not create LWK partition with --force.') rc = spec.write_to_ras_file('jobid', ' ') self.assertTrue(rc, 'Could not write to jobid file.')
def get_cpus(): utilcpus = CpuSet(0) lwkcpus = CpuSet(0) op, rc = run(['lwkctl', '-v', v, '-s']) lines = op.splitlines() for l in lines: if l.startswith('Utility CPU(s):'): f, m, s = l.partition('Utility CPU(s):') s = s.split('[')[0].strip() if s != '': utilcpus.fromList(s) if l.startswith('LWK CPU(s):'): f, m, s = l.partition('LWK CPU(s):') s = s.split('[')[0].strip() if s != '': lwkcpus.fromList(s) return utilcpus, lwkcpus
def test_invalid_partition(self): v = '3' if ARGS.test_debug else '0' spec = Spec() lwkcpus_spec = spec.create_lwkcpu_spec(0.90) self.assertNotEqual(lwkcpus_spec, 'lwkcpus=', 'Failed to create LWKCPU partition spec') lwkmem_spec = spec.create_lwkmem_spec(0.90) self.assertNotEqual(lwkmem_spec, 'lwkmem=', 'Failed to create LWKMEM partition spec') # Manufacture an invalid spec by adding invalid CPU numbers N = spec.n_cpus lwkcpus_spec += ':{}.{}-{}'.format(N, N+1, N+10) # Try to create a partition with CPUs which are not present s = '{} {}'.format(lwkcpus_spec, lwkmem_spec) logging.debug('Testing LWK partition: {}'.format(s)) out, rc = run(['sudo', 'lwkctl', '-v', v, '-c', s]) self.assertFalse(rc == 0, 'Created LWK partition for invalid spec: {}'.format(s))
def test_precise_yes(self): v = '3' if ARGS.test_debug else '0' lwkcpus_spec, utilcpus, lwkcpus = spec.create_lwkcpu_spec(0.90) self.assertNotEqual(lwkcpus_spec, 'lwkcpus=', 'Failed to create LWKCPU partition spec') # Request available memory lwkmem_spec = spec.create_lwkmem_spec(0.90, True) self.assertNotEqual(lwkmem_spec, 'lwkmem=', 'Failed to create LWKMEM partition spec') s = '{} {}'.format(lwkcpus_spec, lwkmem_spec) logging.debug('Testing LWK partition: {}'.format(s)) out, rc = run(['lwkctl', '-v', v, '-c', s, '-p', 'yes', '--force'], requiresRoot=True) self.assertTrue( rc == 0, 'Could not create precise partition with available memory: {}'. format(s))
def test_precise_no(self): v = '3' if ARGS.test_debug else '0' lwkcpus_spec, utilcpus, lwkcpus = spec.create_lwkcpu_spec(0.90) self.assertNotEqual(lwkcpus_spec, 'lwkcpus=', 'Failed to create LWKCPU partition spec') # Request memory above what is available lwkmem_spec = spec.create_lwkmem_spec(1.5) self.assertNotEqual(lwkmem_spec, 'lwkmem=', 'Failed to create LWKMEM partition spec') # Try to create a partition with larger memory than available s = '{} {}'.format(lwkcpus_spec, lwkmem_spec) logging.debug('Testing LWK partition: {}'.format(s)) out, rc = run(['lwkctl', '-v', v, '-c', s, '-p', 'no', '--force'], requiresRoot=True) self.assertTrue( rc == 0, 'Failed to create LWK partition for memory spec exceeding available: {}' .format(s))
def test_lwkreset_existence(self): out, rc = run(['lwkreset', '-h']) self.assertTrue(rc == 0, 'Could not locate lwkreset.')
def create_and_verify(obj, lwk_spec, utilcpus_req, lwkcpus_req, v='0', autogen=False): def get_cpus(): utilcpus = CpuSet(0) lwkcpus = CpuSet(0) op, rc = run(['lwkctl', '-v', v, '-s']) lines = op.splitlines() for l in lines: if l.startswith('Utility CPU(s):'): f, m, s = l.partition('Utility CPU(s):') s = s.split('[')[0].strip() if s != '': utilcpus.fromList(s) if l.startswith('LWK CPU(s):'): f, m, s = l.partition('LWK CPU(s):') s = s.split('[')[0].strip() if s != '': lwkcpus.fromList(s) return utilcpus, lwkcpus def get_profile(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 for token in op.split(): if token.startswith('lwkcpu_profile='): f, m, l = token.partition('lwkcpu_profile=') return l return '' def get_lwkmem(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 units = ['K', 'M', 'G', 'T', 'P', 'E'] total_size = 0 for token in op.split(): if token.startswith('lwkmem='): f, m, l = token.partition('=') l = l.strip() if l != '': for node_spec in l.split(','): node, delimiter, size = node_spec.partition(':') if delimiter == '': size = node size = size.strip() if size != '': multiplier = 1 if size.endswith(('K', 'M', 'G', 'T', 'P', 'E')): for u in units: index = size.find(u) if index != -1: multiplier = 1024**(1 + units.index(u)) break size = size.strip('KMGTPE') total_size += int(size) * multiplier return total_size def lwkcpus_auto(): with open('/sys/kernel/mOS/lwk_config', 'r') as f: data = f.read().rstrip('\n') m = re.search("auto=\S*cpu\S*", data) if m: return True return False def lwkmem_auto(): with open('/sys/kernel/mOS/lwk_config', 'r') as f: data = f.read().rstrip('\n') m = re.search("auto=\S*mem\S*", data) if m: return True return False # Create LWK partition lwk_spec = lwk_spec.strip() out, rc = run(['lwkctl', '-v', v, '-c', lwk_spec], requiresRoot=True) # Read and verify LWK partition using lwkctl -s # Verify CPUs lwkcpus_auto_set = lwkcpus_auto() if not autogen: utilcpus, lwkcpus = get_cpus() if utilcpus != utilcpus_req: logging.error('Mismatch : Syscall CPUs') logging.error('Requested: {}'.format(utilcpus_req.toList())) logging.error('Created : {}'.format(utilcpus.toList())) if lwkcpus != lwkcpus_req: logging.error('Mismatch : LWK CPUs') logging.error('Requested: {}'.format(lwkcpus_req.toList())) logging.error('Created : {}'.format(lwkcpus.toList())) if lwkcpus_auto_set: logging.error('The lwkcpus_auto indicator is set') assert (utilcpus == utilcpus_req) assert (lwkcpus == lwkcpus_req) assert (lwkcpus_auto_set == False) else: if not lwkcpus_auto_set: logging.error('The lwkcpus_auto indicator is not set') assert (lwkcpus_auto == True) # Verify LWK CPU profile profile_req = get_profile(lwk_spec) profile_set = get_profile() msg = 'LWKCPU profile requested: {} set: {}'.format( profile_req, profile_set) logging.debug(msg) if (profile_req == 'debug'): assert (profile_set == profile_req), 'Mismatch: ' + msg else: assert (profile_set == 'normal'), 'Mismatch: ' + msg # Verify LWK Memory if not lwkmem_static and not autogen: lwkmem_req = get_lwkmem(lwk_spec) lwkmem_set = get_lwkmem() msg = 'LWKMEM requested {} allocated {}'.format(lwkmem_req, lwkmem_set) logging.debug(msg) if lwkmem_req != 0: assert (lwkmem_set > 0), 'LWK memory partition was not created' assert (lwkmem_set <= lwkmem_req), 'Mismatch ' + msg lwkmem_auto_set = lwkmem_auto() if not autogen: if lwkmem_auto_set: logging.error('The lwkmem_auto indicator is set') assert (lwkmem_auto_set == False) else: if not lwkmem_auto_set: logging.error('The lwkmem_auto indicator is not set') assert (lwkmem_auto_set == True) # Run tests on LWK yod(obj, '-u', 0, '../lwksched/aff_scan', '-efm') if not lwkmem_static: yod(obj, '../lwkmem/maptest', '--verbose', '--type', 'anonymous', '--num', 10, '--size', 4096, '--iterations', 10) # Delete partition run(['lwkctl', '-v', v, '-d'], requiresRoot=True) # Read and verify using lwkctl -s utilcpus, lwkcpus = get_cpus() profile_set = get_profile() assert (utilcpus == CpuSet(0)) assert (lwkcpus == CpuSet(0)) assert (profile_set == '') if not lwkmem_static: lwkmem_set = get_lwkmem() assert (lwkmem_set == 0), 'Failed to delete LWKMEM partition' # Run tests on Linux run_bin(obj, '../lwksched/aff_scan')
def create_lwkmem_spec(self, ratio, align=False): def get_node_spec(node, size): if size <= 0: return '' unit = ['K', 'M', 'G', 'T', 'P', 'E'] q = size for i in range(0, len(unit)): q, r = divmod(q, 1024) if q == 0 or r != 0: break if i != 0: return '{}:{}{}'.format(int(node), size // (1 << (10 * i)), unit[i - 1]) else: return '{}:{}'.format(int(node), size) if lwkmem_static: op, rc = run(['lwkctl', '-v', '0', '-s', '-r']) for token in op.split(): if token.startswith('lwkmem='): if token != 'lwkmem=': return token return '' op, rc = run(['sync'], requiresRoot=True) logging.debug('sync returned rc={} {}'.format(rc, op)) op, rc = run(['sh', '-c', 'echo 1 > /proc/sys/vm/drop_caches'], requiresRoot=True) logging.debug('Drop caches returned rc={} {}'.format(rc, op)) with open('/sys/kernel/mOS/lwkmem') as f: lwkmemsize = f.read().split() lwkmem_spec = 'lwkmem=' movable_mem = [] fname = '/proc/buddyinfo' for line in fileinput.input(fname, mode='r'): if line.startswith('Node'): tokens = line.split() if tokens[0] == 'Node' and tokens[3] == 'Movable': order = pages = 0 for t in tokens[4:]: pages += int(t) * (1 << order) order += 1 node = int(tokens[1].strip(' ,')) cur_size = int( lwkmemsize[node]) if node < len(lwkmemsize) else 0 size = math.floor((pages * 4096 + cur_size) * ratio) # precise=yes requests must be made on a 128M boundary due # to limitations in the offlining of pages by the kernel if align == True: size = math.floor( size / (128 * 1024 * 1024)) * (128 * 1024 * 1024) movable_mem += [(node, size)] fileinput.close() for node, size in movable_mem: node_spec = get_node_spec(node, size) if node_spec != '': if lwkmem_spec != 'lwkmem=': lwkmem_spec += ',' lwkmem_spec += node_spec if lwkmem_spec == 'lwkmem=': return '' else: return lwkmem_spec
def create_and_verify(obj, lwk_spec, sccpus_req, lwkcpus_req, v='0'): def get_cpus(): sccpus = CpuSet(0) lwkcpus = CpuSet(0) op, rc = run(['lwkctl', '-v', v, '-s']) lines = op.splitlines() for l in lines: if l.startswith('Syscall CPU(s):'): f,m,s = l.partition('Syscall CPU(s):') s = s.strip() if s != '': sccpus.fromList(s) if l.startswith('LWK CPU(s):'): f,m,s = l.partition('LWK CPU(s):') s = s.strip() if s != '': lwkcpus.fromList(s) return sccpus, lwkcpus def get_profile(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 for token in op.split(): if token.startswith('lwkcpu_profile='): f,m,l = token.partition('lwkcpu_profile=') return l return '' def get_lwkmem(spec=None): if spec == None: op, rc = run(['lwkctl', '-v', v, '-s', '-r']) else: op, rc = spec, 0 units = ['K', 'M', 'G', 'T', 'P', 'E'] total_size = 0 for token in op.split(): if token.startswith('lwkmem='): f,m,l = token.partition('=') l = l.strip() if l != '': for node_spec in l.split(','): node,delimiter,size = node_spec.partition(':') if delimiter == '': size = node size = size.strip() if size != '': multiplier = 1 if size.endswith(('K', 'M', 'G', 'T', 'P', 'E')): for u in units: index = size.find(u) if index != -1: multiplier = 1024**(1+units.index(u)) break size = size.strip('KMGTPE') total_size += int(size) * multiplier return total_size # Create LWK partition lwk_spec = lwk_spec.strip() out, rc = run(['sudo', 'lwkctl', '-v', v, '-c', lwk_spec]) # Read and verify LWK partition using lwkctl -s # Verify CPUs sccpus, lwkcpus = get_cpus() if sccpus != sccpus_req or lwkcpus != lwkcpus_req: if sccpus != sccpus_req: logging.error('Mismatch : Syscall CPUs') logging.error('Requested: {}'.format(sccpus_req.toList())) logging.error('Created : {}'.format(sccpus.toList())) if lwkcpus != lwkcpus_req: logging.error('Mismatch : LWK CPUs') logging.error('Requested: {}'.format(lwkcpus_req.toList())) logging.error('Created : {}'.format(lwkcpus.toList())) assert(sccpus == sccpus_req) assert(lwkcpus == lwkcpus_req) # Verify LWK CPU profile profile_req = get_profile(lwk_spec) profile_set = get_profile() msg = 'LWKCPU profile requested: {} set: {}'.format(profile_req, profile_set) logging.debug(msg) if (profile_req == 'debug'): assert(profile_set == profile_req), 'Mismatch: ' + msg else: assert(profile_set == 'normal'), 'Mismatch: ' + msg # Verify LWK Memory if not lwkmem_static: lwkmem_req = get_lwkmem(lwk_spec) lwkmem_set = get_lwkmem() msg = 'LWKMEM requested {} allocated {}'.format(lwkmem_req, lwkmem_set) logging.debug(msg) if lwkmem_req != 0: assert(lwkmem_set > 0), 'LWK memory partition was not created' assert(lwkmem_set <= lwkmem_req), 'Mismatch ' + msg # Run tests on LWK yod(obj, '-u', 0, '../lwksched/aff_scan', '-efm') if not lwkmem_static: yod(obj, '../lwkmem/maptest', '--verbose', '--type', 'anonymous', '--num', 10, '--size', 4096, '--iterations', 10) # Delete partition run(['sudo', 'lwkctl', '-v', v, '-d']) # Read and verify using lwkctl -s sccpus, lwkcpus = get_cpus() profile_set = get_profile() assert(sccpus == CpuSet(0)) assert(lwkcpus == CpuSet(0)) assert(profile_set == '') if not lwkmem_static: lwkmem_set = get_lwkmem() assert(lwkmem_set == 0), 'Failed to delete LWKMEM partition' # Run tests on Linux run_bin(obj, '../lwksched/aff_scan')