[PATCH] floppy: flush pending work before releasing resources on init failure

Karl Mehltretter <[email protected]>
Newsgroups org.kernel.vger.linux-block,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
do_floppy_init() probes each FDC with user_reset_fdc(), which queues a
redo_fd_request() work item on floppy_wq that may still be pending when
the probe finishes. When no controller is found, the error path calls
floppy_release_irq_and_dma() to free the IRQ and DMA channel, and only
later destroys the workqueue. destroy_workqueue() drains the queued work
last, so it can run after the IRQ and DMA are already gone:

  floppy0: no floppy controllers found
  work still pending

The flush used to be here. Commit 070ad7e793dc ("floppy: convert to
delayed work and single-thread wq") renamed the label out_flush_work to
out_release_dma and dropped it. Restore it so the work drains before the
IRQ and DMA are released, as floppy_module_exit() already does.

Fixes: 070ad7e793dc ("floppy: convert to delayed work and single-thread wq")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Karl Mehltretter <[email protected]>
---

Noticed while running mainline on an emulated Acorn RiscPC, a custom
personal QEMU machine. It has no floppy controller and rpc_defconfig
sets CONFIG_BLK_DEV_FD=y, so every boot takes the no-controller error
path. No disk is registered there, so the drained work takes the
empty-request fast path and just unlocks the FDC, leaving only the
spurious message.

Verified with 100 QEMU boots per platform on v7.2-rc4, no controller
present. "work still pending" appeared on an unfixed kernel vs with this
patch:

  Acorn RiscPC, rpc_defconfig: 100/100 -> 0/100
  x86_64 defconfig, qemu -M q35: 6/100 -> 0/100

With a controller present on qemu -M pc, reading and writing a 1.44M
floppy image still works.

 drivers/block/floppy.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index f04397b8e381..6cfd114d27df 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4744,6 +4744,8 @@ static int __init do_floppy_init(void)
 		}
 	}
 out_release_dma:
+	/* Drain the queued redo_fd_request() before releasing IRQ and DMA. */
+	flush_workqueue(floppy_wq);
 	if (atomic_read(&usage_count))
 		floppy_release_irq_and_dma();
 out_unreg_driver:
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.