From nobody Fri Oct 10 09:22:47 2025 Received: from fhigh-a8-smtp.messagingengine.com (fhigh-a8-smtp.messagingengine.com [103.168.172.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 979732C08C8 for ; Sat, 14 Jun 2025 11:34:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900899; cv=none; b=STe73wAzAo5b4qGWOd9EvbQWLhGLgWhatO11YPSi7l9d8LvjmI4Tm3qQip4TVDSuRQIjORrjHVzN7YeB/Vh3kSQnMHZq/jFba26LiwtjP2pPOkf3JgHHdxag+sC/QWAZTE62uCAbXT38J61iSVMcgqX23TzIP1IQ+QN5txTMa+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900899; c=relaxed/simple; bh=ZMM52/9e/aI7mUDgMJjkPnTcqRxwMxNSPQV8mEfRSpU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nkxd0bHS9bZ0gwTn5+XVwNOuyHwMO/tZjQKiRMoLI2kjA41VYGIS5lDFBLkSyK4CbhoEPRDWq0nOuHHdCNBkGDDUfRmnR+GX16VX5lVSEtTWZYErLlr9frhGDTzwN/oAMVAi0VNfj4IinDKRj7Y0PQ8YFSx0yMl8gntQyyiFGKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp; spf=pass smtp.mailfrom=sakamocchi.jp; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b=Y9v7mtbC; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=qh0Qky5m; arc=none smtp.client-ip=103.168.172.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="Y9v7mtbC"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="qh0Qky5m" Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfhigh.phl.internal (Postfix) with ESMTP id 68F16114011D; Sat, 14 Jun 2025 07:34:55 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-01.internal (MEProxy); Sat, 14 Jun 2025 07:34:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1749900895; x= 1749987295; bh=6xLU0HqKW2HQImmVnnNgGa5HUcIsGUZk+o6aTIYe1Ks=; b=Y 9v7mtbC7TeFi+d5hrg9MKw6hQ2G1AXCOrd3UXH0ar8Y372cld8OjCFmQNiY/ftHZ CeIUoWK1x/m7nPthJt5atkQPsrxawDje6UkRgDhlyqfjX9+YN7gES+hI47C+bhoY WEkTuKFzGlekU4biW6kiwLPL7DB53/1DkLo5aS4/8rBxcllunpkcKYjnwUA/rG7z umZP++66Ij7Uv5Al33r6o5yNaC7BoLdgPSP4l9ff3KXtJ+XG+5miZoPqPWEherOt sc79+gcvh4NacsIaGRS5LGoPNArcB1jUkcNOzxvlT69Npn8Irq1ku5ZLHslaVeqJ e7Lt6ttLQiV6zyKDinnwg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1749900895; x=1749987295; bh=6 xLU0HqKW2HQImmVnnNgGa5HUcIsGUZk+o6aTIYe1Ks=; b=qh0Qky5mZDRMS674P ZlbpkoiE1M0exVSO23LmZxtoOa0bu28U1OndqwYTsY4d5thiF53tVkFxbBRb0EW2 H8VaV21P0Vt22+yiubjfBpZAgZx7lMFqiAwy/Og28MXZOWSUBPuTanCd7wVLUyeq yg4w8uWS1BG0erumBOImBe7QdCJixSVMmNHqM/fFZR2isl+7HPA2seNM+FKaQ6WE +7mLLOuwiA3kx1sNAgMrbgdE9V/zt7lh3QbSSsrmxBXOhgHvF5ugvy362Rx7E4qC bAaaZuKti1jlvwW1LEJVtE/eDSiHacNk+wWgDOhfQszCtjQaKC+Sl5fuxak0uUpc H/sWQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtddugddvtdejvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhephffvve fufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgr mhhothhouceoohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrf grthhtvghrnhepvdejgfejuedvgfduudekleevtefgtdevhfdtffefiefgveeuteffiedv ffekvddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomh epohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjphdpnhgspghrtghpthhtohep vddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheplhhinhhugidufeelgedquggvvh gvlheslhhishhtshdrshhouhhrtggvfhhorhhgvgdrnhgvthdprhgtphhtthhopehlihhn uhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: ie8e14432:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 14 Jun 2025 07:34:54 -0400 (EDT) From: Takashi Sakamoto To: linux1394-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/3] firewire: core: allocate workqueue for AR/AT request/response contexts Date: Sat, 14 Jun 2025 20:34:47 +0900 Message-ID: <20250614113449.388758-2-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250614113449.388758-1-o-takashi@sakamocchi.jp> References: <20250614113449.388758-1-o-takashi@sakamocchi.jp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some tasklets (softIRQs) are still used as bottom-halves to handle events for 1394 OHCI AR/AT contexts. However, using softIRQs for IRQ bottom halves is generally discouraged today. This commit adds a per-fw_card workqueue to accommodate the behaviour specified by the 1394 OHCI specification. According to the 1394 OHCI specification, system memory pages are reserved for each asynchronous DMA context. This allows concurrent operation across contexts. In the 1394 OHCI PCI driver implementation, the hardware generates IRQs either upon receiving asynchronous packets from other nodes (incoming) or after completing transmission to them (outgoing). These independent events can occur in the same transmission cycle, therefore the max_active parameter for the workqueue is set to the total number of AR/AT contexts (=3D4). The WQ_UNBOUND flag is used to allow the work to be scheduled on any available core, since there is little CPU cache affinity benefit for the data. Each DMA context uses a circular descriptor list in system memory, allowing deferred data processing in software as long as buffer overrun are avoided. Since the overall operation is sleepable except for small atomic regions, WQ_BH is not used. As the descriptors contain timestamps, WQ_HIGHPRI is specified to support semi-real-time processing. The asynchronous context is also used by the SCSI over IEEE 1394 protocol implementation (sbp2), which can be part of memory reclaim paths. Therefore, WQ_MEM_RECLAIM is required. To allow uses to adjust CPU affinity according to workload, WQ_SYSFS is specified so that workqueue attributes are exposed to user space. Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-card.c | 40 +++++++++++++++++++++++++++--------- include/linux/firewire.h | 1 + 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 2b6ad47b6d57..df0bb5b96ddc 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -574,7 +574,6 @@ EXPORT_SYMBOL(fw_card_initialize); int fw_card_add(struct fw_card *card, u32 max_receive, u32 link_speed, u64= guid, unsigned int supported_isoc_contexts) { - struct workqueue_struct *isoc_wq; int ret; =20 // This workqueue should be: @@ -589,12 +588,29 @@ int fw_card_add(struct fw_card *card, u32 max_receive= , u32 link_speed, u64 guid, // * =3D=3D WQ_SYSFS Parameters are available via sysfs. // * max_active =3D=3D n_it + n_ir A hardIRQ could notify events for mul= tiple isochronous // contexts if they are scheduled to the same cycle. - isoc_wq =3D alloc_workqueue("firewire-isoc-card%u", - WQ_UNBOUND | WQ_FREEZABLE | WQ_HIGHPRI | WQ_SYSFS, - supported_isoc_contexts, card->index); - if (!isoc_wq) + card->isoc_wq =3D alloc_workqueue("firewire-isoc-card%u", + WQ_UNBOUND | WQ_FREEZABLE | WQ_HIGHPRI | WQ_SYSFS, + supported_isoc_contexts, card->index); + if (!card->isoc_wq) return -ENOMEM; =20 + // This workqueue should be: + // * !=3D WQ_BH Sleepable. + // * =3D=3D WQ_UNBOUND Any core can process data for asynchronous conte= xt. + // * =3D=3D WQ_MEM_RECLAIM Used for any backend of block device. + // * =3D=3D WQ_FREEZABLE The target device would not be available when = being freezed. + // * =3D=3D WQ_HIGHPRI High priority to process semi-realtime timestamp= ed data. + // * =3D=3D WQ_SYSFS Parameters are available via sysfs. + // * max_active =3D=3D 4 A hardIRQ could notify events for a pair of re= quests and + // response AR/AT contexts. + card->async_wq =3D alloc_workqueue("firewire-async-card%u", + WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_HIGHPRI | WQ_SYSFS, + 4, card->index); + if (!card->async_wq) { + ret =3D -ENOMEM; + goto err_isoc; + } + card->max_receive =3D max_receive; card->link_speed =3D link_speed; card->guid =3D guid; @@ -603,15 +619,17 @@ int fw_card_add(struct fw_card *card, u32 max_receive= , u32 link_speed, u64 guid, =20 generate_config_rom(card, tmp_config_rom); ret =3D card->driver->enable(card, tmp_config_rom, config_rom_length); - if (ret < 0) { - destroy_workqueue(isoc_wq); - return ret; - } + if (ret < 0) + goto err_async; =20 - card->isoc_wq =3D isoc_wq; list_add_tail(&card->link, &card_list); =20 return 0; +err_async: + destroy_workqueue(card->async_wq); +err_isoc: + destroy_workqueue(card->isoc_wq); + return ret; } EXPORT_SYMBOL(fw_card_add); =20 @@ -744,6 +762,7 @@ void fw_core_remove_card(struct fw_card *card) dummy_driver.stop_iso =3D card->driver->stop_iso; card->driver =3D &dummy_driver; drain_workqueue(card->isoc_wq); + drain_workqueue(card->async_wq); =20 scoped_guard(spinlock_irqsave, &card->lock) fw_destroy_nodes(card); @@ -753,6 +772,7 @@ void fw_core_remove_card(struct fw_card *card) wait_for_completion(&card->done); =20 destroy_workqueue(card->isoc_wq); + destroy_workqueue(card->async_wq); =20 WARN_ON(!list_empty(&card->transaction_list)); } diff --git a/include/linux/firewire.h b/include/linux/firewire.h index b632eec3ab52..c55b8e30e700 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -136,6 +136,7 @@ struct fw_card { __be32 maint_utility_register; =20 struct workqueue_struct *isoc_wq; + struct workqueue_struct *async_wq; }; =20 static inline struct fw_card *fw_card_get(struct fw_card *card) --=20 2.48.1 From nobody Fri Oct 10 09:22:47 2025 Received: from fhigh-a8-smtp.messagingengine.com (fhigh-a8-smtp.messagingengine.com [103.168.172.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D63DD2C08CA for ; Sat, 14 Jun 2025 11:34:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900900; cv=none; b=AQmVUyx55zgt+PEcTALhCZvzNznvO+nj4j0OyfITIuQXzWk+BEWmxYTdC7ut3kwNZ7fHn/OwSUE8ur5JCZKf+ydPctWhhQrRaJoyqMQdHNVwht7t+/4uMizdulAxY5+U3ic+BwvqNlvJJB+cta2sZ+XSZt1yoF9kQ5GJNFV1eTg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900900; c=relaxed/simple; bh=ITbtmPf4cpk3X83sE0SP/sCMpsGJGN4Oib1B9xSOsRQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rhvVXE4K3+zM8SrswurHEK2jvN+PEgv6Ewb/Izs+ncNSpsot2+ZJK+rEdgK/Gd+XVXL6GpQIFPuUvpQHkAbx0X94ogUyulgVWV1vfFaif71ZMzvA6pzTt5YebvpOn0dVQBcrDYfRoEB2qQIhdKc3cLb/6bSOjo5B8VErdqODQSg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp; spf=pass smtp.mailfrom=sakamocchi.jp; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b=Moko1dNr; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VD6dlCH0; arc=none smtp.client-ip=103.168.172.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="Moko1dNr"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VD6dlCH0" Received: from phl-compute-07.internal (phl-compute-07.phl.internal [10.202.2.47]) by mailfhigh.phl.internal (Postfix) with ESMTP id BC1AD1140158; Sat, 14 Jun 2025 07:34:56 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-07.internal (MEProxy); Sat, 14 Jun 2025 07:34:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1749900896; x= 1749987296; bh=s0mnxanqQ2wO103H6uaQ4iaNpdz2HeEAgNvMawAzuog=; b=M oko1dNr4MZoInYSMchUHTnfgqG2VROiw7dEsWSSmlwVCZHT/3b/qVWIW2PANhCFF dImHODEmZ+3j9+22BXQ8D9x+OKlMASj3fu2F8qgTlezXWbdxbQ7dy8TkqOBLpzax cAtasytFJFta7P1u+2Xc6U8eTfKkWQozcY+zVqrY9FcHizKu1irjO6qL7lbNdHwo o8OEZXsCa/hvKrqD7rRcJ8tYtSSNMxG6A1Ucmsg4m0OLuI2dnHb2Vnpdvgb7Vmd5 EanMlZNTypPuAGBuSBDbXCIhkwdE6Jygb7P6KapIiIQeejyUzG4bt6vysutKg/w/ ZFIjFMj1ybV1oocpCJrHQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1749900896; x=1749987296; bh=s 0mnxanqQ2wO103H6uaQ4iaNpdz2HeEAgNvMawAzuog=; b=VD6dlCH080Z65LQg7 16XFlW1JYQR0EBPs84LZKCD4VlwBdRNj3DVvyCkB0NYR0YLgnSK1Sa/+AhzqSAIg JJCVwVn1eIOWK1e/yyfUK8TKp1UF9VAaY/aOC/PlvEoIGVnIX71dQnSsrtse+/Ps LmTtGgewcikCkqowa4d6ngbv9TnM5ZLju3CsB5Gom7z8sPQ57K7wLsaWvHHsRaST 6CQpkunHQEygFDfd91k73NPSIBflYEcR7hBm4nbBYFnRJS1QStgOde2qPevSY+9V VgfuWbG9zcBkE11XUhRIbsTgRkrgjUpo3gLSSjgl1S+SOlgc/QalV3I4cOzoSlKU KdG3w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtddugddvtdejvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhephffvve fufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgr mhhothhouceoohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrf grthhtvghrnhepvdejgfejuedvgfduudekleevtefgtdevhfdtffefiefgveeuteffiedv ffekvddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomh epohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjphdpnhgspghrtghpthhtohep vddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheplhhinhhugidufeelgedquggvvh gvlheslhhishhtshdrshhouhhrtggvfhhorhhgvgdrnhgvthdprhgtphhtthhopehlihhn uhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: ie8e14432:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 14 Jun 2025 07:34:55 -0400 (EDT) From: Takashi Sakamoto To: linux1394-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org Subject: [PATCH 2/3] firewire: ohci: use workqueue to handle events of AR request/response contexts Date: Sat, 14 Jun 2025 20:34:48 +0900 Message-ID: <20250614113449.388758-3-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250614113449.388758-1-o-takashi@sakamocchi.jp> References: <20250614113449.388758-1-o-takashi@sakamocchi.jp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit adds a work item to handle events of 1394 OHCI AR request/response contexts, and queues the item to the specific workqueue. The call of struct fw_address_handler.address_callback() is done in the workqueue when receiving any requests from the remove nodes. Additionally, the call of struct fw_packet.callback() is done in the workqueue too when receiving acknowledge to the asynchronous packet for the response subaction of split transaction to the remote nodes. Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-transaction.c | 7 ++++--- drivers/firewire/ohci.c | 27 +++++++++++---------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-tr= ansaction.c index 2bd5deb9054e..d28477d84697 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -557,9 +557,10 @@ const struct fw_address_region fw_unit_space_region = =3D * * region->start, ->end, and handler->length have to be quadlet-aligned. * - * When a request is received that falls within the specified address rang= e, - * the specified callback is invoked. The parameters passed to the callba= ck - * give the details of the particular request. + * When a request is received that falls within the specified address rang= e, 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. diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 40313a3ec63e..68317b5a64a7 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -101,7 +101,7 @@ struct ar_context { void *pointer; unsigned int last_buffer_index; u32 regs; - struct tasklet_struct tasklet; + struct work_struct work; }; =20 struct context; @@ -1016,9 +1016,9 @@ static void ar_recycle_buffers(struct ar_context *ctx= , unsigned int end_buffer) } } =20 -static void ar_context_tasklet(unsigned long data) +static void ohci_ar_context_work(struct work_struct *work) { - struct ar_context *ctx =3D (struct ar_context *)data; + struct ar_context *ctx =3D from_work(ctx, work, work); unsigned int end_buffer_index, end_buffer_offset; void *p, *end; =20 @@ -1026,23 +1026,19 @@ static void ar_context_tasklet(unsigned long data) if (!p) return; =20 - end_buffer_index =3D ar_search_last_active_buffer(ctx, - &end_buffer_offset); + end_buffer_index =3D ar_search_last_active_buffer(ctx, &end_buffer_offset= ); ar_sync_buffers_for_cpu(ctx, end_buffer_index, end_buffer_offset); end =3D ctx->buffer + end_buffer_index * PAGE_SIZE + end_buffer_offset; =20 if (end_buffer_index < ar_first_buffer_index(ctx)) { - /* - * The filled part of the overall buffer wraps around; handle - * all packets up to the buffer end here. If the last packet - * wraps around, its tail will be visible after the buffer end - * because the buffer start pages are mapped there again. - */ + // The filled part of the overall buffer wraps around; handle all packet= s up to the + // buffer end here. If the last packet wraps around, its tail will be v= isible after + // the buffer end because the buffer start pages are mapped there again. void *buffer_end =3D ctx->buffer + AR_BUFFERS * PAGE_SIZE; p =3D handle_ar_packets(ctx, p, buffer_end); if (p < buffer_end) goto error; - /* adjust p to point back into the actual buffer */ + // adjust p to point back into the actual buffer p -=3D AR_BUFFERS * PAGE_SIZE; } =20 @@ -1057,7 +1053,6 @@ static void ar_context_tasklet(unsigned long data) ar_recycle_buffers(ctx, end_buffer_index); =20 return; - error: ctx->pointer =3D NULL; } @@ -1073,7 +1068,7 @@ static int ar_context_init(struct ar_context *ctx, st= ruct fw_ohci *ohci, =20 ctx->regs =3D regs; ctx->ohci =3D ohci; - tasklet_init(&ctx->tasklet, ar_context_tasklet, (unsigned long)ctx); + INIT_WORK(&ctx->work, ohci_ar_context_work); =20 for (i =3D 0; i < AR_BUFFERS; i++) { ctx->pages[i] =3D dma_alloc_pages(dev, PAGE_SIZE, &dma_addr, @@ -2238,10 +2233,10 @@ static irqreturn_t irq_handler(int irq, void *data) } =20 if (event & OHCI1394_RQPkt) - tasklet_schedule(&ohci->ar_request_ctx.tasklet); + queue_work(ohci->card.async_wq, &ohci->ar_request_ctx.work); =20 if (event & OHCI1394_RSPkt) - tasklet_schedule(&ohci->ar_response_ctx.tasklet); + queue_work(ohci->card.async_wq, &ohci->ar_response_ctx.work); =20 if (event & OHCI1394_reqTxComplete) tasklet_schedule(&ohci->at_request_ctx.tasklet); --=20 2.48.1 From nobody Fri Oct 10 09:22:47 2025 Received: from fhigh-a8-smtp.messagingengine.com (fhigh-a8-smtp.messagingengine.com [103.168.172.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 338A72C08D2 for ; Sat, 14 Jun 2025 11:34:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900901; cv=none; b=Zsa7YtmbmB+RWRnqbLjtGFVO2lT2zqJ12+xy6QtQSvCS/I8fj4upLiFp+dbccoqpcr+hYhcIcmxWodlq24f7mjyAsiwpnb2WSYogLl/pm/yH1k7nVUEkUi0+0RmV6BmimZ4H1DFCxy51TMu3tuaxX0Jur7j5rfeNxTLOEr22dh4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749900901; c=relaxed/simple; bh=Rg3Pr0KjVpHhSuV2HAAJYJlu5JXj+HSAqOdE5nZdtKg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Qv+cU05aLYrq2doT6rbiFEckGfWv4tt0XEtX6+iwCjCMod4v4YCLKHkosWQorHItV+fiWRim/m84U8W1taxDhw1c4IWHz6R0LW5WzLh266jqVQ1y4oI/glNy+ZLy+fyIT7Uvk8rKp3viEeIEYnO91le8QWM8x1dEZMes1eO4GkI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp; spf=pass smtp.mailfrom=sakamocchi.jp; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b=oHt/WwTY; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=b8HkKba5; arc=none smtp.client-ip=103.168.172.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sakamocchi.jp Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sakamocchi.jp header.i=@sakamocchi.jp header.b="oHt/WwTY"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="b8HkKba5" Received: from phl-compute-12.internal (phl-compute-12.phl.internal [10.202.2.52]) by mailfhigh.phl.internal (Postfix) with ESMTP id 2374C1140156; Sat, 14 Jun 2025 07:34:58 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-12.internal (MEProxy); Sat, 14 Jun 2025 07:34:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakamocchi.jp; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1749900898; x= 1749987298; bh=oDfTpkSjhD1e0vY0YkSNYlxPO+dTPHYdbTXzUojYEqk=; b=o Ht/WwTYSmpYYpAUlLGwl8IP/0A2HmMl3p306cNM7ZfPhBvxagvRLCxn4X6rygVYG 9W3fQ47sA2WmvUBEhQ/2i/MqGmKsqdJazIxqAZORVMWSig+AXAUGz1EVTfVKbJWy xKOKikKfvKgLUNXcAviAqs7UDTlkwVncKwHQoEHNBHOzHgKWVR7Y9HlZ+XGMJ4Yg lK50cZYSpWCFOan6csagYmKCE3exfsQgSp6srpAcViBVeDhY8vrQBLlgDuSL8gGz PxXUrDqgyQrjFU9nAIuEqfcT0u75r1glZIFJW30XYlL5rNwQyW7srIhscT/mZIsl WzAu+b4dmShbhWC2ex7Bg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1749900898; x=1749987298; bh=o DfTpkSjhD1e0vY0YkSNYlxPO+dTPHYdbTXzUojYEqk=; b=b8HkKba5MTPBSvkp4 EjdXPizzsXfhR3ZIEUq5hKVb8EC7ZJ6M2mTuZ4+yr0z+CEhuf0k1l6Oa4MXcNdw0 fswvXW11nXWLqH2u5BppwnGagmqgXAV2FRtmcrPLieS8ZT0LhtBfN5EyyDwumAlp 9B0YCdAxszCcHaDcz/OO3MeYGv+/gtzu/UZblWnqODlEAnomvwg0bEQtgzU3kQnO hPyrijszCLbUK6rwtfL9lan7GyjFzE37JbPOwAJ3v8oRkGWr9y7vLxUkWAfl+i4s khYbz8lhzBhuaunSFdnLrs83nAQnOKqixFNiP0Epi9UVuGANR+sy1iQZJupki3ME CvQ+Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtddugddvtdejvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhephffvve fufffkofgjfhgggfestdekredtredttdenucfhrhhomhepvfgrkhgrshhhihcuufgrkhgr mhhothhouceoohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjpheqnecuggftrf grthhtvghrnhepvdejgfejuedvgfduudekleevtefgtdevhfdtffefiefgveeuteffiedv ffekvddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomh epohdqthgrkhgrshhhihesshgrkhgrmhhotggthhhirdhjphdpnhgspghrtghpthhtohep vddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheplhhinhhugidufeelgedquggvvh gvlheslhhishhtshdrshhouhhrtggvfhhorhhgvgdrnhgvthdprhgtphhtthhopehlihhn uhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: ie8e14432:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 14 Jun 2025 07:34:56 -0400 (EDT) From: Takashi Sakamoto To: linux1394-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org Subject: [PATCH 3/3] firewire: ohci: use workqueue to handle events of AT request/response contexts Date: Sat, 14 Jun 2025 20:34:49 +0900 Message-ID: <20250614113449.388758-4-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250614113449.388758-1-o-takashi@sakamocchi.jp> References: <20250614113449.388758-1-o-takashi@sakamocchi.jp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This commit adds a work item to handle events of 1394 OHCI AT request/response contexts, and queues the item to the specific workqueue. The call of struct fw_packet.callbaqck() is done in the workqueue when receiving acknowledgement to the asynchronous packet transferred to remote node. Signed-off-by: Takashi Sakamoto --- drivers/firewire/net.c | 4 ++-- drivers/firewire/ohci.c | 40 ++++++++++++++++++++++++---------------- include/linux/firewire.h | 11 +++++++++-- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 1bf0e15c1540..6d6446713539 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1007,7 +1007,7 @@ static int fwnet_send_packet(struct fwnet_packet_task= *ptask) =20 spin_lock_irqsave(&dev->lock, flags); =20 - /* If the AT tasklet already ran, we may be last user. */ + /* If the AT work item already ran, we may be last user. */ free =3D (ptask->outstanding_pkts =3D=3D 0 && !ptask->enqueued); if (!free) ptask->enqueued =3D true; @@ -1026,7 +1026,7 @@ static int fwnet_send_packet(struct fwnet_packet_task= *ptask) =20 spin_lock_irqsave(&dev->lock, flags); =20 - /* If the AT tasklet already ran, we may be last user. */ + /* If the AT work item already ran, we may be last user. */ free =3D (ptask->outstanding_pkts =3D=3D 0 && !ptask->enqueued); if (!free) ptask->enqueued =3D true; diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 68317b5a64a7..a81a876819d0 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -158,7 +158,7 @@ struct context { =20 descriptor_callback_t callback; =20 - struct tasklet_struct tasklet; + struct work_struct work; }; =20 struct iso_context { @@ -1176,9 +1176,9 @@ static void context_retire_descriptors(struct context= *ctx) } } =20 -static void context_tasklet(unsigned long data) +static void ohci_at_context_work(struct work_struct *work) { - struct context *ctx =3D (struct context *) data; + struct context *ctx =3D from_work(ctx, work, work); =20 context_retire_descriptors(ctx); } @@ -1243,7 +1243,6 @@ static int context_init(struct context *ctx, struct f= w_ohci *ohci, ctx->buffer_tail =3D list_entry(ctx->buffer_list.next, struct descriptor_buffer, list); =20 - tasklet_init(&ctx->tasklet, context_tasklet, (unsigned long)ctx); ctx->callback =3D callback; =20 /* @@ -1524,13 +1523,17 @@ static int at_context_queue_packet(struct context *= ctx, =20 static void at_context_flush(struct context *ctx) { - tasklet_disable(&ctx->tasklet); + // Avoid dead lock due to programming mistake. + if (WARN_ON_ONCE(current_work() =3D=3D &ctx->work)) + return; + + disable_work_sync(&ctx->work); =20 - ctx->flushing =3D true; - context_tasklet((unsigned long)ctx); - ctx->flushing =3D false; + WRITE_ONCE(ctx->flushing, true); + ohci_at_context_work(&ctx->work); + WRITE_ONCE(ctx->flushing, false); =20 - tasklet_enable(&ctx->tasklet); + enable_work(&ctx->work); } =20 static int handle_at_packet(struct context *context, @@ -1542,7 +1545,7 @@ static int handle_at_packet(struct context *context, struct fw_ohci *ohci =3D context->ohci; int evt; =20 - if (last->transfer_status =3D=3D 0 && !context->flushing) + if (last->transfer_status =3D=3D 0 && !READ_ONCE(context->flushing)) /* This descriptor isn't done yet, stop iteration. */ return 0; =20 @@ -1576,7 +1579,7 @@ static int handle_at_packet(struct context *context, break; =20 case OHCI1394_evt_missing_ack: - if (context->flushing) + if (READ_ONCE(context->flushing)) packet->ack =3D RCODE_GENERATION; else { /* @@ -1598,7 +1601,7 @@ static int handle_at_packet(struct context *context, break; =20 case OHCI1394_evt_no_status: - if (context->flushing) { + if (READ_ONCE(context->flushing)) { packet->ack =3D RCODE_GENERATION; break; } @@ -2239,10 +2242,10 @@ static irqreturn_t irq_handler(int irq, void *data) queue_work(ohci->card.async_wq, &ohci->ar_response_ctx.work); =20 if (event & OHCI1394_reqTxComplete) - tasklet_schedule(&ohci->at_request_ctx.tasklet); + queue_work(ohci->card.async_wq, &ohci->at_request_ctx.work); =20 if (event & OHCI1394_respTxComplete) - tasklet_schedule(&ohci->at_response_ctx.tasklet); + queue_work(ohci->card.async_wq, &ohci->at_response_ctx.work); =20 if (event & OHCI1394_isochRx) { iso_event =3D reg_read(ohci, OHCI1394_IsoRecvIntEventClear); @@ -2684,7 +2687,10 @@ static int ohci_cancel_packet(struct fw_card *card, = struct fw_packet *packet) struct driver_data *driver_data =3D packet->driver_data; int ret =3D -ENOENT; =20 - tasklet_disable_in_atomic(&ctx->tasklet); + // Avoid dead lock due to programming mistake. + if (WARN_ON_ONCE(current_work() =3D=3D &ctx->work)) + return 0; + disable_work_sync(&ctx->work); =20 if (packet->ack !=3D 0) goto out; @@ -2703,7 +2709,7 @@ static int ohci_cancel_packet(struct fw_card *card, s= truct fw_packet *packet) packet->callback(packet, &ohci->card, packet->ack); ret =3D 0; out: - tasklet_enable(&ctx->tasklet); + enable_work(&ctx->work); =20 return ret; } @@ -3765,11 +3771,13 @@ static int pci_probe(struct pci_dev *dev, OHCI1394_AsReqTrContextControlSet, handle_at_packet); if (err < 0) return err; + INIT_WORK(&ohci->at_request_ctx.work, ohci_at_context_work); =20 err =3D context_init(&ohci->at_response_ctx, ohci, OHCI1394_AsRspTrContextControlSet, handle_at_packet); if (err < 0) return err; + INIT_WORK(&ohci->at_response_ctx.work, ohci_at_context_work); =20 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); ohci->ir_context_channels =3D ~0ULL; diff --git a/include/linux/firewire.h b/include/linux/firewire.h index c55b8e30e700..cceb70415ed2 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -308,8 +308,7 @@ struct fw_packet { * For successful transmission, the status code is the ack received * from the destination. Otherwise it is one of the juju-specific * rcodes: RCODE_SEND_ERROR, _CANCELLED, _BUSY, _GENERATION, _NO_ACK. - * The callback can be called from tasklet context and thus - * must never block. + * The callback can be called from workqueue and thus must never block. */ fw_packet_callback_t callback; int ack; @@ -382,6 +381,10 @@ void __fw_send_request(struct fw_card *card, struct fw= _transaction *t, int tcode * * A variation of __fw_send_request() to generate callback for response su= baction without time * stamp. + * + * The callback is invoked in the workqueue context in most cases. However= , if an error is detected + * before queueing or the destination address refers to the local node, it= is invoked in the + * current context instead. */ static inline void fw_send_request(struct fw_card *card, struct fw_transac= tion *t, int tcode, int destination_id, int generation, int speed, @@ -411,6 +414,10 @@ static inline void fw_send_request(struct fw_card *car= d, struct fw_transaction * * @callback_data: data to be passed to the transaction completion callback * * A variation of __fw_send_request() to generate callback for response su= baction with time stamp. + * + * The callback is invoked in the workqueue context in most cases. However= , if an error is detected + * before queueing or the destination address refers to the local node, it= is invoked in the current + * context instead. */ static inline void fw_send_request_with_tstamp(struct fw_card *card, struc= t fw_transaction *t, int tcode, int destination_id, int generation, int speed, unsigned long l= ong offset, --=20 2.48.1