summaryrefslogtreecommitdiff
path: root/drivers/firewire/core-iso.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-09-12 22:30:35 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2024-09-12 22:30:35 +0900
commit6ffa9bd6ebce0626e62358dda59effe5758ebfc5 (patch)
tree9465419b648fa583c5f74b5a5ba7c332e2d692ef /drivers/firewire/core-iso.c
parentc45b9a07b6392fa224ca76b89f24dae1046eef09 (diff)
downloadlinux-6ffa9bd6ebce0626e62358dda59effe5758ebfc5.tar.gz
linux-6ffa9bd6ebce0626e62358dda59effe5758ebfc5.tar.bz2
linux-6ffa9bd6ebce0626e62358dda59effe5758ebfc5.zip
Revert "firewire: core: move workqueue handler from 1394 OHCI driver to core function"
This reverts commit 767bfb9ef27ebf760290d9f8bc303828b018c312. It appears that the call of ohci_flush_iso_completions() in the work item scheduled by hardIRQ of 1394 OHCI for any isochronous context changes the timing to queue events in the view of user space application. Link: https://lore.kernel.org/r/20240912133038.238786-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Diffstat (limited to 'drivers/firewire/core-iso.c')
-rw-r--r--drivers/firewire/core-iso.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 9f41c78878ad..f2394f3ed194 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -131,13 +131,6 @@ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed)
return 0;
}
-static void flush_completions_work(struct work_struct *work)
-{
- struct fw_iso_context *ctx = container_of(work, struct fw_iso_context, work);
-
- fw_iso_context_flush_completions(ctx);
-}
-
struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
int type, int channel, int speed, size_t header_size,
fw_iso_callback_t callback, void *callback_data)
@@ -156,7 +149,6 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
ctx->header_size = header_size;
ctx->callback.sc = callback;
ctx->callback_data = callback_data;
- INIT_WORK(&ctx->work, flush_completions_work);
trace_isoc_outbound_allocate(ctx, channel, speed);
trace_isoc_inbound_single_allocate(ctx, channel, header_size);
@@ -226,15 +218,29 @@ EXPORT_SYMBOL(fw_iso_context_queue_flush);
* to process the context asynchronously, fw_iso_context_schedule_flush_completions() is available
* instead.
*
- * Context: Process context.
+ * Context: Process context. May sleep due to disable_work_sync().
*/
int fw_iso_context_flush_completions(struct fw_iso_context *ctx)
{
+ int err;
+
trace_isoc_outbound_flush_completions(ctx);
trace_isoc_inbound_single_flush_completions(ctx);
trace_isoc_inbound_multiple_flush_completions(ctx);
- return ctx->card->driver->flush_iso_completions(ctx);
+ might_sleep();
+
+ // Avoid dead lock due to programming mistake.
+ if (WARN_ON_ONCE(current_work() == &ctx->work))
+ return 0;
+
+ disable_work_sync(&ctx->work);
+
+ err = ctx->card->driver->flush_iso_completions(ctx);
+
+ enable_work(&ctx->work);
+
+ return err;
}
EXPORT_SYMBOL(fw_iso_context_flush_completions);