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.

r8169: Use a raw_spinlock_t for the register locks.

The driver's interrupt service routine is requested with the
IRQF_NO_THREAD if MSI is available. This means that the routine is
invoked in hardirq context even on PREEMPT_RT. The routine itself is
relatively short and schedules a worker, performs register access and
schedules NAPI. On PREEMPT_RT, scheduling NAPI from hardirq results in
waking ksoftirqd for further processing so using NAPI threads with this
driver is highly recommended since it NULL routes the threaded-IRQ
efforts.

Adding rtl_hw_aspm_clkreq_enable() to the ISR is problematic on
PREEMPT_RT because the function uses spinlock_t locks which become
sleeping locks on PREEMPT_RT. The locks are only used to protect
register access and don't nest into other functions or locks. They are
also not used for unbounded period of time. Therefore it looks okay to
convert them to raw_spinlock_t.

Convert the three locks which are used from the interrupt service
routine to raw_spinlock_t.

Fixes: e1ed3e4d9111 ("r8169: disable ASPM during NAPI poll")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://lore.kernel.org/r/20230522134121.uxjax0F5@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Sebastian Andrzej Siewior and committed by
Jakub Kicinski
d6c36cbc 368d3cb4

+22 -22
+22 -22
drivers/net/ethernet/realtek/r8169_main.c
··· 616 616 struct work_struct work; 617 617 } wk; 618 618 619 - spinlock_t config25_lock; 620 - spinlock_t mac_ocp_lock; 619 + raw_spinlock_t config25_lock; 620 + raw_spinlock_t mac_ocp_lock; 621 621 622 - spinlock_t cfg9346_usage_lock; 622 + raw_spinlock_t cfg9346_usage_lock; 623 623 int cfg9346_usage_count; 624 624 625 625 unsigned supports_gmii:1; ··· 671 671 { 672 672 unsigned long flags; 673 673 674 - spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); 674 + raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); 675 675 if (!--tp->cfg9346_usage_count) 676 676 RTL_W8(tp, Cfg9346, Cfg9346_Lock); 677 - spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); 677 + raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); 678 678 } 679 679 680 680 static void rtl_unlock_config_regs(struct rtl8169_private *tp) 681 681 { 682 682 unsigned long flags; 683 683 684 - spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); 684 + raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); 685 685 if (!tp->cfg9346_usage_count++) 686 686 RTL_W8(tp, Cfg9346, Cfg9346_Unlock); 687 - spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); 687 + raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); 688 688 } 689 689 690 690 static void rtl_pci_commit(struct rtl8169_private *tp) ··· 698 698 unsigned long flags; 699 699 u8 val; 700 700 701 - spin_lock_irqsave(&tp->config25_lock, flags); 701 + raw_spin_lock_irqsave(&tp->config25_lock, flags); 702 702 val = RTL_R8(tp, Config2); 703 703 RTL_W8(tp, Config2, (val & ~clear) | set); 704 - spin_unlock_irqrestore(&tp->config25_lock, flags); 704 + raw_spin_unlock_irqrestore(&tp->config25_lock, flags); 705 705 } 706 706 707 707 static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set) ··· 709 709 unsigned long flags; 710 710 u8 val; 711 711 712 - spin_lock_irqsave(&tp->config25_lock, flags); 712 + raw_spin_lock_irqsave(&tp->config25_lock, flags); 713 713 val = RTL_R8(tp, Config5); 714 714 RTL_W8(tp, Config5, (val & ~clear) | set); 715 - spin_unlock_irqrestore(&tp->config25_lock, flags); 715 + raw_spin_unlock_irqrestore(&tp->config25_lock, flags); 716 716 } 717 717 718 718 static bool rtl_is_8125(struct rtl8169_private *tp) ··· 899 899 { 900 900 unsigned long flags; 901 901 902 - spin_lock_irqsave(&tp->mac_ocp_lock, flags); 902 + raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags); 903 903 __r8168_mac_ocp_write(tp, reg, data); 904 - spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 904 + raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 905 905 } 906 906 907 907 static u16 __r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) ··· 919 919 unsigned long flags; 920 920 u16 val; 921 921 922 - spin_lock_irqsave(&tp->mac_ocp_lock, flags); 922 + raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags); 923 923 val = __r8168_mac_ocp_read(tp, reg); 924 - spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 924 + raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 925 925 926 926 return val; 927 927 } ··· 932 932 unsigned long flags; 933 933 u16 data; 934 934 935 - spin_lock_irqsave(&tp->mac_ocp_lock, flags); 935 + raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags); 936 936 data = __r8168_mac_ocp_read(tp, reg); 937 937 __r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 938 - spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 938 + raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags); 939 939 } 940 940 941 941 /* Work around a hw issue with RTL8168g PHY, the quirk disables ··· 1420 1420 r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); 1421 1421 } 1422 1422 1423 - spin_lock_irqsave(&tp->config25_lock, flags); 1423 + raw_spin_lock_irqsave(&tp->config25_lock, flags); 1424 1424 for (i = 0; i < tmp; i++) { 1425 1425 options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; 1426 1426 if (wolopts & cfg[i].opt) 1427 1427 options |= cfg[i].mask; 1428 1428 RTL_W8(tp, cfg[i].reg, options); 1429 1429 } 1430 - spin_unlock_irqrestore(&tp->config25_lock, flags); 1430 + raw_spin_unlock_irqrestore(&tp->config25_lock, flags); 1431 1431 1432 1432 switch (tp->mac_version) { 1433 1433 case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: ··· 5179 5179 tp->eee_adv = -1; 5180 5180 tp->ocp_base = OCP_STD_PHY_BASE; 5181 5181 5182 - spin_lock_init(&tp->cfg9346_usage_lock); 5183 - spin_lock_init(&tp->config25_lock); 5184 - spin_lock_init(&tp->mac_ocp_lock); 5182 + raw_spin_lock_init(&tp->cfg9346_usage_lock); 5183 + raw_spin_lock_init(&tp->config25_lock); 5184 + raw_spin_lock_init(&tp->mac_ocp_lock); 5185 5185 5186 5186 dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev, 5187 5187 struct pcpu_sw_netstats);