一、问题背景
- 441#-AS1-KKX_0411版本高低温运行测试后工模卡死
- 手动组合键进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中,持的锁无法释放,其他线程阻塞等待,从而卡死