diff options
| author | Chandrakanth Patil <chandrakanth.patil@broadcom.com> | 2026-07-24 23:22:31 +0530 |
|---|---|---|
| committer | Martin K. Petersen <martin.petersen@oracle.com> | 2026-07-28 22:05:42 -0400 |
| commit | ccff8c92571500fcfed21281e33daaf645bf692f (patch) | |
| tree | 5f760053cc771d9b388515a952f15ab357f9dad5 | |
| parent | a8ddfd2425bbbafadae8700d63ed8a61a4109878 (diff) | |
scsi: mpi3mr: Fix potential deadlock in mpi3mr_fault_uevent_emit
mpi3mr_fault_uevent_emit() runs from the fault watchdog and reset paths
where host I/O may already be blocked. GFP_KERNEL allocations here, both
the local kzalloc_obj() and the ones inside kobject_uevent_env() itself,
can trigger reclaim that waits on that blocked I/O and deadlock.
Use memalloc_noio_save()/restore() to cover the whole call instead of
just the local allocation.
Fixes: ec54b348f274 ("scsi: mpi3mr: Record and report controller firmware faults")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260724164630.924288-1-chandrakanth.patil%40broadcom.com
Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Link: https://patch.msgid.link/20260724175231.935192-1-chandrakanth.patil@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_fw.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 31b19ed1528e..681868716ebd 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -9,6 +9,7 @@ #include "mpi3mr.h" #include <linux/io-64-nonatomic-lo-hi.h> +#include <linux/sched/mm.h> static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u16 reset_reason); @@ -1287,11 +1288,14 @@ out_failed: static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc) { struct kobj_uevent_env *env; + unsigned int noio_flag; int ret; + noio_flag = memalloc_noio_save(); + env = kzalloc_obj(*env); if (!env) - return; + goto out_restore; ret = add_uevent_var(env, "DRIVER=%s", mrioc->driver_name); if (ret) @@ -1326,7 +1330,8 @@ static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc) out_free: kfree(env); - +out_restore: + memalloc_noio_restore(noio_flag); } /** |
