Fix r8169 link detection with Xenomai

```
[  741.073012] IRQ pipeline: some code running in oob context 'Xenomai'
[  741.073013]               called an in-band only routine
[  741.073013] CPU: 1 PID: 22419 Comm: my_task Tainted: G           O      5.10.179-lp154.3-0510xenomai3 #1
[  741.073014] Hardware name: ICP / iEi IMBA-9454ISA/IMBA-9454ISA(E168), BIOS 080014  02/20/2009
[  741.073015] IRQ stage: Xenomai
[  741.073015] Call Trace:
[  741.073015]  dump_stack+0x86/0xa6
[  741.073016]  check_inband_stage+0x8c/0xa0
[  741.073017]  inband_irq_save+0xe/0x30
[  741.073017]  try_to_grab_pending+0x1e/0x180
[  741.073018]  mod_delayed_work_on+0x42/0xa0
[  741.073018]  phy_trigger_machine+0x23/0x30
[  741.073019]  phy_mac_interrupt+0xe/0x20
[  741.073019]  ec_poll+0x105/0x110 [ec_r8169]
[  741.073020]  ec_device_poll+0x24/0x30 [ec_master]
[  741.073020]  ecrt_master_receive+0x21/0x160 [ec_master]
[  741.073021]  ec_ioctl_rtdm_rt+0x430/0x4c0 [ec_master]
[  741.073021]  ? rtdm_fd_get+0x11d/0x210
[  741.073022]  ec_rtdm_ioctl_rt_handler+0x26/0x40 [ec_master]
[  741.073022]  rtdm_fd_ioctl+0xdc/0x240
[  741.073023]  ? xnlock_dbg_release+0x21/0xf0
[  741.073023]  CoBaLt_ioctl+0xe/0x20
[  741.073024]  handle_head_syscall+0x10f/0x4d0
[  741.073025]  ? CoBaLt_fcntl+0x20/0x20
[  741.073025]  ? handle_pipelined_syscall+0x39/0x40
[  741.073026]  handle_oob_syscall+0x13/0x20
[  741.073026]  pipeline_syscall+0x8c/0x130
[  741.073027]  syscall_enter_from_user_mode+0x26/0x90
[  741.073027]  do_syscall_64+0x13/0x60
[  741.073028]  entry_SYSCALL_64_after_hwframe+0x61/0xc6
[  741.073029] RIP: 0033:0x7fac8da13c8f
[  741.073029] Code: Unable to access opcode bytes at RIP 0x7fac8da13c65.
[  741.073030] RSP: 002b:00007fac8e864c90 EFLAGS: 00000206 ORIG_RAX: 0000000010000050
[  741.073031] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fac8da13c8f
[  741.073032] RDX: 0000000000000000 RSI: 000000000000a426 RDI: 0000000000000003
[  741.073032] RBP: 000000000000a426 R08: 00007fac8e865700 R09: 0000000000000000
[  741.073033] R10: 0000000000000113 R11: 0000000000000206 R12: 0000000000000000
[  741.073033] R13: 0000000000000000 R14: 0000000000000000 R15: 00007fac8e864e80
```
This commit is contained in:
Bjarne von Horn 2024-02-01 16:03:33 +01:00
parent 0c1e2bc397
commit bdd7d1f8f7
4 changed files with 52 additions and 5 deletions

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -633,6 +634,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5079,6 +5081,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5369,6 +5372,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5387,8 +5398,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5588,6 +5598,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -653,6 +654,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5048,6 +5050,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5338,6 +5341,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5356,7 +5367,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5560,6 +5571,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -641,6 +642,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -5041,6 +5043,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5331,6 +5334,14 @@ done:
rtl_rar_set(tp, mac_addr);
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5349,7 +5360,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5552,6 +5563,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);

View File

@ -21,6 +21,7 @@
#include <linux/in.h>
#include <linux/io.h>
#include <linux/ip.h>
#include <linux/irq_work.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
@ -630,6 +631,7 @@ struct rtl8169_private {
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
struct irq_work ec_watchdog_kicker;
};
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@ -4919,6 +4921,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
if (tp->ecdev) {
ecdev_close(tp->ecdev);
irq_work_sync(&tp->ec_watchdog_kicker);
ecdev_withdraw(tp->ecdev);
} else {
unregister_netdev(tp->dev);
@ -5189,6 +5192,14 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
return false;
}
static void ec_kick_watchdog(struct irq_work *work)
{
struct rtl8169_private *tp =
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
phy_mac_interrupt(tp->phydev);
}
static void ec_poll(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@ -5207,7 +5218,7 @@ static void ec_poll(struct net_device *dev)
rtl_rx(dev, tp, 100);
if (status & LinkChg)
phy_mac_interrupt(tp->phydev);
irq_work_queue(&tp->ec_watchdog_kicker);
rtl_ack_events(tp, status);
}
@ -5416,6 +5427,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_put_sync(&pdev->dev);
if (tp->ecdev) {
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
rc = ecdev_open(tp->ecdev);
if (rc) {
ecdev_withdraw(tp->ecdev);