mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context
@ 2026-09-20  8:36 Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 1/5] firewire: core: fulfill kerneldoc for address handler Takashi Sakamoto
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

Hi,

The address handlers in the cdev layer are now invoked in process context,
following the change to use a workqueue for all packet callbacks in the
1394 OHCI driver[1]. This allows the cdev layer to use GFP_KERNEL for
memory allocation and replace a spinlock with a mutex where appropriate.

This series first updates the kerneldoc for the address handler, and then
refactors the cdev layer accordingly.

[1] https://lore.kernel.org/lkml/20260919115017.859169-1-o-takashi@sakamocchi.jp/


Takashi Sakamoto (5):
  firewire: core: fulfill kerneldoc for address handler
  firewire: cdev: use mutex for phy receiver list
  firewire: cdev: use GFP_KERNEL in address handler
  firewire: cdev: refactor add_client_resource() to drop GFP flags
    argument
  firewire: cdev: refactor add_client_resource() to have release
    callback function

 drivers/firewire/core-cdev.c        | 50 +++++++++--------------------
 drivers/firewire/core-transaction.c |  8 ++---
 include/linux/firewire.h            | 22 +++++++++----
 3 files changed, 34 insertions(+), 46 deletions(-)


base-commit: d34653cbe03fb090325a61566348cabc2d9c83df
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] firewire: core: fulfill kerneldoc for address handler
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
@ 2026-09-20  8:36 ` Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 2/5] firewire: cdev: use mutex for phy receiver list Takashi Sakamoto
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

The callback for the address handler is now invoked in process context.

Update the kerneldoc for the address handler accordingly.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-transaction.c |  8 +++-----
 include/linux/firewire.h            | 22 +++++++++++++++-------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index a2a8d755ad0a..bdd2437c6f7f 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -637,16 +637,14 @@ static int put_address_handler(struct fw_address_handler *handler)
  *
  * When a request is received that falls within the specified address range, the specified callback
  * is invoked.  The parameters passed to the callback give the details of the particular request.
- * The callback is invoked in the workqueue context in most cases. However, if the request is
- * initiated by the local node, the callback is invoked in the initiator's context.
- *
- * To be called in process context.
- * Return value:  0 on success, non-zero otherwise.
  *
  * The start offset of the handler's address region is determined by
  * fw_core_add_address_handler() and is returned in handler->offset.
  *
  * Address allocations are exclusive, except for the FCP registers.
+ *
+ * Context: Process context.
+ * Returns: 0 on success, non-zero otherwise.
  */
 int fw_core_add_address_handler(struct fw_address_handler *handler,
 				const struct fw_address_region *region)
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 2b065f03565d..4bca5af6793d 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -298,17 +298,25 @@ union fw_transaction_callback {
 	fw_transaction_callback_with_tstamp_t with_tstamp;
 };
 
-/*
- * This callback handles an inbound request subaction. If the request subaction is initiated from
- * the local node (e.g. by unit driver), the execution context depends on the initiator and is
- * unspecified. Otherwise, it runs in workqueue context.
+/**
+ * typedef fw_address_callback_t - Function to handle the request of the asynchronous transaction.
+ * @card: the card instance which receives the request
+ * @request: the request instance.
+ * @tcode: the transaction code
+ * @destination: the destination node ID
+ * @source: the source node ID
+ * @generation: the bus generation in which the request was sent
+ * @offset: the destination offset in source node.
+ * @data: the request content if available.
+ * @length: the length of data.
+ * @callback_data: the data registered with this function.
  *
- * The callback should not initiate outbound request subactions directly.
- * Otherwise there is a danger of recursion of inbound and outbound
- * transactions from and to the local node.
+ * This callback handles an inbound request subaction.
  *
  * The callback is responsible that fw_send_response() is called on the @request, except for FCP
  * registers for which the core takes care of that.
+ *
+ * Context: Process context.
  */
 typedef void (*fw_address_callback_t)(struct fw_card *card,
 				      struct fw_request *request,
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] firewire: cdev: use mutex for phy receiver list
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 1/5] firewire: core: fulfill kerneldoc for address handler Takashi Sakamoto
@ 2026-09-20  8:36 ` Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 3/5] firewire: cdev: use GFP_KERNEL in address handler Takashi Sakamoto
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

