From: Matt Mackall <mpm@selenic.com>
To: Andrew Morton <akpm@osdl.com>, "David S. Miller" <davem@davemloft.net>
Cc: ak@suse.de, Jeff Moyer <jmoyer@redhat.com>,
netdev@oss.sgi.com, linux-kernel@vger.kernel.org, mingo@elte.hu,
john.ronciak@intel.com, rostedt@goodmis.org
Subject: [PATCH 7/8] netpoll: fix initialization/NAPI race
Date: Thu, 11 Aug 2005 21:19:12 -0500 [thread overview]
Message-ID: <8.502409567@selenic.com> (raw)
In-Reply-To: <7.502409567@selenic.com>
This fixes a race during initialization with the NAPI softirq
processing by using an RCU approach.
This race was discovered when refill_skbs() was added to
the setup code.
Signed-off-by: Matt Mackall <mpm@selenic.com>
Index: l/net/core/netpoll.c
===================================================================
--- l.orig/net/core/netpoll.c 2005-08-09 00:56:23.000000000 -0500
+++ l/net/core/netpoll.c 2005-08-11 01:50:24.000000000 -0500
@@ -731,6 +731,9 @@ int netpoll_setup(struct netpoll *np)
/* last thing to do is link it to the net device structure */
ndev->npinfo = npinfo;
+ /* avoid racing with NAPI reading npinfo */
+ synchronize_rcu();
+
return 0;
release:
Index: l/include/linux/netpoll.h
===================================================================
--- l.orig/include/linux/netpoll.h 2005-08-09 00:56:23.000000000 -0500
+++ l/include/linux/netpoll.h 2005-08-11 01:33:42.000000000 -0500
@@ -9,6 +9,7 @@
#include <linux/netdevice.h>
#include <linux/interrupt.h>
+#include <linux/rcupdate.h>
#include <linux/list.h>
struct netpoll;
@@ -61,25 +62,31 @@ static inline int netpoll_rx(struct sk_b
return ret;
}
-static inline void netpoll_poll_lock(struct net_device *dev)
+static inline void *netpoll_poll_lock(struct net_device *dev)
{
+ rcu_read_lock(); /* deal with race on ->npinfo */
if (dev->npinfo) {
spin_lock(&dev->npinfo->poll_lock);
dev->npinfo->poll_owner = smp_processor_id();
+ return dev->npinfo;
}
+ return NULL;
}
-static inline void netpoll_poll_unlock(struct net_device *dev)
+static inline void netpoll_poll_unlock(void *have)
{
- if (dev->npinfo) {
- dev->npinfo->poll_owner = -1;
- spin_unlock(&dev->npinfo->poll_lock);
+ struct netpoll_info *npi = have;
+
+ if (npi) {
+ npi->poll_owner = -1;
+ spin_unlock(&npi->poll_lock);
}
+ rcu_read_unlock();
}
#else
#define netpoll_rx(a) 0
-#define netpoll_poll_lock(a)
+#define netpoll_poll_lock(a) 0
#define netpoll_poll_unlock(a)
#endif
Index: l/net/core/dev.c
===================================================================
--- l.orig/net/core/dev.c 2005-08-09 00:56:23.000000000 -0500
+++ l/net/core/dev.c 2005-08-11 01:34:08.000000000 -0500
@@ -1696,7 +1696,8 @@ static void net_rx_action(struct softirq
struct softnet_data *queue = &__get_cpu_var(softnet_data);
unsigned long start_time = jiffies;
int budget = netdev_budget;
-
+ void *have;
+
local_irq_disable();
while (!list_empty(&queue->poll_list)) {
@@ -1709,10 +1710,10 @@ static void net_rx_action(struct softirq
dev = list_entry(queue->poll_list.next,
struct net_device, poll_list);
- netpoll_poll_lock(dev);
+ have = netpoll_poll_lock(dev);
if (dev->quota <= 0 || dev->poll(dev, &budget)) {
- netpoll_poll_unlock(dev);
+ netpoll_poll_unlock(have);
local_irq_disable();
list_del(&dev->poll_list);
list_add_tail(&dev->poll_list, &queue->poll_list);
@@ -1721,7 +1722,7 @@ static void net_rx_action(struct softirq
else
dev->quota = dev->weight;
} else {
- netpoll_poll_unlock(dev);
+ netpoll_poll_unlock(have);
dev_put(dev);
local_irq_disable();
}
next prev parent reply other threads:[~2005-08-12 2:19 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-12 2:18 [PATCH 0/8] netpoll: various bugfixes Matt Mackall
2005-08-12 2:19 ` [PATCH 1/8] netpoll: rx_flags bugfix Matt Mackall
2005-08-12 2:19 ` [PATCH 2/8] netpoll: deadlock bugfix Matt Mackall
2005-08-12 2:19 ` [PATCH 3/8] netpoll: e1000 netpoll tweak Matt Mackall
2005-08-12 2:19 ` [PATCH 4/8] netpoll: netpoll_send_skb simplify Matt Mackall
2005-08-12 2:19 ` [PATCH 5/8] netpoll: add retry timeout Matt Mackall
2005-08-12 2:19 ` [PATCH 6/8] netpoll: pre-fill skb pool Matt Mackall
2005-08-12 2:19 ` Matt Mackall [this message]
2005-08-12 2:19 ` [PATCH 8/8] netpoll: remove unused variable Matt Mackall
2005-08-12 19:02 ` [PATCH 3/8] netpoll: e1000 netpoll tweak John Ronciak
[not found] ` <56a8daef0508121202172bcd17@mail.gmail.com>
2005-08-12 19:10 ` David S. Miller
2005-08-12 19:17 ` Matt Mackall
2005-08-12 2:41 ` [PATCH 0/8] netpoll: various bugfixes David S. Miller
2005-08-12 17:21 ` Olaf Hering
[not found] ` <20050812172151.GA11104@suse.de>
2005-08-12 19:21 ` Matt Mackall
2005-08-12 19:31 ` Olaf Hering
[not found] ` <20050812193109.GA15434@suse.de>
2005-08-14 21:00 ` Matt Mackall
2005-08-15 6:16 ` Olaf Hering
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8.502409567@selenic.com \
--to=mpm@selenic.com \
--cc=ak@suse.de \
--cc=akpm@osdl.com \
--cc=davem@davemloft.net \
--cc=jmoyer@redhat.com \
--cc=john.ronciak@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=netdev@oss.sgi.com \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).