mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 07:03:37 +02:00
The call to pm_runtime_get_sync() in ufshcd_program_key() can deadlock
because it waits for the UFS controller to be resumed, but it can itself
be reached while resuming the UFS controller via:
- ufshcd_runtime_resume()
- ufshcd_resume()
- ufshcd_reset_and_restore()
- ufshcd_host_reset_and_restore()
- ufshcd_hba_enable()
- ufshcd_hba_execute_hce()
- ufshcd_hba_start()
- ufshcd_crypto_enable()
- keyslot_manager_reprogram_all_keys()
- ufshcd_crypto_keyslot_program()
- ufshcd_program_key()
But pm_runtime_get_sync() *is* needed when evicting a key. Also, on
pre-4.20 kernels it's needed when programming a keyslot for a bio since
the block layer used to resume the device in a different place.
Thus, it's hard for drivers to know what to do in .keyslot_program() and
.keyslot_evict(). In old kernels it may even be impossible unless we
were to pass more information down from the keyslot_manager.
There's also another possible deadlock: keyslot programming and eviction
take ksm->lock for write and then resume the device, which may result in
ksm->lock being taken again via the above call stack. To fix this, we
should resume the device before taking ksm->lock.
Fix these problems by moving to a better design where the block layer
(namely, the keyslot manager) handles runtime power management instead
of drivers. This is analogous to the block layer's existing runtime
power management support (blk-pm), which handles resuming devices when
bios are submitted to them so that drivers don't need to handle it.
Test: Tested on coral with:
echo 5 > /sys/bus/platform/devices/1d84000.ufshc/rpm_lvl
sleep 30
touch /data && sync # hangs before this fix
Also verified via kvm-xfstests that blk-crypto-fallback continues
to work both with and without CONFIG_PM=y.
Bug: 137270441
Bug: 149368295
Change-Id: I6bc9fb81854afe7edf490d71796ee68a61f7cbc8
Signed-off-by: Eric Biggers <ebiggers@google.com>
|
||
|---|---|---|
| .. | ||
| partitions | ||
| badblocks.c | ||
| bfq-cgroup.c | ||
| bfq-iosched.c | ||
| bfq-iosched.h | ||
| bfq-wf2q.c | ||
| bio-crypt-ctx.c | ||
| bio-integrity.c | ||
| bio.c | ||
| blk-cgroup.c | ||
| blk-core.c | ||
| blk-crypto-fallback.c | ||
| blk-crypto-internal.h | ||
| blk-crypto.c | ||
| blk-exec.c | ||
| blk-flush.c | ||
| blk-integrity.c | ||
| blk-ioc.c | ||
| blk-iolatency.c | ||
| blk-lib.c | ||
| blk-map.c | ||
| blk-merge.c | ||
| blk-mq-cpumap.c | ||
| blk-mq-debugfs-zoned.c | ||
| blk-mq-debugfs.c | ||
| blk-mq-debugfs.h | ||
| blk-mq-pci.c | ||
| blk-mq-rdma.c | ||
| blk-mq-sched.c | ||
| blk-mq-sched.h | ||
| blk-mq-sysfs.c | ||
| blk-mq-tag.c | ||
| blk-mq-tag.h | ||
| blk-mq-virtio.c | ||
| blk-mq.c | ||
| blk-mq.h | ||
| blk-rq-qos.c | ||
| blk-rq-qos.h | ||
| blk-settings.c | ||
| blk-softirq.c | ||
| blk-stat.c | ||
| blk-stat.h | ||
| blk-sysfs.c | ||
| blk-tag.c | ||
| blk-throttle.c | ||
| blk-timeout.c | ||
| blk-wbt.c | ||
| blk-wbt.h | ||
| blk-zoned.c | ||
| blk.h | ||
| bounce.c | ||
| bsg-lib.c | ||
| bsg.c | ||
| cfq-iosched.c | ||
| cmdline-parser.c | ||
| compat_ioctl.c | ||
| deadline-iosched.c | ||
| elevator.c | ||
| genhd.c | ||
| ioctl.c | ||
| ioprio.c | ||
| Kconfig | ||
| Kconfig.iosched | ||
| keyslot-manager.c | ||
| kyber-iosched.c | ||
| Makefile | ||
| mq-deadline.c | ||
| noop-iosched.c | ||
| opal_proto.h | ||
| partition-generic.c | ||
| scsi_ioctl.c | ||
| sed-opal.c | ||
| t10-pi.c | ||