mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
[IPV4]: Replace __in_dev_get with __in_dev_get_rcu/rtnl
The following patch renames __in_dev_get() to __in_dev_get_rtnl() and introduces __in_dev_get_rcu() to cover the second case. 1) RCU with refcnt should use in_dev_get(). 2) RCU without refcnt should use __in_dev_get_rcu(). 3) All others must hold RTNL and use __in_dev_get_rtnl(). There is one exception in net/ipv4/route.c which is in fact a pre-existing race condition. I've marked it as such so that we remember to fix it. This patch is based on suggestions and prior work by Suzanne Wood and Paul McKenney. Signed-off-by: Herbert Xu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
a5e7c210fe
commit
e5ed639913
24 changed files with 73 additions and 55 deletions
|
|
@ -2776,7 +2776,7 @@ static u32 bond_glean_dev_ip(struct net_device *dev)
|
|||
return 0;
|
||||
|
||||
rcu_read_lock();
|
||||
idev = __in_dev_get(dev);
|
||||
idev = __in_dev_get_rcu(dev);
|
||||
if (!idev)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include <linux/ioport.h> /* request_region(), release_region() */
|
||||
#include <linux/wanrouter.h> /* WAN router definitions */
|
||||
#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
#include <linux/in.h>
|
||||
#include <asm/io.h> /* phys_to_virt() */
|
||||
|
|
@ -1268,37 +1269,41 @@ unsigned long get_ip_address(struct net_device *dev, int option)
|
|||
|
||||
struct in_ifaddr *ifaddr;
|
||||
struct in_device *in_dev;
|
||||
unsigned long addr = 0;
|
||||
|
||||
if ((in_dev = __in_dev_get(dev)) == NULL){
|
||||
return 0;
|
||||
rcu_read_lock();
|
||||
if ((in_dev = __in_dev_get_rcu(dev)) == NULL){
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ifaddr = in_dev->ifa_list)== NULL ){
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (option){
|
||||
|
||||
case WAN_LOCAL_IP:
|
||||
return ifaddr->ifa_local;
|
||||
addr = ifaddr->ifa_local;
|
||||
break;
|
||||
|
||||
case WAN_POINTOPOINT_IP:
|
||||
return ifaddr->ifa_address;
|
||||
addr = ifaddr->ifa_address;
|
||||
break;
|
||||
|
||||
case WAN_NETMASK_IP:
|
||||
return ifaddr->ifa_mask;
|
||||
addr = ifaddr->ifa_mask;
|
||||
break;
|
||||
|
||||
case WAN_BROADCAST_IP:
|
||||
return ifaddr->ifa_broadcast;
|
||||
addr = ifaddr->ifa_broadcast;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return addr;
|
||||
}
|
||||
|
||||
void add_gateway(sdla_t *card, struct net_device *dev)
|
||||
|
|
|
|||
|
|
@ -769,7 +769,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
|
|||
u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
|
||||
#ifdef CONFIG_INET
|
||||
rcu_read_lock();
|
||||
if ((in_dev = __in_dev_get(dev)) != NULL)
|
||||
if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
|
||||
{
|
||||
for (ifa=in_dev->ifa_list; ifa != NULL;
|
||||
ifa=ifa->ifa_next) {
|
||||
|
|
|
|||
|
|
@ -1352,7 +1352,7 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
|
|||
struct in_device *in_dev;
|
||||
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get(strip_info->dev);
|
||||
in_dev = __in_dev_get_rcu(strip_info->dev);
|
||||
if (in_dev == NULL) {
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
|
|
@ -1508,7 +1508,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
|
|||
|
||||
brd = addr = 0;
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get(strip_info->dev);
|
||||
in_dev = __in_dev_get_rcu(strip_info->dev);
|
||||
if (in_dev) {
|
||||
if (in_dev->ifa_list) {
|
||||
brd = in_dev->ifa_list->ifa_broadcast;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/hardware.h>
|
||||
|
|
@ -358,9 +359,10 @@ static __inline__ int led_get_net_activity(void)
|
|||
/* we are running as tasklet, so locking dev_base
|
||||
* for reading should be OK */
|
||||
read_lock(&dev_base_lock);
|
||||
rcu_read_lock();
|
||||
for (dev = dev_base; dev; dev = dev->next) {
|
||||
struct net_device_stats *stats;
|
||||
struct in_device *in_dev = __in_dev_get(dev);
|
||||
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
||||
if (!in_dev || !in_dev->ifa_list)
|
||||
continue;
|
||||
if (LOOPBACK(in_dev->ifa_list->ifa_local))
|
||||
|
|
@ -371,6 +373,7 @@ static __inline__ int led_get_net_activity(void)
|
|||
rx_total += stats->rx_packets;
|
||||
tx_total += stats->tx_packets;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
read_unlock(&dev_base_lock);
|
||||
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -5200,7 +5200,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
|
|||
if (!card->vlangrp)
|
||||
return;
|
||||
rcu_read_lock();
|
||||
in_dev = __in_dev_get(card->vlangrp->vlan_devices[vid]);
|
||||
in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
|
||||
if (!in_dev)
|
||||
goto out;
|
||||
for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
|
||||
|
|
@ -7725,7 +7725,7 @@ qeth_arp_constructor(struct neighbour *neigh)
|
|||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
in_dev = rcu_dereference(__in_dev_get(dev));
|
||||
in_dev = __in_dev_get_rcu(dev);
|
||||
if (in_dev == NULL) {
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in a new issue