AI智能摘要
在高低温测试后出现工模卡死问题,通过手动组合键获取dump和日志分析发现,卡死主要涉及g_reclaim_threa、kworker和电池相关进程,均处于不可中断状态,线程堆栈显示重复调度和互斥锁等待。问题集中在充电管理和电池状态处理流程,表明驱动在极端温度下存在逻辑漏洞。
此摘要由AI分析文章内容生成,仅供参考。

一、问题背景

  1. 441#-AS1-KKX_0411版本高低温运行测试后工模卡死
  2. 手动组合键进dump

{% btns rounded grid1 %}
{% cell 下载日志1, https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/25/4/parser_output_android_stability_038.zip, anzhiyufont anzhiyu-icon-bolt %}
{% endbtns %}

二、日志分析

卡死时刻的线程栈

[43616.570812][  T700] task PC stack pid father
[43616.575287][  T700] task:g_reclaim_threa state:D stack:0     pid:121   ppid:2      flags:0x00000008
[43616.584433][  T700] Call trace:
[43616.587655][  T700]  __switch_to+0x164/0x308
[43616.592016][  T700]  __schedule+0x624/0xa10
[43616.596281][  T700]  schedule+0x84/0xf0
[43616.600199][  T700]  schedule_preempt_disabled+0x28/0x44
[43616.605584][  T700]  kthread+0xb8/0x154
[43616.609503][  T700]  ret_from_fork+0x10/0x20
[43616.613955][  T700] task:kworker/6:4     state:D stack:0     pid:688   ppid:2      flags:0x00000008
[43616.623096][  T700] Workqueue: events smblib_reverse_charge_monitor_workfunc [qpnp_smb5_main]
[43616.631870][  T700] Call trace:
[43616.635067][  T700]  __switch_to+0x164/0x308
[43616.639434][  T700]  __schedule+0x624/0xa10
[43616.643692][  T700]  schedule+0x84/0xf0
[43616.647616][  T700]  schedule_timeout+0x44/0x12c
[43616.652345][  T700]  wait_for_common+0xdc/0x1a8
[43616.656978][  T700]  wait_for_completion+0x18/0x24
[43616.661463][ T6777] _block2mtd_write: finish all 
[43616.661830][  T700]  __flush_work+0x260/0x2dc
[43616.671094][  T700]  __cancel_work_timer+0x120/0x1cc
[43616.676127][  T700]  cancel_delayed_work_sync+0x14/0x28
[43616.681408][  T700]  smblib_handle_reverse_charge_event+0xbc/0x438 [qpnp_smb5_main]
[43616.689256][  T700]  smb5_iio_set_prop+0x50c/0x788 [qpnp_smb5_main]
[43616.695676][  T700]  smb5_write_raw+0x18/0x28 [qpnp_smb5_main]
[43616.701687][  T700]  iio_write_channel_raw+0x6c/0xa4
[43616.706705][  T700]  smblib_gear_shift_set+0x140/0x198 [usbpd]
[43616.712674][  T700]  smblib_reverse_charge_monitor_workfunc+0x7c/0xe4 [qpnp_smb5_main]
[43616.720741][  T700]  process_one_work+0x240/0x504
[43616.725543][  T700]  worker_thread+0x264/0x480
[43616.730058][  T700]  kthread+0x10c/0x154
[43616.734094][  T700]  ret_from_fork+0x10/0x20
[43616.739609][  T700] task:batterysecret   state:D stack:0     pid:3994  ppid:1      flags:0x04000000
[43616.748773][  T700] Call trace:
[43616.751990][  T700]  __switch_to+0x164/0x308
[43616.756334][  T700]  __schedule+0x624/0xa10
[43616.760570][  T700]  schedule+0x84/0xf0
[43616.764479][  T700]  schedule_preempt_disabled+0x28/0x44
[43616.769910][  T700]  __mutex_lock+0x414/0xdec
[43616.774365][  T700]  __mutex_lock_slowpath+0x14/0x24
[43616.779429][  T700]  mutex_lock+0x40/0xec
[43616.783513][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43616.789616][  T700]  iio_read_channel_processed+0x14/0x24
[43616.795112][  T700]  lc_chg_sysfs_get_iio_channel+0x22c/0x3a4 [lc_charger_sysfs_main]
[43616.803054][  T700]  lc_get_usb_real_type+0x40/0xcc [lc_charger_sysfs_main]
[43616.810142][  T700]  real_type_show+0x38/0x144 [lc_charger_sysfs_main]
[43616.816797][  T700]  class_attr_show+0x34/0x4c
[43616.821348][  T700]  sysfs_kf_seq_show+0xb4/0x130
[43616.826128][  T700]  kernfs_seq_show+0x4c/0x60
[43616.830753][  T700]  seq_read_iter+0x158/0x4ec
[43616.835297][  T700]  kernfs_fop_read_iter+0x68/0x1bc
[43616.840377][  T700]  vfs_read+0x234/0x2c8
[43616.844458][  T700]  ksys_read+0x78/0xe8
[43616.848468][  T700]  __arm64_sys_read+0x1c/0x2c
[43616.853077][  T700]  invoke_syscall+0x58/0x114
[43616.857621][  T700]  el0_svc_common+0xb4/0xfc
[43616.862057][  T700]  do_el0_svc+0x24/0x84
[43616.866158][  T700]  el0_svc+0x2c/0x90
[43616.869996][  T700]  el0t_64_sync_handler+0x68/0xb4
[43616.874963][  T700]  el0t_64_sync+0x1a4/0x1a8
[43616.879417][  T700] task:charge_logger   state:D stack:0     pid:3996  ppid:1      flags:0x04000000
[43616.888549][  T700] Call trace:
[43616.891761][  T700]  __switch_to+0x164/0x308
[43616.896108][  T700]  __schedule+0x624/0xa10
[43616.900365][  T700]  schedule+0x84/0xf0
[43616.904272][  T700]  schedule_preempt_disabled+0x28/0x44
[43616.909677][  T700]  __mutex_lock+0x414/0xdec
[43616.914108][  T700]  __mutex_lock_slowpath+0x14/0x24
[43616.919143][  T700]  mutex_lock+0x40/0xec
[43616.923250][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43616.929342][  T700]  iio_read_channel_processed+0x14/0x24
[43616.934850][  T700]  lc_chg_sysfs_get_iio_channel+0x22c/0x3a4 [lc_charger_sysfs_main]
[43616.942775][  T700]  typec_mode_show+0x60/0x174 [lc_charger_sysfs_main]
[43616.949524][  T700]  class_attr_show+0x34/0x4c
[43616.954042][  T700]  sysfs_kf_seq_show+0xb4/0x130
[43616.958825][  T700]  kernfs_seq_show+0x4c/0x60
[43616.963342][  T700]  seq_read_iter+0x158/0x4ec
[43616.967895][  T700]  kernfs_fop_read_iter+0x68/0x1bc
[43616.972934][  T700]  vfs_read+0x234/0x2c8
[43616.977017][  T700]  ksys_read+0x78/0xe8
[43616.981002][  T700]  __arm64_sys_read+0x1c/0x2c
[43616.985610][  T700]  invoke_syscall+0x58/0x114
[43616.990119][  T700]  el0_svc_common+0xb4/0xfc
[43616.991351][T10920] get_eu_mode: eu_mode:1 !
[43616.994506][T10920] fg_read_cyclecount: [FG_NFG1000] fake_cycle_count:-999 
[43616.994550][  T700]  do_el0_svc+0x24/0x84
[43617.008927][T10920] fg_read_current: [FG_NFG1000] successed to read IBAT:-506
[43617.009929][  T700]  el0_svc+0x2c/0x90
[43617.018249][T10920] fg_read_temperature: [FG_NFG1000] read FG TBAT = 3042
[43617.020910][  T700]  el0t_64_sync_handler+0x68/0xb4
[43617.030034][T10920] fg_update_status: fg_update_status fg_update rsoc=92, raw_soc=9199, vbat=4331, cycle_count=3
[43617.032676][  T700]  el0t_64_sync+0x1a4/0x1a8
[43617.043015][T10920] smooth_new:soc:93, last_soc:92, raw_soc:9200, soc_changed:1, update_now:0, charge_status:2, batt_ma:-506
[43617.047423][  T700] task:ongcheertel.cit state:D
[43617.058563][T10920] bq_battery_soc_smooth_tracking_eea update down soc 92 92
[43617.058576][T10920] fg_update_status: [FG_NFG1000] [FG_STATUS] [UISOC RSOC RAWSOC TEMP_SOC SOH] = [92 92 9199 0 100], [VBAT CELL0 CELL1 IBAT TBAT FC FAST_MODE] = [4331 4331 4331 -506 312 0 0]
[43617.058585][T10920] fg_update_status: fg_update_status last_soc = 93, last_temp = 307, delta_temp = 5
[43617.063258][  T700]  stack:0     pid:5246  ppid:1249   flags:0x04000001
[43617.063268][  T700] Call trace:
[43617.070483][T10920] [usbpd-pm]: cycle_count_reduce_voltage: bat_volt_lp_lmt is 4490
[43617.087448][  T700]  __switch_to+0x164/0x308
[43617.087465][  T700]  __schedule+0x624/0xa10
[43617.096744][T10920] fsa4480-driver 0-0042: fsa4480_usbc_event_changed_psupply: queueing usbc_analog_work
[43617.097108][T10910] PL_DISABLE: ICL_CHANGE_VOTER,4 voting on of val=1
[43617.103477][  T700]  schedule+0x84/0xf0
[43617.106812][T10910] PL_DISABLE: ICL_CHANGE_VOTER,4 voting off of val=0
[43617.114387][  T700]  schedule_preempt_disabled+0x28/0x44
[43617.114400][  T700]  __mutex_lock+0x414/0xdec
[43617.119335][T10910] QCOM-BATT: pl_fv_vote_callback: pl_fv_vote_callback, fv_uv = 4490000, smart_batt = 0, val = 4490000
[43617.122940][  T700]  __mutex_lock_slowpath+0x14/0x24
[43617.132487][T10920] fg_read_current: [FG_NFG1000] successed to read IBAT:-506
[43617.132666][T10910] QCOM-BATT: pl_fv_vote_callback: pl_fv_vote_callback, fv_uv = 4490000, smart_batt = 0, val = 4490000
[43617.138993][  T700]  mutex_lock+0x40/0xec
[43617.148509][T10910] QCOM-BATT: pl_fv_vote_callback: pl_fv_vote_callback, fv_uv = 4490000, smart_batt = 0, val = 4490000
[43617.149466][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43617.150979][ T1344] healthd: battery l=92 v=4318 t=31.2 h=2 st=3 chg=
[43617.220676][  T700]  iio_read_channel_processed+0x14/0x24
[43617.226158][  T700]  lc_chg_sysfs_get_iio_channel+0x22c/0x3a4 [lc_charger_sysfs_main]
[43617.234068][  T700]  typec_cc_orientation_show+0x64/0x140 [lc_charger_sysfs_main]
[43617.241655][  T700]  class_attr_show+0x34/0x4c
[43617.246165][  T700]  sysfs_kf_seq_show+0xb4/0x130
[43617.251029][  T700]  kernfs_seq_show+0x4c/0x60
[43617.255557][  T700]  seq_read_iter+0x158/0x4ec
[43617.260066][  T700]  kernfs_fop_read_iter+0x68/0x1bc
[43617.265093][  T700]  vfs_read+0x234/0x2c8
[43617.269168][  T700]  ksys_read+0x78/0xe8
[43617.273149][  T700]  __arm64_sys_read+0x1c/0x2c
[43617.277757][  T700]  invoke_syscall+0x58/0x114
[43617.282260][  T700]  el0_svc_common+0xb4/0xfc
[43617.286718][  T700]  do_el0_svc+0x24/0x84
[43617.290896][  T700]  el0_svc+0x2c/0x90
[43617.294735][  T700]  el0t_64_sync_handler+0x68/0xb4
[43617.299701][  T700]  el0t_64_sync+0x1a4/0x1a8
[43617.304229][  T700] task:kworker/1:0     state:D stack:0     pid:29536 ppid:2      flags:0x00000008
[43617.313380][  T700] Workqueue: events xm_charge_work [xm_smart_chg]
[43617.319815][  T700] Call trace:
[43617.323009][  T700]  __switch_to+0x164/0x308
[43617.327387][  T700]  __schedule+0x624/0xa10
[43617.331650][  T700]  schedule+0x84/0xf0
[43617.335556][  T700]  schedule_preempt_disabled+0x28/0x44
[43617.340942][  T700]  __mutex_lock+0x414/0xdec
[43617.345372][  T700]  __mutex_lock_slowpath+0x14/0x24
[43617.350388][  T700]  mutex_lock+0x40/0xec
[43617.354463][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43617.360538][  T700]  iio_read_channel_processed+0x14/0x24
[43617.366031][  T700]  xm_charge_update_date+0xd8/0x210 [xm_smart_chg]
[43617.372452][  T700]  xm_charge_work+0x28/0x244 [xm_smart_chg]
[43617.378302][  T700]  process_one_work+0x240/0x504
[43617.383070][  T700]  worker_thread+0x264/0x480
[43617.387624][  T700]  kthread+0x10c/0x154
[43617.391659][  T700]  ret_from_fork+0x10/0x20
[43617.396012][  T700] task:kworker/0:4     state:D stack:0     pid:29940 ppid:2      flags:0x00000008
[43617.405139][  T700] Workqueue: events_freezable fsa4480_usbc_analog_work_fn [fsa4480_i2c]
[43617.413407][  T700] Call trace:
[43617.416633][  T700]  __switch_to+0x164/0x308
[43617.420955][  T700]  __schedule+0x624/0xa10
[43617.425239][  T700]  schedule+0x84/0xf0
[43617.429126][  T700]  schedule_preempt_disabled+0x28/0x44
[43617.434525][  T700]  __mutex_lock+0x414/0xdec
[43617.438922][  T700]  __mutex_lock_slowpath+0x14/0x24
[43617.443959][  T700]  mutex_lock+0x40/0xec
[43617.448006][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43617.454110][  T700]  iio_read_channel_processed+0x14/0x24
[43617.459589][  T700]  fsa4480_usbc_analog_setup_switches+0x48/0x2f0 [fsa4480_i2c]
[43617.467107][  T700]  fsa4480_usbc_analog_work_fn+0x20/0xac0 [fsa4480_i2c]
[43617.473974][  T700]  process_one_work+0x240/0x504
[43617.478764][  T700]  worker_thread+0x264/0x480
[43617.483268][  T700]  kthread+0x10c/0x154
[43617.487286][  T700]  ret_from_fork+0x10/0x20
[43617.491654][  T700] task:kworker/0:0     state:D stack:0     pid:32007 ppid:2      flags:0x00000008
[43617.500790][  T700] Workqueue: events status_change_work [qpnp_smb5_main]

