首页 新闻 会员 周边 捐助

kernel 关机 device_shutdown 函数卡住问题求助

0
悬赏园豆:100 [待解决问题]

项目过程中遇到一个很棘手的问题,详细如下:
手机进行自动开关机压力测试(高通8937)400-1000次左右大概会有一次卡住导致不关机(并没有kernel panic),现象就是卡在关机动画,adb还可以连,uart log也正常输出,我的做法就是把kernel 关机流程全部加上printk,然后弄10台机器进行压力测试,等到出现问题后,触发ramdump,再解开ramdump,查看kmsg中加的trace走到哪一步进一步分析卡在哪里。

但是这个情况很特殊!!!!加了kernel log后,浮现概率大大降低,就算进行2000次测试也不一定可以出现问题(进一步怀疑是某一个dev时序问题卡住,但是不知道凶手是谁..),好不容易抓到一次,大致定位到了出问题就是卡在函数就是 device_shutdown函数,可惜log太少没有找出卡在具体哪一个device,现在还在继续压力测试中,我们分析极有可能是卡在pm_runtime_barrier 函数中,但是这个内核函数有点复杂,不太懂这块。
希望有高手可以指定一二,重点详细的帮忙分析下device_shutdown 整个函数,多谢!!!!! 集思广益,希望大家不吝给出各种调试分析手段!

void device_shutdown(void)
{
         struct device *dev, *parent;

         spin_lock(&devices_kset->list_lock);
         /*
         * Walk the devices list backward, shutting down each in turn.
         * Beware that device unplug events may also start pulling
         * devices offline, even as the system is shutting down.
         */
         while (!list_empty(&devices_kset->list)) {
                   dev = list_entry(devices_kset->list.prev, struct device,
                                     kobj.entry);


                   dev_p = (char *)dev->kobj.name;
                       step1++;
         
          
                   /*
                   * hold reference count of device's parent to
                   * prevent it from being freed because parent's
                   * lock is to be held
                   */
                   parent = get_device(dev->parent);
                   get_device(dev);
                   /*
                   * Make sure the device is off the kset list, in the
                   * event that dev->*->shutdown() doesn't remove it.
                   */
                   list_del_init(&dev->kobj.entry);
                   spin_unlock(&devices_kset->list_lock);

                   /* hold lock to avoid race with probe/release */
                   if (parent)
                            device_lock(parent);
                   device_lock(dev);
  
                   /* Don't allow any more runtime suspends */
                   pm_runtime_get_noresume(dev);
                   pm_runtime_barrier(dev);

                  step2++;          
                    
                   if (dev->bus && dev->bus->shutdown) {
                            if (initcall_debug)
                                     dev_info(dev, "shutdown\n");
                            dev->bus->shutdown(dev);
                   } else if (dev->driver && dev->driver->shutdown) {
                            if (initcall_debug)
                                     dev_info(dev, "shutdown\n");
                            dev->driver->shutdown(dev);
                   }

                   device_unlock(dev);
                   if (parent)
                            device_unlock(parent);

                   put_device(dev);
                   put_device(parent);

                   spin_lock(&devices_kset->list_lock);
         }
         spin_unlock(&devices_kset->list_lock);
}



上面的 dev_p = (char *)dev->kobj.name; 和step1,step2是我加的计数器,用于记录出问题时候跑了哪一步,是哪个dev卡住,可惜目前还没出结果,只能从代码层级深入挖掘o(╯□╰)o sad

 

 

问题补充:

跑了一夜,浮现了一次,dev_p = (char *)dev->kobj.name;
用adb拉出来了,发现卡住的dev是 :bam_dmux_ch_0.2 , 但是不了解这个东西是干什么用的,也不确定是在这个dev干什么时候stuck住了,

 

现在有一种临时交差方案是在device_shutdown函数的while循环里面加一个mdelay(1);基本就不会浮现了,但是未能找到根本原因!!!!!我还是非常希望可以找到root cause..

只有这样才具备经验继承性.

 

 

 

咋没人理捏?高手们不吝赐教啊,要死人了

victor.guo的主页 victor.guo | 初学一级 | 园豆:109
提问于:2016-09-20 22:28
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册