Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

firewire: core: maintain phy packet receivers locally in cdev layer

The list of receivers for phy packet is used only by cdev layer, while it
is maintained as a member of fw_card structure.

This commit maintains the list locally in cdev layer.

Link: https://lore.kernel.org/r/20250915234747.915922-3-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+20 -10
-1
drivers/firewire/core-card.c
··· 556 556 kref_init(&card->kref); 557 557 init_completion(&card->done); 558 558 INIT_LIST_HEAD(&card->transaction_list); 559 - INIT_LIST_HEAD(&card->phy_receiver_list); 560 559 spin_lock_init(&card->lock); 561 560 562 561 card->local_node = NULL;
+20 -7
drivers/firewire/core-cdev.c
··· 47 47 #define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5 48 48 #define FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP 6 49 49 50 + static DEFINE_SPINLOCK(phy_receiver_list_lock); 51 + static LIST_HEAD(phy_receiver_list); 52 + 50 53 struct client { 51 54 u32 version; 52 55 struct fw_device *device; ··· 1672 1669 static int ioctl_receive_phy_packets(struct client *client, union ioctl_arg *arg) 1673 1670 { 1674 1671 struct fw_cdev_receive_phy_packets *a = &arg->receive_phy_packets; 1675 - struct fw_card *card = client->device->card; 1676 1672 1677 1673 /* Access policy: Allow this ioctl only on local nodes' device files. */ 1678 1674 if (!client->device->is_local) 1679 1675 return -ENOSYS; 1680 1676 1681 - guard(spinlock_irq)(&card->lock); 1677 + // NOTE: This can be without irq when we can guarantee that __fw_send_request() for local 1678 + // destination never runs in any type of IRQ context. 1679 + scoped_guard(spinlock_irq, &phy_receiver_list_lock) 1680 + list_move_tail(&client->phy_receiver_link, &phy_receiver_list); 1682 1681 1683 - list_move_tail(&client->phy_receiver_link, &card->phy_receiver_list); 1684 1682 client->phy_receiver_closure = a->closure; 1685 1683 1686 1684 return 0; ··· 1691 1687 { 1692 1688 struct client *client; 1693 1689 1694 - guard(spinlock_irqsave)(&card->lock); 1690 + // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for local 1691 + // destination never runs in any type of IRQ context. 1692 + guard(spinlock_irqsave)(&phy_receiver_list_lock); 1695 1693 1696 - list_for_each_entry(client, &card->phy_receiver_list, phy_receiver_link) { 1697 - struct inbound_phy_packet_event *e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC); 1694 + list_for_each_entry(client, &phy_receiver_list, phy_receiver_link) { 1695 + struct inbound_phy_packet_event *e; 1696 + 1697 + if (client->device->card != card) 1698 + continue; 1699 + 1700 + e = kmalloc(sizeof(*e) + 8, GFP_ATOMIC); 1698 1701 if (e == NULL) 1699 1702 break; 1700 1703 ··· 1868 1857 struct client_resource *resource; 1869 1858 unsigned long index; 1870 1859 1871 - scoped_guard(spinlock_irq, &client->device->card->lock) 1860 + // NOTE: This can be without irq when we can guarantee that __fw_send_request() for local 1861 + // destination never runs in any type of IRQ context. 1862 + scoped_guard(spinlock_irq, &phy_receiver_list_lock) 1872 1863 list_del(&client->phy_receiver_link); 1873 1864 1874 1865 scoped_guard(mutex, &client->device->client_list_mutex)
-2
include/linux/firewire.h
··· 115 115 int index; 116 116 struct list_head link; 117 117 118 - struct list_head phy_receiver_list; 119 - 120 118 struct delayed_work br_work; /* bus reset job */ 121 119 bool br_short; 122 120