Unplug failures are almost impossible to reproduce in practice, so let's add a debugfs knob to simulate those.
With this new knob, we can check this error case with the following sequence: # echo 1 > /sys/kernel/debug/dri/128/fake_unplug_failure # <start-some-GPU-workload> # echo fb000000.gpu > /sys/module/panthor/drivers/platform\:panthor/unbind # <stop-the-GPU-workload> Signed-off-by: Boris Brezillon <[email protected]> --- drivers/gpu/drm/panthor/panthor_device.c | 28 ++++++++++++++++++++++++++++ drivers/gpu/drm/panthor/panthor_device.h | 8 ++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c index d037c89e6198..012edf5d590c 100644 --- a/drivers/gpu/drm/panthor/panthor_device.c +++ b/drivers/gpu/drm/panthor/panthor_device.c @@ -4,6 +4,7 @@ /* Copyright 2023 Collabora ltd. */ /* Copyright 2025 ARM Limited. All rights reserved. */ +#include <linux/debugfs.h> #include <linux/clk.h> #include <linux/mm.h> #include <linux/platform_device.h> @@ -81,6 +82,8 @@ static int panthor_device_stop_before_unplug(struct panthor_device *ptdev) * procedure. */ ret = panthor_hw_soft_reset(ptdev); + if (!ret && ptdev->unplug.fake_failure) + ret = -EIO; clk_disable_unprepare(ptdev->clks.core); return ret; @@ -676,8 +679,33 @@ int panthor_device_suspend(struct device *dev) } #ifdef CONFIG_DEBUG_FS +static int panthor_device_fake_unplug_failure_get(void *data, u64 *val) +{ + struct panthor_device *ptdev = data; + + *val = ptdev->unplug.fake_failure ? 1 : 0; + return 0; +} + +static int panthor_device_fake_unplug_failure_set(void *data, u64 val) +{ + struct panthor_device *ptdev = data; + + ptdev->unplug.fake_failure = val ? true : false; + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(panthor_device_fake_unplug_failure_fops, + panthor_device_fake_unplug_failure_get, + panthor_device_fake_unplug_failure_set, "%llu\n"); + void panthor_device_debugfs_init(struct drm_minor *minor) { + struct panthor_device *ptdev = container_of(minor->dev, struct panthor_device, base); + + debugfs_create_file("fake_unplug_failure", 0644, + minor->debugfs_root, ptdev, + &panthor_device_fake_unplug_failure_fops); panthor_mmu_debugfs_init(minor); panthor_gem_debugfs_init(minor); } diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index 8c9177cf5da2..b2788373bfa9 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -282,6 +282,14 @@ struct panthor_device { * any BO attached to an active VM, ...). */ bool leak_active_resources; + + /** + * @fake_failure: When true, pretend the SOFT_RESET in the unplug path failed. + * + * This is important to check that we're doing the right thing in this very + * unlikely case. + */ + bool fake_failure; } unplug; /** @reset: Reset related fields. */ -- 2.55.0
