From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
Qianfeng Zhang <frzhang@redhat.com>,
"David S. Miller" <davem@davemloft.net>,
netdev@vger.kernel.org, WANG Cong <amwang@redhat.com>,
Stephen Hemminger <shemminger@vyatta.com>,
Matt Mackall <mpm@selenic.com>
Subject: Re: [PATCH 3/8] netpoll: Fix RCU usage
Date: Fri, 11 Jun 2010 16:10:21 -0700 [thread overview]
Message-ID: <20100611231021.GK2394@linux.vnet.ibm.com> (raw)
In-Reply-To: <E1OMtjg-0006Ob-Sb@gondolin.me.apana.org.au>
On Fri, Jun 11, 2010 at 12:12:44PM +1000, Herbert Xu wrote:
> netpoll: Fix RCU usage
>
> The use of RCU in netpoll is incorrect in a number of places:
>
> 1) The initial setting is lacking a write barrier.
> 2) The synchronize_rcu is in the wrong place.
> 3) Read barriers are missing.
> 4) Some places are even missing rcu_read_lock.
> 5) npinfo is zeroed after freeing.
>
> This patch fixes those issues. As most users are in BH context,
> this also converts the RCU usage to the BH variant.
Looks good for me from an RCU viewpoint, but as usual I confess much
ignorance of the surrounding code.
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> ---
>
> include/linux/netpoll.h | 13 ++++++++-----
> net/core/netpoll.c | 20 ++++++++++++--------
> 2 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
> index e9e2312..95c9f7e 100644
> --- a/include/linux/netpoll.h
> +++ b/include/linux/netpoll.h
> @@ -57,12 +57,15 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
> #ifdef CONFIG_NETPOLL
> static inline bool netpoll_rx(struct sk_buff *skb)
> {
> - struct netpoll_info *npinfo = skb->dev->npinfo;
> + struct netpoll_info *npinfo;
> unsigned long flags;
> bool ret = false;
>
> + rcu_read_lock_bh();
> + npinfo = rcu_dereference(skb->dev->npinfo);
> +
> if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
> - return false;
> + goto out;
>
> spin_lock_irqsave(&npinfo->rx_lock, flags);
> /* check rx_flags again with the lock held */
> @@ -70,12 +73,14 @@ static inline bool netpoll_rx(struct sk_buff *skb)
> ret = true;
> spin_unlock_irqrestore(&npinfo->rx_lock, flags);
>
> +out:
> + rcu_read_unlock_bh();
> return ret;
> }
>
> static inline int netpoll_rx_on(struct sk_buff *skb)
> {
> - struct netpoll_info *npinfo = skb->dev->npinfo;
> + struct netpoll_info *npinfo = rcu_dereference(skb->dev->npinfo);
>
> return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
> }
> @@ -91,7 +96,6 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi)
> {
> struct net_device *dev = napi->dev;
>
> - rcu_read_lock(); /* deal with race on ->npinfo */
> if (dev && dev->npinfo) {
> spin_lock(&napi->poll_lock);
> napi->poll_owner = smp_processor_id();
> @@ -108,7 +112,6 @@ static inline void netpoll_poll_unlock(void *have)
> napi->poll_owner = -1;
> spin_unlock(&napi->poll_lock);
> }
> - rcu_read_unlock();
> }
>
> #else
> diff --git a/net/core/netpoll.c b/net/core/netpoll.c
> index 748c930..4b7623d 100644
> --- a/net/core/netpoll.c
> +++ b/net/core/netpoll.c
> @@ -292,6 +292,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
> unsigned long tries;
> struct net_device *dev = np->dev;
> const struct net_device_ops *ops = dev->netdev_ops;
> + /* It is up to the caller to keep npinfo alive. */
> struct netpoll_info *npinfo = np->dev->npinfo;
>
> if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
> @@ -841,10 +842,7 @@ int netpoll_setup(struct netpoll *np)
> refill_skbs();
>
> /* last thing to do is link it to the net device structure */
> - ndev->npinfo = npinfo;
> -
> - /* avoid racing with NAPI reading npinfo */
> - synchronize_rcu();
> + rcu_assign_pointer(ndev->npinfo, npinfo);
>
> return 0;
>
> @@ -888,6 +886,16 @@ void netpoll_cleanup(struct netpoll *np)
>
> if (atomic_dec_and_test(&npinfo->refcnt)) {
> const struct net_device_ops *ops;
> +
> + ops = np->dev->netdev_ops;
> + if (ops->ndo_netpoll_cleanup)
> + ops->ndo_netpoll_cleanup(np->dev);
> +
> + rcu_assign_pointer(np->dev->npinfo, NULL);
> +
> + /* avoid racing with NAPI reading npinfo */
> + synchronize_rcu_bh();
> +
> skb_queue_purge(&npinfo->arp_tx);
> skb_queue_purge(&npinfo->txq);
> cancel_rearming_delayed_work(&npinfo->tx_work);
> @@ -895,10 +903,6 @@ void netpoll_cleanup(struct netpoll *np)
> /* clean after last, unfinished work */
> __skb_queue_purge(&npinfo->txq);
> kfree(npinfo);
> - ops = np->dev->netdev_ops;
> - if (ops->ndo_netpoll_cleanup)
> - ops->ndo_netpoll_cleanup(np->dev);
> - np->dev->npinfo = NULL;
> }
> }
>
next prev parent reply other threads:[~2010-06-11 23:10 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-10 12:40 [0/8] netpoll/bridge fixes Herbert Xu
2010-06-10 12:42 ` [PATCH 1/7] netpoll: Set npinfo to NULL even with ndo_netpoll_cleanup Herbert Xu
2010-06-10 12:42 ` [PATCH 2/7] bridge: Remove redundant npinfo NULL setting Herbert Xu
2010-06-10 12:42 ` [PATCH 3/7] netpoll: Fix RCU usage Herbert Xu
2010-06-10 12:42 ` [PATCH 4/7] netpoll: Add locking for netpoll_setup/cleanup Herbert Xu
2010-06-10 12:42 ` [PATCH 5/7] netpoll: Add ndo_netpoll_setup Herbert Xu
2010-06-10 12:42 ` [PATCH 6/7] netpoll: Allow netpoll_setup/cleanup recursion Herbert Xu
2010-06-10 12:42 ` [PATCH 7/7] bridge: Fix netpoll support Herbert Xu
2010-06-10 14:49 ` [0/8] netpoll/bridge fixes Stephen Hemminger
2010-06-10 21:56 ` Herbert Xu
2010-06-10 21:59 ` Stephen Hemminger
2010-06-10 22:48 ` Herbert Xu
2010-06-11 2:11 ` Herbert Xu
2010-06-11 2:12 ` [PATCH 1/8] netpoll: Set npinfo to NULL even with ndo_netpoll_cleanup Herbert Xu
2010-06-11 2:12 ` [PATCH 2/8] bridge: Remove redundant npinfo NULL setting Herbert Xu
2010-06-11 2:12 ` [PATCH 3/8] netpoll: Fix RCU usage Herbert Xu
2010-06-11 23:10 ` Paul E. McKenney [this message]
2010-06-11 2:12 ` [PATCH 4/8] netpoll: Add locking for netpoll_setup/cleanup Herbert Xu
2010-06-11 2:12 ` [PATCH 5/8] netpoll: Add ndo_netpoll_setup Herbert Xu
2010-06-11 2:12 ` [PATCH 6/8] netpoll: Allow netpoll_setup/cleanup recursion Herbert Xu
2010-06-25 1:21 ` Andrew Morton
2010-06-25 3:01 ` Herbert Xu
2010-06-25 3:30 ` David Miller
2010-06-25 3:50 ` Andrew Morton
2010-06-25 4:27 ` David Miller
2010-06-25 4:42 ` Andrew Morton
2010-06-25 4:52 ` David Miller
2010-06-25 8:08 ` Peter Zijlstra
2010-06-25 8:42 ` Andrew Morton
2010-06-25 9:45 ` Peter Zijlstra
2010-06-25 8:46 ` Ingo Molnar
2010-06-25 10:08 ` Nick Piggin
2010-06-11 2:12 ` [PATCH 7/8] netpoll: Add netpoll_tx_running Herbert Xu
2010-06-11 2:12 ` [PATCH 8/8] bridge: Fix netpoll support Herbert Xu
2010-06-11 3:08 ` fired a bug report on bugzilla.redhat.com Qianfeng Zhang
2010-06-15 10:28 ` [PATCH 8/8] bridge: Fix netpoll support Cong Wang
2010-06-17 10:38 ` Herbert Xu
2010-06-17 10:57 ` Cong Wang
2010-06-17 10:55 ` Herbert Xu
2010-06-18 3:06 ` Cong Wang
2010-06-11 20:03 ` [0/8] netpoll/bridge fixes Matt Mackall
2010-06-15 10:17 ` Cong Wang
2010-06-15 18:39 ` David Miller
2010-06-16 2:58 ` Eric Dumazet
2010-06-16 3:03 ` Eric Dumazet
2010-06-16 3:33 ` Herbert Xu
2010-06-16 4:47 ` David Miller
2010-06-16 23:02 ` Paul E. McKenney
2010-06-17 10:18 ` Michael S. Tsirkin
2010-06-17 21:26 ` Paul E. McKenney
2010-06-16 6:16 ` Eric Dumazet
2010-06-16 5:08 ` Paul E. McKenney
2010-06-16 6:21 ` Eric Dumazet
2010-06-16 16:01 ` Paul E. McKenney
2010-07-19 10:19 ` Michael S. Tsirkin
2010-07-19 10:53 ` Herbert Xu
2010-07-19 11:54 ` Herbert Xu
2010-07-19 16:05 ` David Miller
2010-07-19 16:52 ` Eric Dumazet
2010-07-19 20:35 ` David Miller
2010-07-20 5:26 ` Herbert Xu
2010-07-20 6:28 ` David Miller
2010-06-29 12:53 ` Yanko Kaneti
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=20100611231021.GK2394@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=amwang@redhat.com \
--cc=davem@davemloft.net \
--cc=frzhang@redhat.com \
--cc=herbert@gondor.apana.org.au \
--cc=mpm@selenic.com \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.