1*9c5db199SXin Li# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Li""" 6*9c5db199SXin LiProvides utility class for stopping and restarting services 7*9c5db199SXin Li 8*9c5db199SXin LiWhen using this class, one likely wishes to do the following: 9*9c5db199SXin Li 10*9c5db199SXin Li def initialize(self): 11*9c5db199SXin Li self._services = service_stopper.ServiceStopper(['service']) 12*9c5db199SXin Li self._services.stop_services() 13*9c5db199SXin Li 14*9c5db199SXin Li 15*9c5db199SXin Li def cleanup(self): 16*9c5db199SXin Li self._services.start_services() 17*9c5db199SXin Li 18*9c5db199SXin LiAs this ensures that the services will be off before the test code runs, and 19*9c5db199SXin Lithe test framework will ensure that the services are restarted through any 20*9c5db199SXin Licode path out of the test. 21*9c5db199SXin Li""" 22*9c5db199SXin Li 23*9c5db199SXin Liimport logging 24*9c5db199SXin Liimport os 25*9c5db199SXin Li 26*9c5db199SXin Lifrom autotest_lib.client.bin import utils 27*9c5db199SXin Lifrom autotest_lib.client.cros import upstart 28*9c5db199SXin Li 29*9c5db199SXin Li 30*9c5db199SXin Liclass ServiceStopper(object): 31*9c5db199SXin Li """Class to manage CrOS services. 32*9c5db199SXin Li Public attributes: 33*9c5db199SXin Li services_to_stop: list of services that should be stopped 34*9c5db199SXin Li 35*9c5db199SXin Li Public constants: 36*9c5db199SXin Li POWER_DRAW_SERVICES: list of services that influence power test in 37*9c5db199SXin Li unpredictable/undesirable manners. 38*9c5db199SXin Li 39*9c5db199SXin Li Public methods: 40*9c5db199SXin Li stop_sevices: stop running system services. 41*9c5db199SXin Li restore_services: restore services that were previously stopped. 42*9c5db199SXin Li 43*9c5db199SXin Li Private attributes: 44*9c5db199SXin Li _services_stopped: list of services that were successfully stopped 45*9c5db199SXin Li """ 46*9c5db199SXin Li 47*9c5db199SXin Li POWER_DRAW_SERVICES = ['fwupd', 'powerd', 'update-engine', 'vnc'] 48*9c5db199SXin Li 49*9c5db199SXin Li # List of thermal throttling services that should be disabled. 50*9c5db199SXin Li # - temp_metrics for link. 51*9c5db199SXin Li # - thermal for daisy, snow, pit etc. 52*9c5db199SXin Li # - dptf for intel >= baytrail 53*9c5db199SXin Li # TODO(ihf): cpu_quiet on nyan isn't a service. We still need to disable it 54*9c5db199SXin Li # on nyan. See crbug.com/357457. 55*9c5db199SXin Li THERMAL_SERVICES = ['dptf', 'temp_metrics', 'thermal'] 56*9c5db199SXin Li 57*9c5db199SXin Li def __init__(self, services_to_stop=[]): 58*9c5db199SXin Li """Initialize instance of class. 59*9c5db199SXin Li 60*9c5db199SXin Li By Default sets an empty list of services. 61*9c5db199SXin Li """ 62*9c5db199SXin Li self.services_to_stop = services_to_stop 63*9c5db199SXin Li self._services_stopped = [] 64*9c5db199SXin Li 65*9c5db199SXin Li 66*9c5db199SXin Li def stop_services(self): 67*9c5db199SXin Li """Turn off managed services.""" 68*9c5db199SXin Li 69*9c5db199SXin Li for service in self.services_to_stop: 70*9c5db199SXin Li if not upstart.has_service(service): 71*9c5db199SXin Li continue 72*9c5db199SXin Li if not upstart.is_running(service): 73*9c5db199SXin Li continue 74*9c5db199SXin Li upstart.stop_job(service) 75*9c5db199SXin Li self._services_stopped.append(service) 76*9c5db199SXin Li 77*9c5db199SXin Li 78*9c5db199SXin Li def restore_services(self): 79*9c5db199SXin Li """Restore services that were stopped.""" 80*9c5db199SXin Li for service in reversed(self._services_stopped): 81*9c5db199SXin Li upstart.restart_job(service) 82*9c5db199SXin Li self._services_stopped = [] 83*9c5db199SXin Li 84*9c5db199SXin Li 85*9c5db199SXin Li def __enter__(self): 86*9c5db199SXin Li self.stop_services() 87*9c5db199SXin Li return self 88*9c5db199SXin Li 89*9c5db199SXin Li 90*9c5db199SXin Li def __exit__(self, exnval, exntype, exnstack): 91*9c5db199SXin Li self.restore_services() 92*9c5db199SXin Li 93*9c5db199SXin Li 94*9c5db199SXin Li def close(self): 95*9c5db199SXin Li """Equivalent to restore_services.""" 96*9c5db199SXin Li self.restore_services() 97*9c5db199SXin Li 98*9c5db199SXin Li 99*9c5db199SXin Li def _dptf_fixup_pl1(self): 100*9c5db199SXin Li """For intel devices that don't set their PL1 override in coreboot's 101*9c5db199SXin Li devicetree.cb (See 'register "tdp_pl1_override') stopping DPTF will 102*9c5db199SXin Li change the PL1 limit to the platform default. For eve (KBL-Y) that 103*9c5db199SXin Li would be 4.5W. To workaround this until FW can be fixed we should 104*9c5db199SXin Li instead query what the PL1 limit is for the proc_thermal driver and 105*9c5db199SXin Li write it to the PL1 constraint. 106*9c5db199SXin Li 107*9c5db199SXin Li TODO(b/144020442) 108*9c5db199SXin Li """ 109*9c5db199SXin Li pl1_max_path = \ 110*9c5db199SXin Li '/sys/devices/pci0000:00/0000:00:04.0/power_limits/power_limit_0_max_uw' 111*9c5db199SXin Li pl1_constraint_path = \ 112*9c5db199SXin Li '/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw' 113*9c5db199SXin Li if not os.path.exists(pl1_max_path): 114*9c5db199SXin Li return 115*9c5db199SXin Li 116*9c5db199SXin Li pl1 = int(utils.read_one_line(pl1_max_path)) 117*9c5db199SXin Li logging.debug('PL1 set to %d uw', pl1) 118*9c5db199SXin Li utils.system('echo %d > %s' % (pl1, pl1_constraint_path)) 119*9c5db199SXin Li 120*9c5db199SXin Li 121*9c5db199SXin Lidef get_thermal_service_stopper(): 122*9c5db199SXin Li """Convenience method to retrieve thermal service stopper.""" 123*9c5db199SXin Li return ServiceStopper(services_to_stop=ServiceStopper.THERMAL_SERVICES) 124