多个线程处于D状态

2.1batterysecret线程

[43616.739609][  T700] task:batterysecret   state:D stack:0     pid:3994  ppid:1      flags:0x04000000
[43616.748773][  T700] Call trace:
[43616.751990][  T700]  __switch_to+0x164/0x308
[43616.756334][  T700]  __schedule+0x624/0xa10
[43616.760570][  T700]  schedule+0x84/0xf0
[43616.764479][  T700]  schedule_preempt_disabled+0x28/0x44
[43616.769910][  T700]  __mutex_lock+0x414/0xdec
[43616.774365][  T700]  __mutex_lock_slowpath+0x14/0x24
[43616.779429][  T700]  mutex_lock+0x40/0xec
[43616.783513][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43616.789616][  T700]  iio_read_channel_processed+0x14/0x24
[43616.795112][  T700]  lc_chg_sysfs_get_iio_channel+0x22c/0x3a4 [lc_charger_sysfs_main]
[43616.803054][  T700]  lc_get_usb_real_type+0x40/0xcc [lc_charger_sysfs_main]
[43616.810142][  T700]  real_type_show+0x38/0x144 [lc_charger_sysfs_main]
[43616.816797][  T700]  class_attr_show+0x34/0x4c
[43616.821348][  T700]  sysfs_kf_seq_show+0xb4/0x130
[43616.826128][  T700]  kernfs_seq_show+0x4c/0x60
[43616.830753][  T700]  seq_read_iter+0x158/0x4ec
[43616.835297][  T700]  kernfs_fop_read_iter+0x68/0x1bc
[43616.840377][  T700]  vfs_read+0x234/0x2c8
[43616.844458][  T700]  ksys_read+0x78/0xe8
[43616.848468][  T700]  __arm64_sys_read+0x1c/0x2c
[43616.853077][  T700]  invoke_syscall+0x58/0x114
[43616.857621][  T700]  el0_svc_common+0xb4/0xfc
[43616.862057][  T700]  do_el0_svc+0x24/0x84
[43616.866158][  T700]  el0_svc+0x2c/0x90
[43616.869996][  T700]  el0t_64_sync_handler+0x68/0xb4
[43616.874963][  T700]  el0t_64_sync+0x1a4/0x1a8

