From c6fb88a5270f4ba24859f5ecb61cfc731ef16300 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 4 Sep 2024 21:51:50 +0900 Subject: firewire: core: allocate workqueue to handle isochronous contexts in card This commit adds a workqueue dedicated for isochronous context processing. The workqueue is allocated per instance of fw_card structure to satisfy the following characteristics descending from 1394 OHCI specification: In 1394 OHCI specification, memory pages are reserved to each isochronous context dedicated to DMA transmission. It allows to operate these per-context pages concurrently. Software can schedule hardware interrupt for several isochronous context to the same cycle, thus WQ_UNBOUND is specified. Additionally, it is sleepable to operate the content of pages, thus WQ_BH is not used. The isochronous context delivers the packets with time stamp, thus WQ_HIGHPRI is specified for semi real-time data such as IEC 61883-1/6 protocol implemented by ALSA firewire stack. The isochronous context is not used by the implementation of SCSI over IEEE1394 protocol (sbp2), thus WQ_MEM_RECLAIM is not specified. It is useful for users to adjust cpu affinity of the workqueue depending on their work loads, thus WQ_SYS is specified to expose the attributes to user space. Tested-by: Edmund Raile Link: https://lore.kernel.org/r/20240904125155.461886-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 1cca14cf5652..10e135d60824 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -134,6 +134,8 @@ struct fw_card { __be32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4]; __be32 maint_utility_register; + + struct workqueue_struct *isoc_wq; }; static inline struct fw_card *fw_card_get(struct fw_card *card) -- cgit v1.2.3 From 4f55ad754d6b7b6fa4ebcfd8c50f7e53e661a78e Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 4 Sep 2024 21:51:51 +0900 Subject: firewire: core: add local API to queue work item to workqueue specific to isochronous contexts In the previous commit, the workqueue is added per the instance of fw_card structure for isochronous contexts. The workqueue is designed to be used by the implementation of fw_card_driver structure underlying the fw_card. This commit adds some local APIs to be used by the implementation. Tested-by: Edmund Raile Link: https://lore.kernel.org/r/20240904125155.461886-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 10e135d60824..72f497b61739 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -511,6 +511,7 @@ union fw_iso_callback { struct fw_iso_context { struct fw_card *card; + struct work_struct work; int type; int channel; int speed; -- cgit v1.2.3 From 446216bd8e5d4a3ffc9738f6adffc98fbfdcc582 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 8 Sep 2024 13:05:48 +0900 Subject: firewire: core: expose kernel API to schedule work item to process isochronous context In packet-per-buffer mode for isochronous context of 1394 OHCI, software can schedule hardIRQ to the buffer in which the content of isochronous packet is processed. The actual behaviour is different between isochronous receive (IR) and transmit (IT) contexts in respect to isochronous cycle in which the hardIRQ occurs. In IR context, the hardIRQ occurs when the buffer is filled actually by the content of received packet. If there are any isochronous cycles in which the packet transmission is skipped, it is postponed to generate the hardIRQ in respect to the isochronous cycle. In IT context, software can schedule the content of packet every isochronous cycle including skipping, therefore the hardIRQ occurs in the isochronous cycle to which the software scheduled. ALSA firewire stack uses the packet-per-buffer mode for both IR/IT contexts. To process time stamp per packet (or per sample in some cases) steadily for media clock recovery against unexpected transmission skips, it uses an IT context to operate all of isochronous contexts by calls of fw_iso_context_flush_completions() in the bottom-half of hardIRQ for the IT context. Although it looks well to handle all of isochronous contexts in a single bottom-half context, it relatively takes longer time. In the future code integration (not yet), it is possible to apply parallelism method to process these context. In the case, it is useful to allow unit drivers to schedule work items to process these isochronous contexts. As a preparation, this commit exposes fw_iso_context_schedule_flush_completions() as a kernel API available by unit drivers. It is renamed from fw_iso_context_queue_work() since it is a counter part of fw_iso_context_flush_completions(). Link: https://lore.kernel.org/r/20240908040549.75304-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 72f497b61739..f815d12deda0 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -531,6 +531,23 @@ int fw_iso_context_queue(struct fw_iso_context *ctx, unsigned long payload); void fw_iso_context_queue_flush(struct fw_iso_context *ctx); int fw_iso_context_flush_completions(struct fw_iso_context *ctx); + +/** + * fw_iso_context_schedule_flush_completions() - schedule work item to process isochronous context. + * @ctx: the isochronous context + * + * Schedule a work item on workqueue to process the isochronous context. The registered callback + * function is called in the worker if some packets have been already transferred since the last + * time. If it is required to process the context in the current context, + * fw_iso_context_flush_completions() is available instead. + * + * Context: Any context. + */ +static inline void fw_iso_context_schedule_flush_completions(struct fw_iso_context *ctx) +{ + queue_work(ctx->card->isoc_wq, &ctx->work); +} + int fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags); int fw_iso_context_stop(struct fw_iso_context *ctx); -- cgit v1.2.3 From f877f1d81b2ffcac341ff62ae076d7ad5ba83f46 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Mon, 9 Sep 2024 23:00:18 +0900 Subject: firewire: core: use mutex to coordinate concurrent calls to flush completions In current implementation, test_and_set_bit_lock() is used to mediate concurrent calls of ohci_flush_iso_completions(). However, the ad-hoc usage of atomic operations is not preferable. This commit uses mutex_trylock() as the similar operations. The core function is responsible for the mediation, instead of 1394 OHCI driver. Link: https://lore.kernel.org/r/20240909140018.65289-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index f815d12deda0..19e8c5f9537c 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -512,6 +512,7 @@ union fw_iso_callback { struct fw_iso_context { struct fw_card *card; struct work_struct work; + struct mutex flushing_completions_mutex; int type; int channel; int speed; -- cgit v1.2.3 From c45b9a07b6392fa224ca76b89f24dae1046eef09 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Thu, 12 Sep 2024 22:30:34 +0900 Subject: Revert "firewire: core: use mutex to coordinate concurrent calls to flush completions" This reverts commit d9605d67562505e27dcc0f71af418118d3db91e5, since this commit is on the following reverted changes. Link: https://lore.kernel.org/r/20240912133038.238786-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 19e8c5f9537c..f815d12deda0 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -512,7 +512,6 @@ union fw_iso_callback { struct fw_iso_context { struct fw_card *card; struct work_struct work; - struct mutex flushing_completions_mutex; int type; int channel; int speed; -- cgit v1.2.3 From 4010cb1efda08ec6fd02ec5db9da909322ef352e Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Thu, 12 Sep 2024 22:30:37 +0900 Subject: firewire: core: update documentation of kernel APIs for flushing completions There is a slight difference between fw_iso_context_flush_completions() and fw_iso_context_schedule_flush_completions(). This commit updates the documentations for them. Link: https://lore.kernel.org/r/20240912133038.238786-5-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- include/linux/firewire.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/firewire.h b/include/linux/firewire.h index f815d12deda0..b632eec3ab52 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -537,9 +537,11 @@ int fw_iso_context_flush_completions(struct fw_iso_context *ctx); * @ctx: the isochronous context * * Schedule a work item on workqueue to process the isochronous context. The registered callback - * function is called in the worker if some packets have been already transferred since the last - * time. If it is required to process the context in the current context, - * fw_iso_context_flush_completions() is available instead. + * function is called by the worker when a queued packet buffer with the interrupt flag is + * completed, either after transmission in the IT context or after being filled in the IR context. + * The callback function is also called when the header buffer in the context becomes full, If it + * is required to process the context in the current context, fw_iso_context_flush_completions() is + * available instead. * * Context: Any context. */ -- cgit v1.2.3