watchdog ,hang_detect分析
来源:互联网 发布:淘宝客店铺做裂变 编辑:程序博客网 时间:2024/05/16 06:45
作用:
用于监控,system_server 中的watchdog 线程的行为是否异常。
实现:
mtk 在kernel 中专门注册了一个设备( /dev/RT_Monitor ),用于和上层通信监控 watchdog是否正常。
大概为:watchdog 向/dev/RT_Monitor 设置一个值,然后hang_detect根据此值,计算出一个时间,在此时间内,watchdog,必须再次通知一下hang_detect, 来表示并未超时。
代码流程:
kernel-3.18/drivers/misc/mediatek/aee/aed/monitor_hang.c
//定义/dev/RT_Monitor 设备。static struct miscdevice aed_wdt_RT_Monitor_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "RT_Monitor", .fops = &aed_wdt_RT_Monitor_fops,};
//定义/dev/RT_Monitor 设备对应的操作函数。static const struct file_operations aed_wdt_RT_Monitor_fops = { .owner = THIS_MODULE, .open = monitor_hang_open, .release = monitor_hang_release, .poll = monitor_hang_poll, .read = monitor_hang_read, .write = monitor_hang_write, //watchdog 调用ioctl RT_Monitor驱动时,会调用 此方法monitor_hang_ioctl,来从新设置超时时间。 .unlocked_ioctl = monitor_hang_ioctl,#ifdef CONFIG_COMPAT .compat_ioctl = monitor_hang_ioctl, #endif}
//注册设备,并初始化 hang_detectstatic int __init monitor_hang_init(void){ //注册一个字符设备,/dev/RT_Monitor err = misc_register(&aed_wdt_RT_Monitor_dev); //初始化hang_detect hang_detect_init(); return err;}
//启动一个新线程,初始化hang_detectint hang_detect_init(void){ struct task_struct *hd_thread; unsigned char *name = "hang_detect"; //创建monitor hang 线程,去监控 watchdog //hang_detect_thread 新线程要运行的方法 //name 新线程的名字 hd_thread = kthread_create(hang_detect_thread, NULL, name); //唤醒开始运行hd_thread, wake_up_process(hd_thread); return 0;}
//在新线程中运行此函数,去监控watchdogstatic int hang_detect_thread(void *arg) { struct sched_param param = {.sched_priority = 99 }; //设置调度策略 sched_setscheduler(current, SCHED_FIFO, ¶m); //无限循环开始监控watchdog while (!kthread_should_stop()) { if ((1 == hd_detect_enabled) && (FindTaskByName("system_server") != -1)) { if (hang_detect_counter <= 0) ShowStatus(); if (hang_detect_counter == 0) { //根据当前版本做不同的选择, //如果是user版本,去通过aee_kernel_warning_api 抓取oops,并上报warning if (aee_mode != AEE_MODE_CUSTOMER_USER) { aee_kernel_warning_api (__FILE__, __LINE__, DB_OPT_NE_JBT_TRACES | DB_OPT_DISPLAY_HANG_DUMP, "\nCRDISPATCH_KEY:SS Hang\n", "we triger HWT "); msleep(30 * 1000); } else { //如果不是user版本,向kernel上报bug, BUG(); } } //如果本次循环没有问题,hang_detect_counter 减一,并休眠30s //上层会通过ioctl RT_Monitor 设备,来重设 hang_detect_counter 的值 hang_detect_counter--; } else { //如果没有找到system_server线程,表示系统在重启,那么等待hang_detect_counter*30s if (1 == hd_detect_enabled) { hang_detect_counter = hd_timeout + 4; hd_detect_enabled = 0; } } //每次循环休眠30s msleep((HD_INTER) * 1000); } return 0;}
//如果是user版本:kernel-3.18/drivers/misc/mediatek/aee/common/aee-common.c void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, const char *msg, ...){ char msgbuf[KERNEL_REPORT_LENGTH]; int offset = 0; va_list args; va_start(args, msg); offset += snprintf(msgbuf, KERNEL_REPORT_LENGTH, "<%s:%d> ", file, line); offset += vsnprintf(msgbuf + offset, KERNEL_REPORT_LENGTH - offset, msg, args); if (g_aee_api && g_aee_api->kernel_reportAPI) //如果g_aee_api存在且初始化成功,调用他的 kernel_reportAPI方法 g_aee_api->kernel_reportAPI(AE_DEFECT_WARNING, db_opt, module, msgbuf); else LOGE("AEE kernel warning: %s", msgbuf); va_end(args);}EXPORT_SYMBOL(aee_kernel_warning_api);
//g_aee_api 的初始化为:
drivers/misc/mediatek/aee/aed/aed-main.c
module_init(aed_init);
static int __init aed_init(void) { ...... aee_register_api(&kernel_api); ......}
此kernel_api 是在本类中定义的,他的kernel_reportAPI 方法也是本类中的方法
static struct aee_kernel_api kernel_api = { .kernel_reportAPI = kernel_reportAPI, .md_exception = external_exception, .md32_exception = external_exception, .scp_exception = external_exception, .combo_exception = external_exception};
drivers/misc/mediatek/aee/common/aee-common.c
会在aee_register_api 方法中将kernel_api 赋值给g_aee_api
void aee_register_api(struct aee_kernel_api *aee_api) { if (!aee_api) BUG(); g_aee_api = aee_api; }
上层与底层通信是:
frameworks/base/services/core/java/com/android/server/Watchdog.java@Overridepublic void run() { while (true) { if (exceptionHWT != null) { exceptionHWT.WDTMatterJava(300); } }}
frameworks/base/core/java/com/mediatek/aee/ExceptionLog.javapublic void WDTMatterJava(long lParam) { WDTMatter(lParam) ;}private static native void WDTMatter(long lParam) ;
frameworks/base/core/java/com/mediatek/aee/jni/com_mediatek_aee_exceptionlog.cppstatic void com_mediatek_exceptionlog_WDTMatter (JNIEnv* env, jobject clazz, jlong lParam){ //AE_WDT_DEVICE_PATH 即为设备 "/dev/RT_Monitor" int fd = open(AE_WDT_DEVICE_PATH, O_RDONLY); //通过ioctl 将 300 传入 RT_Monitor 驱动 if (ret = ioctl(fd, AEEIOCTL_RT_MON_Kick, (int)(lParam))) ...... close (fd) ; return;}
在之后会调用到monitor_hang 类的 monitor_hang_ioctl 方法(在注册此设备时,就已经指定,ioctl此设备,会调用此函数)
// 对 /dev/RT_Monitor 使用ioctl 操作时会调用此方法。 //cmd 为 AEEIOCTL_RT_MON_Kick // arg 为 300 static long monitor_hang_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { ...... //正常会走这里 if (cmd == AEEIOCTL_RT_MON_Kick) { LOGE("AEEIOCTL_RT_MON_Kick ( %d)\n", (int)arg); aee_kernel_RT_Monitor_api((int)arg); return ret; } ...... } //在此方法中根据lParam(300),从新计算hang_detect_counter 的值void aee_kernel_RT_Monitor_api(int lParam) { ...... hd_detect_enabled = 1; //HD_INTER 为 30 //300 对应的为 10, //那么表示在10*30s内,watchdog 必须再次ioctl RT_monitor,否则认为watchdog 发生异常。 hang_detect_counter = hd_timeout = ((long)lParam + HD_INTER - 1) / (HD_INTER); ...... }}
参考:
http://blog.csdn.net/ldinvicible/article/details/51042811
0 0
- watchdog ,hang_detect分析
- watchdog 分析
- kdb中的watchdog分析
- Android WatchDog分析
- android -- WatchDog看门狗分析
- SW watchdog 分析
- Android watchdog分析
- android -- WatchDog看门狗分析
- android -- WatchDog看门狗分析
- SW watchdog 分析
- linux watchdog 分析
- Android WatchDog分析
- android 学习--WatchDog分析
- Watchdog 源码分析
- Android WatchDog分析
- Android Watchdog分析二
- framework watchdog源码分析
- Watchdog死锁实例分析
- Android:androidpn
- tomcat以及微信支付中签名的中文编码问题
- over partition by 用法
- 多态的理解
- C#事务处理(二)之ADO.NET事务
- watchdog ,hang_detect分析
- 1.Block内部执行完才走后续的代码 2.多次请求完成才执行代码
- 【第四课】面向对象编程---构造函数
- 互联网金融事件频发,我们如何保护服务器安全?
- 日期时间
- 转载 仿微信表情与软键盘冲突
- CentOs6.5上快速搭建ftp服务器
- 安装Android虚拟机Genymotion 的那些事
- 百度出品强大的Html5上传控件WebUploader-支持手机端