查看锁的持有者

__mutex_lock(lock = 0xFFFFFF8054978458, state = 0x2, subclass = 0x0, nest_lock = 0x0)
lock = 0xFFFFFF8054978458 -> (
owner = (
{% p red, counter = 0xFFFFFF804C354B01), // ---> comm = "kworker/6:4" %}
wait_lock = (raw_lock = (val = (counter = 0x0), locked = 0x0, pending = 0x0, locked_pending = 0x
osq = (tail = (counter = 0x0)),
wait_list = (next = 0xFFFFFFC01DEBBC20, prev = 0xFFFFFFC01E6EBBE0),
android_oem_data1 = (0x0, 0x0))
state = 0x2
subclass = 0x0
nest_lock = 0x0

batterysecret线程等待{% span red, "kworker/6:4" %}释放锁

2.2 charge_logger线程

    Task name: charge_logger    [affinity: 0xff] pid:   3996 tgid:   3996 cpu: 2 prio: 120 start: 0xffffff80831fddc0
    state: 0x2[D] exit_state: 0x0 stack base: 0xffffffc01cc10000
    Last_enqueued_ts:   11094.839605863 Last_sleep_ts:   11094.839851123
    Stack:
    [<ffffffc0090416e0>] __switch_to+0x164
    [<ffffffc009041ee4>] __schedule+0x624
    [<ffffffc009042354>] schedule+0x84
    [<ffffffc009042430>] schedule_preempt_disabled+0x28
    [<ffffffc009044564>] __mutex_lock+0x414
    [<ffffffc009043744>] __mutex_lock_slowpath+0x14
    [<ffffffc009043684>] mutex_lock[jt]+0x70
    [<ffffffc008c8dbfc>] iio_read_channel_processed_scale+0x44
    [<ffffffc008c8ddd8>] iio_read_channel_processed+0x14
    [<ffffffc002582cd4>] lc_chg_sysfs_get_iio_channel[lc_charger_sysfs_main]+0x22c
    [<ffffffc002581f5c>] typec_mode_show[lc_charger_sysfs_main]+0x60
    [<ffffffc00890b3a4>] class_attr_show[jt]+0x3c
    [<ffffffc0084880ac>] sysfs_kf_seq_show+0xb4
    [<ffffffc008486e68>] kernfs_seq_show+0x4c
    [<ffffffc0083f834c>] seq_read_iter+0x158
    [<ffffffc008485e14>] kernfs_fop_read_iter.llvm.3279189179197410940+0x68
    [<ffffffc0083bc4d8>] vfs_read+0x234
    [<ffffffc0083bdab4>] ksys_read+0x78
    [<ffffffc0083bdb40>] __arm64_sys_read+0x1c
    [<ffffffc00803e270>] invoke_syscall[jt]+0xac
    [<ffffffc00803e1a8>] el0_svc_common.llvm.11374131550631168591+0xb4
    [<ffffffc00803e094>] do_el0_svc+0x24
    [<ffffffc00903a688>] el0_svc+0x2c
    [<ffffffc00903a610>] el0t_64_sync_handler[jt]+0xa8
    [<ffffffc008011584>] ret_to_user[jt]+0x0

同样指向 {% span red, "kworker/6:4" %}

2.3 xm_charge_work

[43617.304229][  T700] task:kworker/1:0     state:D stack:0     pid:29536 ppid:2      flags:0x00000008
[43617.313380][  T700] Workqueue: events xm_charge_work [xm_smart_chg]
[43617.319815][  T700] Call trace:
[43617.323009][  T700]  __switch_to+0x164/0x308
[43617.327387][  T700]  __schedule+0x624/0xa10
[43617.331650][  T700]  schedule+0x84/0xf0
[43617.335556][  T700]  schedule_preempt_disabled+0x28/0x44
[43617.340942][  T700]  __mutex_lock+0x414/0xdec
[43617.345372][  T700]  __mutex_lock_slowpath+0x14/0x24
[43617.350388][  T700]  mutex_lock+0x40/0xec
[43617.354463][  T700]  iio_read_channel_processed_scale+0x44/0x20c
[43617.360538][  T700]  iio_read_channel_processed+0x14/0x24
[43617.366031][  T700]  xm_charge_update_date+0xd8/0x210 [xm_smart_chg]
[43617.372452][  T700]  xm_charge_work+0x28/0x244 [xm_smart_chg]
[43617.378302][  T700]  process_one_work+0x240/0x504
[43617.383070][  T700]  worker_thread+0x264/0x480
[43617.387624][  T700]  kthread+0x10c/0x154
[43617.391659][  T700]  ret_from_fork+0x10/0x20

查看锁的持有者

同样指向 {% span red, "kworker/6:4" %}

2.4 fsa4480_usbc_analog_work_fn

    Task name: kworker/0:4      [affinity: 0x1] pid:  29940 tgid:  29940 cpu: 0 prio: 120 start: 0xffffff802521cb00
    state: 0x2[D] exit_state: 0x0 stack base: 0xffffffc01f168000
    Last_enqueued_ts:   11094.659192320 Last_sleep_ts:   11094.659229143
    Stack:
    [<ffffffc0090416e0>] __switch_to+0x164
    [<ffffffc009041ee4>] __schedule+0x624
    [<ffffffc009042354>] schedule+0x84
    [<ffffffc009042430>] schedule_preempt_disabled+0x28
    [<ffffffc009044564>] __mutex_lock+0x414
    [<ffffffc009043744>] __mutex_lock_slowpath+0x14
    [<ffffffc009043684>] mutex_lock[jt]+0x70
    [<ffffffc008c8dbfc>] iio_read_channel_processed_scale+0x44
    [<ffffffc008c8ddd8>] iio_read_channel_processed+0x14
    [<ffffffc0024651c0>] fsa4480_usbc_analog_setup_switches[fsa4480_i2c]+0x48
    [<ffffffc002466564>] fsa4480_usbc_analog_work_fn[fsa4480_i2c]+0x20
    [<ffffffc0080e71d4>] process_one_work+0x240
    [<ffffffc0080e7754>] worker_thread+0x264
    [<ffffffc0080ee6c4>] kthread+0x10c
    [<ffffffc00801491c>] ret_from_fork+0x10

查看锁的拥有者

同样指向 {% span red, "kworker/6:4" %}


从目前分析的几个线程来看,问题都指向"kworker/6:4"

三、kworker/6:4死锁追踪

    Task name: kworker/6:4      [affinity: 0x40] pid:    688 tgid:    688 cpu: 6 prio: 120 start: 0xffffff804c354b00
    state: 0x2[D] exit_state: 0x0 stack base: 0xffffffc00f060000
    Last_enqueued_ts:   11094.567446383 Last_sleep_ts:   11094.582977320
    Stack:
    [<ffffffc0090416e0>] __switch_to+0x164
    [<ffffffc009041ee4>] __schedule+0x624
    [<ffffffc009042354>] schedule+0x84
    [<ffffffc00904d274>] schedule_timeout+0x44
    [<ffffffc009042ae0>] wait_for_common+0xdc
    [<ffffffc0090429f8>] wait_for_completion+0x18
    [<ffffffc0080e23e4>] __flush_work.llvm.5496837230684047041+0x260
    [<ffffffc0080e25a4>] __cancel_work_timer.llvm.5496837230684047041+0x120
    [<ffffffc0080e28c8>] cancel_delayed_work_sync+0x14
    [<ffffffc002f01c94>] smblib_handle_reverse_charge_event[qpnp_smb5_main]+0xbc
    [<ffffffc002f0a108>] smb5_iio_set_prop[qpnp_smb5_main][jt]+0x668
    [<ffffffc002ef390c>] smb5_write_raw[qpnp_smb5_main]+0x18
    [<ffffffc008c8e334>] iio_write_channel_raw+0x6c
    [<ffffffc00222ba04>] smblib_gear_shift_set[usbpd]+0x140
    [<ffffffc002f0536c>] smblib_reverse_charge_monitor_workfunc[qpnp_smb5_main]+0x7c
    [<ffffffc0080e71d4>] process_one_work+0x240
    [<ffffffc0080e7754>] worker_thread+0x264
    [<ffffffc0080ee6c4>] kthread+0x10c
    [<ffffffc00801491c>] ret_from_fork+0x10

当前处理的流程

smblib_reverse_charge_monitor_workfunc
  └── smblib_handle_reverse_charge_event
      └── cancel_delayed_work_sync
          └── __flush_work

smblib_reverse_charge_monitor_workfunc最终调用cancel_delayed_work_sync,等待这个work完成

多个其他线程/进程也在等待同一个 IIO mutex:

  • batterysecret(用户空间)
  • charge_logger(用户空间)
  • xm_charge_work(workqueue)
  • fsa4480_usbc_analog_work_fn(workqueue)

这些线程都调用了 iio_read_channel_processed(),在访问 IIO 通道时卡在 mutex_lock()进一步加重了锁争用

3.1 追踪源码

static void smblib_reverse_charge_monitor_workfunc(struct work_struct *work)
{

		smblib_gear_shift_set(chg->pd, chg->source_boost_status);
}

-->

void smblib_gear_shift_set(struct usbpd *pd, int val)
{
	union power_supply_propval pval = { 0 };

	pd->gear_shift = val;
	usbpd_err(&pd->dev, "gear_shift=%d\n", pd->gear_shift);
	if (pd->gear_shift == 1) {
		usbpd_set_state(pd, PE_SRC_SEND_CAPABILITIES);
	} else {
		pval.intval = 1; //pos:1
		usbpd_set_state(pd, PE_SRC_HARD_RESET);
		usbpd_set_psy_iio_property(pd, POWER_SUPPLY_PROP_REVERSE_QUICK_CHARGE_EVENT, &pval);//走到这里
	}
}

-->


int usbpd_set_psy_iio_property(struct usbpd *pd,
		enum iio_psy_property prop, union power_supply_propval *val)
{
	int ret;

	ret = iio_write_channel_raw(pd->iio_channels[prop], val->intval);
	if (ret < 0) {
		usbpd_err(&pd->dev, "failed to set IIO property: %d\n", prop);
		return ret;
	}

	return 0;
}

-->

int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
				enum iio_chan_info_enum attribute)
{
	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
	int ret;

	mutex_lock(&iio_dev_opaque->info_exist_lock);   //持锁
	if (!chan->indio_dev->info) {
		ret = -ENODEV;
		goto err_unlock;
	}

	ret = iio_channel_write(chan, val, val2, attribute);
err_unlock:
	mutex_unlock(&iio_dev_opaque->info_exist_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(iio_write_channel_attribute);

int iio_write_channel_raw(struct iio_channel *chan, int val)
{
	return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW);
}

--> iio_channel_write

static int iio_channel_write(struct iio_channel *chan, int val, int val2,
			     enum iio_chan_info_enum info)
{
	return chan->indio_dev->info->write_raw(chan->indio_dev,
						chan->channel, val, val2, info);
}

这个write_raw就是函数smb5_write_raw

static int smb5_write_raw(struct iio_dev *indio_dev,
			 struct iio_chan_spec const *chan, int val, int val2,
			 long mask)
{
	struct smb5 *iio_chip = iio_priv(indio_dev);
	struct smb_charger *chg = &iio_chip->chg;

	return smb5_iio_set_prop(chg, chan->channel, val);
}

根据channel=0x9B,确定走如下的流程

	case PSY_IIO_REVERSE_QUICK_CHARGE_EVENT:
		pval.intval = val;
		smblib_handle_reverse_charge_event(chg, pval.intval);
		break;
void smblib_handle_reverse_charge_event(struct smb_charger *chg, int revchg_sts)
{
     //....
	if (!chg->otg_status) {
		cancel_delayed_work_sync(&chg->reverse_charge_monitor_work);
		cancel_delayed_work_sync(&chg->delay_disable_otg);
	}

这个函数有两个cancel_delayed_work_sync

那到底是哪个worker出现问题的呢?

可以看到work指向的是 chg->reverse_charge_monitor_work

那这个work的func是哪个?

INIT_DELAYED_WORK(&chg->reverse_charge_monitor_work, smblib_reverse_charge_monitor_workfunc);

可以发现它要cancel的worker是自己本身

四、根本原因

reverse_charge_monitor_workfunc()
└── smblib_gear_shift_set()
└── iio_write_channel_raw()
└── mutex_lock(iio_dev->mlock) ← 持锁
...
🔁 smb5_write_raw
└── smblib_handle_reverse_charge_event()
└── cancel_delayed_work_sync(&self) ←❌ 等待当前 work 退出

陷入了自身的workqueue中,持的锁无法释放,其他线程阻塞等待,从而卡死