In the cdev layer, the list of phy packet receivers is currently
protected by a spinlock. This requires GFP_ATOMIC for memory allocation
when enumerating the list in fw_cdev_handle_phy_packet(). However, the
function is guaranteed to be invoked in process context, so GFP_KERNEL
can be used by switching from the spinlock to a mutex.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 6d91a6e7ad0d..3dd8ea1991b0 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -47,7 +47,7 @@
 #define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW	5
 #define FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP	6
 
-static DEFINE_SPINLOCK(phy_receiver_list_lock);
+static DEFINE_MUTEX(phy_receiver_list_mutex);
 static LIST_HEAD(phy_receiver_list);
 
 struct client {
@@ -1751,9 +1751,7 @@ static int ioctl_receive_phy_packets(struct client *client, union ioctl_arg *arg
 	if (!client->device->is_local)
 		return -ENOSYS;
 
-	// NOTE: This can be without irq when we can guarantee that __fw_send_request() for local
-	// destination never runs in any type of IRQ context.
-	scoped_guard(spinlock_irq, &phy_receiver_list_lock)
+	scoped_guard(mutex, &phy_receiver_list_mutex)
 		list_move_tail(&client->phy_receiver_link, &phy_receiver_list);
 
 	client->phy_receiver_closure = a->closure;
@@ -1765,18 +1763,14 @@ void fw_cdev_handle_phy_packet(struct fw_card *card, struct fw_packet *p)
 {
 	struct client *client;
 
-	// NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for local
-	// destination never runs in any type of IRQ context.
-	guard(spinlock_irqsave)(&phy_receiver_list_lock);
+	guard(mutex)(&phy_receiver_list_mutex);
 
 	list_for_each_entry(client, &phy_receiver_list, phy_receiver_link) {
-		struct inbound_phy_packet_event *e;
-
 		if (client->device->card != card)
 			continue;
 
-		e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC);
-		if (e == NULL)
+		struct inbound_phy_packet_event *e = kmalloc(sizeof(*e) + 8, GFP_KERNEL);
+		if (!e)
 			break;
 
 		if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) {
@@ -1943,9 +1937,7 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
 	struct client_resource *resource;
 	unsigned long index;
 
-	// NOTE: This can be without irq when we can guarantee that __fw_send_request() for local
-	// destination never runs in any type of IRQ context.
-	scoped_guard(spinlock_irq, &phy_receiver_list_lock)
+	scoped_guard(mutex, &phy_receiver_list_mutex)
 		list_del(&client->phy_receiver_link);
 
 	scoped_guard(mutex, &client->device->client_list_mutex)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] firewire: cdev: use GFP_KERNEL in address handler
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 1/5] firewire: core: fulfill kerneldoc for address handler Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 2/5] firewire: cdev: use mutex for phy receiver list Takashi Sakamoto
@ 2026-09-20  8:36 ` Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 4/5] firewire: cdev: refactor add_client_resource() to drop GFP flags argument Takashi Sakamoto
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

The callback for the address handler is now guaranteed to be invoked in
process context. In the cdev layer, GFP_ATOMIC is still used for memory
allocation in the address handler.

Use GFP_KERNEL instead.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 3dd8ea1991b0..625792b6ab71 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -777,8 +777,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
 	if (is_fcp)
 		fw_request_get(request);
 
-	r = kmalloc_obj(*r, GFP_ATOMIC);
-	e = kmalloc_obj(*e, GFP_ATOMIC);
+	r = kmalloc_obj(*r);
+	e = kmalloc_obj(*e);
 	if (r == NULL || e == NULL)
 		goto failed;
 
@@ -789,7 +789,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
 	r->length  = length;
 
 	r->resource.release = release_request;
-	ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
+	ret = add_client_resource(handler->client, &r->resource, GFP_KERNEL);
 	if (ret < 0)
 		goto failed;
 
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] firewire: cdev: refactor add_client_resource() to drop GFP flags argument
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
                   ` (2 preceding siblings ...)
  2026-09-20  8:36 ` [PATCH 3/5] firewire: cdev: use GFP_KERNEL in address handler Takashi Sakamoto
@ 2026-09-20  8:36 ` Takashi Sakamoto
  2026-09-20  8:36 ` [PATCH 5/5] firewire: cdev: refactor add_client_resource() to have release callback function Takashi Sakamoto
  2026-09-21  3:00 ` [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

The add_client_resource() function has an argument for GFP flags. The
argument was originally used to distinguish atomic calls. However, all
callers now use GFP_KERNEL.

Drop the unused argument and always allocate with GFP_KERNEL.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 625792b6ab71..96f3619237f3 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -539,8 +539,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
 	return 0;
 }
 
