Skip to content

Commit

Permalink
bridge: add rcu_read_lock on transmit
Browse files Browse the repository at this point in the history
Long ago, when bridge was converted to RCU, rcu lock was equivalent
to having preempt disabled. RCU has changed a lot since then and
bridge code was still assuming the since transmit was called with
bottom half disabled, it was RCU safe.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Tested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
stephen hemminger authored and David S. Miller committed Jul 28, 2010
1 parent ff847ac commit eeaf61d
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 6 deletions.
4 changes: 3 additions & 1 deletion net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <asm/uaccess.h>
#include "br_private.h"

/* net device transmit always called with no BH (preempt_disabled) */
/* net device transmit always called with BH disabled */
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
Expand All @@ -46,6 +46,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
skb_reset_mac_header(skb);
skb_pull(skb, ETH_HLEN);

rcu_read_lock();
if (is_multicast_ether_addr(dest)) {
if (br_multicast_rcv(br, NULL, skb))
goto out;
Expand All @@ -61,6 +62,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
br_flood_deliver(br, skb);

out:
rcu_read_unlock();
return NETDEV_TX_OK;
}

Expand Down
2 changes: 1 addition & 1 deletion net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void br_fdb_delete_by_port(struct net_bridge *br,
spin_unlock_bh(&br->hash_lock);
}

/* No locking or refcounting, assumes caller has no preempt (rcu_read_lock) */
/* No locking or refcounting, assumes caller has rcu_read_lock */
struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
const unsigned char *addr)
{
Expand Down
6 changes: 3 additions & 3 deletions net/bridge/br_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static int br_pass_frame_up(struct sk_buff *skb)
netif_receive_skb);
}

/* note: already called with rcu_read_lock (preempt_disabled) */
/* note: already called with rcu_read_lock */
int br_handle_frame_finish(struct sk_buff *skb)
{
const unsigned char *dest = eth_hdr(skb)->h_dest;
Expand Down Expand Up @@ -108,7 +108,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
goto out;
}

/* note: already called with rcu_read_lock (preempt_disabled) */
/* note: already called with rcu_read_lock */
static int br_handle_local_finish(struct sk_buff *skb)
{
struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
Expand All @@ -133,7 +133,7 @@ static inline int is_link_local(const unsigned char *dest)
/*
* Called via br_handle_frame_hook.
* Return NULL if skb is handled
* note: already called with rcu_read_lock (preempt_disabled)
* note: already called with rcu_read_lock
*/
struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
{
Expand Down
2 changes: 1 addition & 1 deletion net/bridge/br_stp_bpdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void br_send_tcn_bpdu(struct net_bridge_port *p)
/*
* Called from llc.
*
* NO locks, but rcu_read_lock (preempt_disabled)
* NO locks, but rcu_read_lock
*/
void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
struct net_device *dev)
Expand Down

0 comments on commit eeaf61d

Please sign in to comment.