You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					79 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					79 lines
				
				2.2 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								#!/usr/bin/env python3
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								import time
							 | 
						||
| 
								 | 
							
								import psutil
							 | 
						||
| 
								 | 
							
								from typing import Optional
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from common.realtime import set_core_affinity, set_realtime_priority
							 | 
						||
| 
								 | 
							
								from selfdrive.swaglog import cloudlog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MAX_MODEM_CRASHES = 3
							 | 
						||
| 
								 | 
							
								MODEM_PATH = "/sys/devices/soc/2080000.qcom,mss/subsys5"
							 | 
						||
| 
								 | 
							
								WATCHED_PROCS = ["zygote", "zygote64", "/system/bin/servicemanager", "/system/bin/surfaceflinger"]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def get_modem_crash_count() -> Optional[int]:
							 | 
						||
| 
								 | 
							
								  try:
							 | 
						||
| 
								 | 
							
								    with open(os.path.join(MODEM_PATH, "crash_count")) as f:
							 | 
						||
| 
								 | 
							
								      return int(f.read())
							 | 
						||
| 
								 | 
							
								  except Exception:
							 | 
						||
| 
								 | 
							
								    cloudlog.exception("Error reading modem crash count")
							 | 
						||
| 
								 | 
							
								  return None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def get_modem_state() -> str:
							 | 
						||
| 
								 | 
							
								  try:
							 | 
						||
| 
								 | 
							
								    with open(os.path.join(MODEM_PATH, "state")) as f:
							 | 
						||
| 
								 | 
							
								      return f.read().strip()
							 | 
						||
| 
								 | 
							
								  except Exception:
							 | 
						||
| 
								 | 
							
								    cloudlog.exception("Error reading modem state")
							 | 
						||
| 
								 | 
							
								  return ""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def main():
							 | 
						||
| 
								 | 
							
								  set_core_affinity(1)
							 | 
						||
| 
								 | 
							
								  set_realtime_priority(1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  procs = {}
							 | 
						||
| 
								 | 
							
								  crash_count = 0
							 | 
						||
| 
								 | 
							
								  modem_killed = False
							 | 
						||
| 
								 | 
							
								  modem_state = "ONLINE"
							 | 
						||
| 
								 | 
							
								  while True:
							 | 
						||
| 
								 | 
							
								    # check critical android services
							 | 
						||
| 
								 | 
							
								    if any(p is None or not p.is_running() for p in procs.values()) or not len(procs):
							 | 
						||
| 
								 | 
							
								      cur = {p: None for p in WATCHED_PROCS}
							 | 
						||
| 
								 | 
							
								      for p in psutil.process_iter(attrs=['cmdline']):
							 | 
						||
| 
								 | 
							
								        cmdline = None if not len(p.info['cmdline']) else p.info['cmdline'][0]
							 | 
						||
| 
								 | 
							
								        if cmdline in WATCHED_PROCS:
							 | 
						||
| 
								 | 
							
								          cur[cmdline] = p
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if len(procs):
							 | 
						||
| 
								 | 
							
								        for p in WATCHED_PROCS:
							 | 
						||
| 
								 | 
							
								          if cur[p] != procs[p]:
							 | 
						||
| 
								 | 
							
								            cloudlog.event("android service pid changed", proc=p, cur=cur[p], prev=procs[p])
							 | 
						||
| 
								 | 
							
								      procs.update(cur)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # check modem state
							 | 
						||
| 
								 | 
							
								    state = get_modem_state()
							 | 
						||
| 
								 | 
							
								    if state != modem_state and not modem_killed:
							 | 
						||
| 
								 | 
							
								      cloudlog.event("modem state changed", state=state)
							 | 
						||
| 
								 | 
							
								    modem_state = state
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # check modem crashes
							 | 
						||
| 
								 | 
							
								    cnt = get_modem_crash_count()
							 | 
						||
| 
								 | 
							
								    if cnt is not None:
							 | 
						||
| 
								 | 
							
								      if cnt > crash_count:
							 | 
						||
| 
								 | 
							
								        cloudlog.event("modem crash", count=cnt)
							 | 
						||
| 
								 | 
							
								      crash_count = cnt
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # handle excessive modem crashes
							 | 
						||
| 
								 | 
							
								    if crash_count > MAX_MODEM_CRASHES and not modem_killed:
							 | 
						||
| 
								 | 
							
								      cloudlog.event("killing modem")
							 | 
						||
| 
								 | 
							
								      with open("/sys/kernel/debug/msm_subsys/modem", "w") as f:
							 | 
						||
| 
								 | 
							
								        f.write("put")
							 | 
						||
| 
								 | 
							
								      modem_killed = True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    time.sleep(1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if __name__ == "__main__":
							 | 
						||
| 
								 | 
							
								  main()
							 |