summaryrefslogtreecommitdiff
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2023-04-12 12:01:32 +0200
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2023-04-12 12:01:32 +0200
commit5603effb8295ada8419408d038a34ca89d658229 (patch)
treeb06d8e309631d507c7b030e943b8479e2d15250b /net/core/netpoll.c
parentb89ce1177d42d5c124e83f3858818cd4e6a2c46f (diff)
parent09a9639e56c01c7a00d6c0ca63f4c7c41abe075d (diff)
Merge remote-tracking branch 'drm/drm-fixes' into drm-misc-fixes
We were stuck on rc2, should at least attempt to track drm-fixes slightly. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a089b704b986..e6a739b1afa9 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -137,6 +137,20 @@ static void queue_process(struct work_struct *work)
}
}
+static int netif_local_xmit_active(struct net_device *dev)
+{
+ int i;
+
+ for (i = 0; i < dev->num_tx_queues; i++) {
+ struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+
+ if (READ_ONCE(txq->xmit_lock_owner) == smp_processor_id())
+ return 1;
+ }
+
+ return 0;
+}
+
static void poll_one_napi(struct napi_struct *napi)
{
int work;
@@ -183,7 +197,10 @@ void netpoll_poll_dev(struct net_device *dev)
if (!ni || down_trylock(&ni->dev_lock))
return;
- if (!netif_running(dev)) {
+ /* Some drivers will take the same locks in poll and xmit,
+ * we can't poll if local CPU is already in xmit.
+ */
+ if (!netif_running(dev) || netif_local_xmit_active(dev)) {
up(&ni->dev_lock);
return;
}