net/netpoll: don't disable irqs in netpoll_send_skb()
RFC PATCH 1/1 net/netpoll: don't disable irqs in netpoll_send_skb()
Greetings,
I occasionally want to use netconsole, but it has RT issues. It seems to work fine with the not so pretty hacklet below.
net/netpoll: don't disable irqs in netpoll_send_skb()
RT takes sleeping locks, we can't disable irqs.
Signed-off-by Mike Galbraith <[email protected]>
--- include/linux/netpoll.h | 8 ++++++-- net/core/netpoll.c | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-)
include/linux/netpoll.h +6 -2
@@ -67,9 +67,13 @@ void netpoll_send_skb_on_dev(struct netpstatic inline void netpoll_send_skb (struct netpoll *np,struct sk_buff *skb) {unsigned long flags; -local_irq_save (flags); +local_irq_save_nort (flags); +if (IS_ENABLED (CONFIG_PREEMPT_RT_FULL )) +rcu_read_lock ();netpoll_send_skb_on_dev (np, skb, np->dev); -local_irq_restore (flags); +if (IS_ENABLED (CONFIG_PREEMPT_RT_FULL )) +rcu_read_unlock (); +local_irq_restore_nort (flags); }#ifdef CONFIG_NETPOLL
net/core/netpoll.c +2 -2
@@ -328,7 +328,7 @@ void netpoll_send_skb_on_dev(struct netp/* It is up to the caller to keep npinfo alive. */ struct netpoll_info *npinfo; -WARN_ON_ONCE (!irqs_disabled ()); +WARN_ON_ONCE_NONRT (!irqs_disabled ()); npinfo =rcu_dereference_bh (np->dev->npinfo);if (!npinfo || !netif_running (dev) || !netif_device_present (dev)) {
@@ -362,7 +362,7 @@ void netpoll_send_skb_on_dev(struct netpudelay (USEC_PER_POLL ); } -WARN_ONCE (!irqs_disabled (), +WARN_ONCE (!IS_ENABLED (CONFIG_PREEMPT_RT_FULL ) && !irqs_disabled (),"netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n" , dev->name, dev->netdev_ops->ndo_start_xmit);
Not that it matters, but there was a hunk missing.
RT takes sleeping locks, we can't disable irqs.
Signed-off-by Mike Galbraith <[email protected]>
--- include/linux/netpoll.h | 8 ++++++-- net/core/netpoll.c | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
include/linux/netpoll.h +6 -2
@@ -67,9 +67,13 @@ void netpoll_send_skb_on_dev(struct netpstatic inline void netpoll_send_skb (struct netpoll *np,struct sk_buff *skb) {unsigned long flags; -local_irq_save (flags); +local_irq_save_nort (flags); +if (IS_ENABLED (CONFIG_PREEMPT_RT_FULL )) +rcu_read_lock ();netpoll_send_skb_on_dev (np, skb, np->dev); -local_irq_restore (flags); +if (IS_ENABLED (CONFIG_PREEMPT_RT_FULL )) +rcu_read_unlock (); +local_irq_restore_nort (flags); }#ifdef CONFIG_NETPOLL
net/core/netpoll.c +3 -3
@@ -328,7 +328,7 @@ void netpoll_send_skb_on_dev(struct netp/* It is up to the caller to keep npinfo alive. */ struct netpoll_info *npinfo; -WARN_ON_ONCE (!irqs_disabled ()); +WARN_ON_ONCE_NONRT (!irqs_disabled ()); npinfo =rcu_dereference_bh (np->dev->npinfo);if (!npinfo || !netif_running (dev) || !netif_device_present (dev)) {
@@ -362,7 +362,7 @@ void netpoll_send_skb_on_dev(struct netpudelay (USEC_PER_POLL ); } -WARN_ONCE (!irqs_disabled (), +WARN_ONCE (!IS_ENABLED (CONFIG_PREEMPT_RT_FULL ) && !irqs_disabled (),"netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n" , dev->name, dev->netdev_ops->ndo_start_xmit);
@@ -385,7 +385,7 @@ void netpoll_send_udp(struct netpoll *npstatic atomic_t ip_ident;struct ipv6hdr *ip6h; -WARN_ON_ONCE (!irqs_disabled ()); +WARN_ON_ONCE_NONRT (!irqs_disabled ()); udp_len = len +sizeof (*udph);if (np->ipv6)