-static int add_client_resource(struct client *client, struct client_resource *resource,
-			       gfp_t gfp_mask)
+static int add_client_resource(struct client *client, struct client_resource *resource)
 {
 	scoped_guard(spinlock_irqsave, &client->lock) {
 		u32 index;
@@ -549,13 +548,7 @@ static int add_client_resource(struct client *client, struct client_resource *re
 		if (client->in_shutdown)
 			return  -ECANCELED;
 
-		if (gfpflags_allow_blocking(gfp_mask)) {
-			ret = xa_alloc(&client->resource_xa, &index, resource, xa_limit_32b,
-				       GFP_NOWAIT);
-		} else {
-			ret = xa_alloc_bh(&client->resource_xa, &index, resource,
-					  xa_limit_32b, GFP_NOWAIT);
-		}
+		ret = xa_alloc(&client->resource_xa, &index, resource, xa_limit_32b, GFP_KERNEL);
 		if (ret < 0)
 			return ret;
 
@@ -705,7 +698,7 @@ static int init_request(struct client *client,
 	}
 
 	e->r.resource.release = release_transaction;
-	ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
+	ret = add_client_resource(client, &e->r.resource);
 	if (ret < 0)
 		goto failed;
 
@@ -789,7 +782,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
 	r->length  = length;
 
 	r->resource.release = release_request;
-	ret = add_client_resource(handler->client, &r->resource, GFP_KERNEL);
+	ret = add_client_resource(handler->client, &r->resource);
 	if (ret < 0)
 		goto failed;
 
@@ -893,7 +886,7 @@ static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
 	a->offset = r->handler.offset;
 
 	r->resource.release = release_address_handler;
-	ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+	ret = add_client_resource(client, &r->resource);
 	if (ret < 0) {
 		release_address_handler(client, &r->resource);
 		return ret;
@@ -993,7 +986,7 @@ static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg)
 		goto failed;
 
 	r->resource.release = release_descriptor;
-	ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+	ret = add_client_resource(client, &r->resource);
 	if (ret < 0) {
 		fw_core_remove_descriptor(&r->descriptor);
 		goto failed;
@@ -1479,7 +1472,7 @@ static int ioctl_allocate_iso_resource(struct client *client, union ioctl_arg *a
 	e2->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
 
 	r->resource.release = release_iso_resource_auto;
-	err = add_client_resource(client, &r->resource, GFP_KERNEL);
+	err = add_client_resource(client, &r->resource);
 	if (err < 0)
 		return err;
 	request->handle = r->resource.handle;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] firewire: cdev: refactor add_client_resource() to have release callback function
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
                   ` (3 preceding siblings ...)
  2026-09-20  8:36 ` [PATCH 4/5] firewire: cdev: refactor add_client_resource() to drop GFP flags argument Takashi Sakamoto
@ 2026-09-20  8:36 ` Takashi Sakamoto
  2026-09-21  3:00 ` [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-20  8:36 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

The implementation of the client_resource structure now requires a release
callback.

Add an argument to add_client_resource() for the release callback.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 drivers/firewire/core-cdev.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 96f3619237f3..9a471307aa5d 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -539,7 +539,8 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
 	return 0;
 }
 
-static int add_client_resource(struct client *client, struct client_resource *resource)
+static int add_client_resource(struct client *client, struct client_resource *resource,
+			       client_resource_release_fn_t release)
 {
 	scoped_guard(spinlock_irqsave, &client->lock) {
 		u32 index;
@@ -553,6 +554,7 @@ static int add_client_resource(struct client *client, struct client_resource *re
 			return ret;
 
 		resource->handle = index;
+		resource->release = release;
 		client_get(client);
 	}
 
@@ -697,8 +699,7 @@ static int init_request(struct client *client,
 		goto failed;
 	}
 
-	e->r.resource.release = release_transaction;
-	ret = add_client_resource(client, &e->r.resource);
+	ret = add_client_resource(client, &e->r.resource, release_transaction);
 	if (ret < 0)
 		goto failed;
 
@@ -781,8 +782,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
 	r->data    = payload;
 	r->length  = length;
 
-	r->resource.release = release_request;
-	ret = add_client_resource(handler->client, &r->resource);
+	ret = add_client_resource(handler->client, &r->resource, release_request);
 	if (ret < 0)
 		goto failed;
 
@@ -885,8 +885,7 @@ static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
 	}
 	a->offset = r->handler.offset;
 
-	r->resource.release = release_address_handler;
-	ret = add_client_resource(client, &r->resource);
+	ret = add_client_resource(client, &r->resource, release_address_handler);
 	if (ret < 0) {
 		release_address_handler(client, &r->resource);
 		return ret;
@@ -985,8 +984,7 @@ static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg)
 	if (ret < 0)
 		goto failed;
 
-	r->resource.release = release_descriptor;
-	ret = add_client_resource(client, &r->resource);
+	ret = add_client_resource(client, &r->resource, release_descriptor);
 	if (ret < 0) {
 		fw_core_remove_descriptor(&r->descriptor);
 		goto failed;
@@ -1471,8 +1469,7 @@ static int ioctl_allocate_iso_resource(struct client *client, union ioctl_arg *a
 	e2->iso_resource.closure = request->closure;
 	e2->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
 
-	r->resource.release = release_iso_resource_auto;
-	err = add_client_resource(client, &r->resource);
+	err = add_client_resource(client, &r->resource, release_iso_resource_auto);
 	if (err < 0)
 		return err;
 	request->handle = r->resource.handle;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context
  2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
                   ` (4 preceding siblings ...)
  2026-09-20  8:36 ` [PATCH 5/5] firewire: cdev: refactor add_client_resource() to have release callback function Takashi Sakamoto
@ 2026-09-21  3:00 ` Takashi Sakamoto
  5 siblings, 0 replies; 7+ messages in thread
From: Takashi Sakamoto @ 2026-09-21  3:00 UTC (permalink / raw)
  To: linux1394-devel; +Cc: linux-kernel

On Sun, Sep 20, 2026 at 05:36:54PM +0900, Takashi Sakamoto wrote:
> Hi,
> 
> The address handlers in the cdev layer are now invoked in process context,
> following the change to use a workqueue for all packet callbacks in the
> 1394 OHCI driver[1]. This allows the cdev layer to use GFP_KERNEL for
> memory allocation and replace a spinlock with a mutex where appropriate.
> 
> This series first updates the kerneldoc for the address handler, and then
> refactors the cdev layer accordingly.
> 
> [1] https://lore.kernel.org/lkml/20260919115017.859169-1-o-takashi@sakamocchi.jp/
> 
> 
> Takashi Sakamoto (5):
>   firewire: core: fulfill kerneldoc for address handler
>   firewire: cdev: use mutex for phy receiver list
>   firewire: cdev: use GFP_KERNEL in address handler
>   firewire: cdev: refactor add_client_resource() to drop GFP flags
>     argument
>   firewire: cdev: refactor add_client_resource() to have release
>     callback function
> 
>  drivers/firewire/core-cdev.c        | 50 +++++++++--------------------
>  drivers/firewire/core-transaction.c |  8 ++---
>  include/linux/firewire.h            | 22 +++++++++----
>  3 files changed, 34 insertions(+), 46 deletions(-)

Applied to for-next branch.


Regards

Takashi Sakamoto

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-09-21  3:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20  8:36 [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto
2026-09-20  8:36 ` [PATCH 1/5] firewire: core: fulfill kerneldoc for address handler Takashi Sakamoto
2026-09-20  8:36 ` [PATCH 2/5] firewire: cdev: use mutex for phy receiver list Takashi Sakamoto
2026-09-20  8:36 ` [PATCH 3/5] firewire: cdev: use GFP_KERNEL in address handler Takashi Sakamoto
2026-09-20  8:36 ` [PATCH 4/5] firewire: cdev: refactor add_client_resource() to drop GFP flags argument Takashi Sakamoto
2026-09-20  8:36 ` [PATCH 5/5] firewire: cdev: refactor add_client_resource() to have release callback function Takashi Sakamoto
2026-09-21  3:00 ` [PATCH 0/5] firewire: cdev: refactor packet callbacks in process context Takashi Sakamoto

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®