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.

Merge branch 'net-macb-fix-two-lock-warnings-when-wol-is-used'

Kevin Hao says:

====================
net: macb: Fix two lock warnings when WOL is used

This patch series addresses two lock warnings that occur when using WOL as a
wakeup source on my AMD ZynqMP board.
====================

Link: https://patch.msgid.link/20260318-macb-irq-v2-0-f1179768ab24@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+23 -14
+23 -14
drivers/net/ethernet/cadence/macb_main.c
··· 5776 5776 struct macb_queue *queue; 5777 5777 struct in_device *idev; 5778 5778 unsigned long flags; 5779 + u32 tmp, ifa_local; 5779 5780 unsigned int q; 5780 5781 int err; 5781 - u32 tmp; 5782 5782 5783 5783 if (!device_may_wakeup(&bp->dev->dev)) 5784 5784 phy_exit(bp->phy); ··· 5787 5787 return 0; 5788 5788 5789 5789 if (bp->wol & MACB_WOL_ENABLED) { 5790 - /* Check for IP address in WOL ARP mode */ 5791 - idev = __in_dev_get_rcu(bp->dev); 5792 - if (idev) 5793 - ifa = rcu_dereference(idev->ifa_list); 5794 - if ((bp->wolopts & WAKE_ARP) && !ifa) { 5795 - netdev_err(netdev, "IP address not assigned as required by WoL walk ARP\n"); 5796 - return -EOPNOTSUPP; 5790 + if (bp->wolopts & WAKE_ARP) { 5791 + /* Check for IP address in WOL ARP mode */ 5792 + rcu_read_lock(); 5793 + idev = __in_dev_get_rcu(bp->dev); 5794 + if (idev) 5795 + ifa = rcu_dereference(idev->ifa_list); 5796 + if (!ifa) { 5797 + rcu_read_unlock(); 5798 + netdev_err(netdev, "IP address not assigned as required by WoL walk ARP\n"); 5799 + return -EOPNOTSUPP; 5800 + } 5801 + ifa_local = be32_to_cpu(ifa->ifa_local); 5802 + rcu_read_unlock(); 5797 5803 } 5804 + 5798 5805 spin_lock_irqsave(&bp->lock, flags); 5799 5806 5800 5807 /* Disable Tx and Rx engines before disabling the queues, ··· 5840 5833 if (bp->wolopts & WAKE_ARP) { 5841 5834 tmp |= MACB_BIT(ARP); 5842 5835 /* write IP address into register */ 5843 - tmp |= MACB_BFEXT(IP, be32_to_cpu(ifa->ifa_local)); 5836 + tmp |= MACB_BFEXT(IP, ifa_local); 5844 5837 } 5838 + spin_unlock_irqrestore(&bp->lock, flags); 5845 5839 5846 5840 /* Change interrupt handler and 5847 5841 * Enable WoL IRQ on queue 0 ··· 5855 5847 dev_err(dev, 5856 5848 "Unable to request IRQ %d (error %d)\n", 5857 5849 bp->queues[0].irq, err); 5858 - spin_unlock_irqrestore(&bp->lock, flags); 5859 5850 return err; 5860 5851 } 5852 + spin_lock_irqsave(&bp->lock, flags); 5861 5853 queue_writel(bp->queues, IER, GEM_BIT(WOL)); 5862 5854 gem_writel(bp, WOL, tmp); 5855 + spin_unlock_irqrestore(&bp->lock, flags); 5863 5856 } else { 5864 5857 err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt, 5865 5858 IRQF_SHARED, netdev->name, bp->queues); ··· 5868 5859 dev_err(dev, 5869 5860 "Unable to request IRQ %d (error %d)\n", 5870 5861 bp->queues[0].irq, err); 5871 - spin_unlock_irqrestore(&bp->lock, flags); 5872 5862 return err; 5873 5863 } 5864 + spin_lock_irqsave(&bp->lock, flags); 5874 5865 queue_writel(bp->queues, IER, MACB_BIT(WOL)); 5875 5866 macb_writel(bp, WOL, tmp); 5867 + spin_unlock_irqrestore(&bp->lock, flags); 5876 5868 } 5877 - spin_unlock_irqrestore(&bp->lock, flags); 5878 5869 5879 5870 enable_irq_wake(bp->queues[0].irq); 5880 5871 } ··· 5941 5932 queue_readl(bp->queues, ISR); 5942 5933 if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 5943 5934 queue_writel(bp->queues, ISR, -1); 5935 + spin_unlock_irqrestore(&bp->lock, flags); 5936 + 5944 5937 /* Replace interrupt handler on queue 0 */ 5945 5938 devm_free_irq(dev, bp->queues[0].irq, bp->queues); 5946 5939 err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt, ··· 5951 5940 dev_err(dev, 5952 5941 "Unable to request IRQ %d (error %d)\n", 5953 5942 bp->queues[0].irq, err); 5954 - spin_unlock_irqrestore(&bp->lock, flags); 5955 5943 return err; 5956 5944 } 5957 - spin_unlock_irqrestore(&bp->lock, flags); 5958 5945 5959 5946 disable_irq_wake(bp->queues[0].irq); 5960 5947