mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
[NET]: Convert RTNL to mutex.
This patch turns the RTNL from a semaphore to a new 2.6.16 mutex and gets rid of some of the leftover legacy. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
253aa11578
commit
6756ae4b4e
@ -1605,7 +1605,7 @@ static void rtl8139_thread (void *_data)
|
|||||||
if (tp->watchdog_fired) {
|
if (tp->watchdog_fired) {
|
||||||
tp->watchdog_fired = 0;
|
tp->watchdog_fired = 0;
|
||||||
rtl8139_tx_timeout_task(_data);
|
rtl8139_tx_timeout_task(_data);
|
||||||
} else if (rtnl_shlock_nowait() == 0) {
|
} else if (rtnl_trylock()) {
|
||||||
rtl8139_thread_iter (dev, tp, tp->mmio_addr);
|
rtl8139_thread_iter (dev, tp, tp->mmio_addr);
|
||||||
rtnl_unlock ();
|
rtnl_unlock ();
|
||||||
} else {
|
} else {
|
||||||
|
@ -907,6 +907,7 @@ struct tcamsg
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
|
extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
|
||||||
static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
|
static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
|
||||||
@ -1038,24 +1039,17 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
|
|||||||
|
|
||||||
extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
|
extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
|
||||||
|
|
||||||
extern struct semaphore rtnl_sem;
|
/* RTNL is used as a global lock for all changes to network configuration */
|
||||||
|
|
||||||
#define rtnl_shlock() down(&rtnl_sem)
|
|
||||||
#define rtnl_shlock_nowait() down_trylock(&rtnl_sem)
|
|
||||||
|
|
||||||
#define rtnl_shunlock() do { up(&rtnl_sem); \
|
|
||||||
if (rtnl && rtnl->sk_receive_queue.qlen) \
|
|
||||||
rtnl->sk_data_ready(rtnl, 0); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
extern void rtnl_lock(void);
|
extern void rtnl_lock(void);
|
||||||
extern int rtnl_lock_interruptible(void);
|
|
||||||
extern void rtnl_unlock(void);
|
extern void rtnl_unlock(void);
|
||||||
|
extern int rtnl_trylock(void);
|
||||||
|
|
||||||
extern void rtnetlink_init(void);
|
extern void rtnetlink_init(void);
|
||||||
|
extern void __rtnl_unlock(void);
|
||||||
|
|
||||||
#define ASSERT_RTNL() do { \
|
#define ASSERT_RTNL() do { \
|
||||||
if (unlikely(down_trylock(&rtnl_sem) == 0)) { \
|
if (unlikely(rtnl_trylock())) { \
|
||||||
up(&rtnl_sem); \
|
rtnl_unlock(); \
|
||||||
printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
|
printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
dump_stack(); \
|
dump_stack(); \
|
||||||
|
@ -2466,9 +2466,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (cmd == SIOCGIFCONF) {
|
if (cmd == SIOCGIFCONF) {
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
ret = dev_ifconf((char __user *) arg);
|
ret = dev_ifconf((char __user *) arg);
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (cmd == SIOCGIFNAME)
|
if (cmd == SIOCGIFNAME)
|
||||||
@ -2877,7 +2877,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
|
|||||||
rebroadcast_time = warning_time = jiffies;
|
rebroadcast_time = warning_time = jiffies;
|
||||||
while (atomic_read(&dev->refcnt) != 0) {
|
while (atomic_read(&dev->refcnt) != 0) {
|
||||||
if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
|
if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
/* Rebroadcast unregister notification */
|
/* Rebroadcast unregister notification */
|
||||||
notifier_call_chain(&netdev_chain,
|
notifier_call_chain(&netdev_chain,
|
||||||
@ -2894,7 +2894,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
|
|||||||
linkwatch_run_queue();
|
linkwatch_run_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
rtnl_shunlock();
|
__rtnl_unlock();
|
||||||
|
|
||||||
rebroadcast_time = jiffies;
|
rebroadcast_time = jiffies;
|
||||||
}
|
}
|
||||||
|
@ -139,9 +139,9 @@ static void linkwatch_event(void *dummy)
|
|||||||
linkwatch_nextevent = jiffies + HZ;
|
linkwatch_nextevent = jiffies + HZ;
|
||||||
clear_bit(LW_RUNNING, &linkwatch_flags);
|
clear_bit(LW_RUNNING, &linkwatch_flags);
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
linkwatch_run_queue();
|
linkwatch_run_queue();
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -669,14 +669,14 @@ int netpoll_setup(struct netpoll *np)
|
|||||||
printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
|
printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
|
||||||
np->name, np->dev_name);
|
np->name, np->dev_name);
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
if (dev_change_flags(ndev, ndev->flags | IFF_UP) < 0) {
|
if (dev_change_flags(ndev, ndev->flags | IFF_UP) < 0) {
|
||||||
printk(KERN_ERR "%s: failed to open %s\n",
|
printk(KERN_ERR "%s: failed to open %s\n",
|
||||||
np->name, np->dev_name);
|
np->name, np->dev_name);
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
atleast = jiffies + HZ/10;
|
atleast = jiffies + HZ/10;
|
||||||
atmost = jiffies + 4*HZ;
|
atmost = jiffies + 4*HZ;
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
@ -51,25 +52,31 @@
|
|||||||
#include <net/pkt_sched.h>
|
#include <net/pkt_sched.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
|
|
||||||
DECLARE_MUTEX(rtnl_sem);
|
static DEFINE_MUTEX(rtnl_mutex);
|
||||||
|
|
||||||
void rtnl_lock(void)
|
void rtnl_lock(void)
|
||||||
{
|
{
|
||||||
rtnl_shlock();
|
mutex_lock(&rtnl_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtnl_lock_interruptible(void)
|
void __rtnl_unlock(void)
|
||||||
{
|
{
|
||||||
return down_interruptible(&rtnl_sem);
|
mutex_unlock(&rtnl_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtnl_unlock(void)
|
void rtnl_unlock(void)
|
||||||
{
|
{
|
||||||
rtnl_shunlock();
|
mutex_unlock(&rtnl_mutex);
|
||||||
|
if (rtnl && rtnl->sk_receive_queue.qlen)
|
||||||
|
rtnl->sk_data_ready(rtnl, 0);
|
||||||
netdev_run_todo();
|
netdev_run_todo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rtnl_trylock(void)
|
||||||
|
{
|
||||||
|
return mutex_trylock(&rtnl_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
|
int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
|
||||||
{
|
{
|
||||||
memset(tb, 0, sizeof(struct rtattr*)*maxattr);
|
memset(tb, 0, sizeof(struct rtattr*)*maxattr);
|
||||||
@ -625,9 +632,9 @@ static void rtnetlink_rcv(struct sock *sk, int len)
|
|||||||
unsigned int qlen = 0;
|
unsigned int qlen = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rtnl_lock();
|
mutex_lock(&rtnl_mutex);
|
||||||
netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg);
|
netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg);
|
||||||
up(&rtnl_sem);
|
mutex_unlock(&rtnl_mutex);
|
||||||
|
|
||||||
netdev_run_todo();
|
netdev_run_todo();
|
||||||
} while (qlen);
|
} while (qlen);
|
||||||
@ -704,6 +711,5 @@ EXPORT_SYMBOL(rtnetlink_links);
|
|||||||
EXPORT_SYMBOL(rtnetlink_put_metrics);
|
EXPORT_SYMBOL(rtnetlink_put_metrics);
|
||||||
EXPORT_SYMBOL(rtnl);
|
EXPORT_SYMBOL(rtnl);
|
||||||
EXPORT_SYMBOL(rtnl_lock);
|
EXPORT_SYMBOL(rtnl_lock);
|
||||||
EXPORT_SYMBOL(rtnl_lock_interruptible);
|
EXPORT_SYMBOL(rtnl_trylock);
|
||||||
EXPORT_SYMBOL(rtnl_sem);
|
|
||||||
EXPORT_SYMBOL(rtnl_unlock);
|
EXPORT_SYMBOL(rtnl_unlock);
|
||||||
|
@ -1730,7 +1730,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
|
|||||||
if (!MULTICAST(addr))
|
if (!MULTICAST(addr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
in_dev = ip_mc_find_dev(imr);
|
in_dev = ip_mc_find_dev(imr);
|
||||||
|
|
||||||
@ -1763,7 +1763,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
|
|||||||
ip_mc_inc_group(in_dev, addr);
|
ip_mc_inc_group(in_dev, addr);
|
||||||
err = 0;
|
err = 0;
|
||||||
done:
|
done:
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1837,7 +1837,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
|
|||||||
if (!MULTICAST(addr))
|
if (!MULTICAST(addr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
|
imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
|
||||||
imr.imr_address.s_addr = mreqs->imr_interface;
|
imr.imr_address.s_addr = mreqs->imr_interface;
|
||||||
@ -1947,7 +1947,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
|
|||||||
ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
|
ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1,
|
||||||
&mreqs->imr_sourceaddr, 1);
|
&mreqs->imr_sourceaddr, 1);
|
||||||
done:
|
done:
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
if (leavegroup)
|
if (leavegroup)
|
||||||
return ip_mc_leave_group(sk, &imr);
|
return ip_mc_leave_group(sk, &imr);
|
||||||
return err;
|
return err;
|
||||||
@ -1970,7 +1970,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
|
|||||||
msf->imsf_fmode != MCAST_EXCLUDE)
|
msf->imsf_fmode != MCAST_EXCLUDE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
|
imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
|
||||||
imr.imr_address.s_addr = msf->imsf_interface;
|
imr.imr_address.s_addr = msf->imsf_interface;
|
||||||
@ -2030,7 +2030,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
|
|||||||
pmc->sfmode = msf->imsf_fmode;
|
pmc->sfmode = msf->imsf_fmode;
|
||||||
err = 0;
|
err = 0;
|
||||||
done:
|
done:
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
if (leavegroup)
|
if (leavegroup)
|
||||||
err = ip_mc_leave_group(sk, &imr);
|
err = ip_mc_leave_group(sk, &imr);
|
||||||
return err;
|
return err;
|
||||||
@ -2050,7 +2050,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
|||||||
if (!MULTICAST(addr))
|
if (!MULTICAST(addr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
|
imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
|
||||||
imr.imr_address.s_addr = msf->imsf_interface;
|
imr.imr_address.s_addr = msf->imsf_interface;
|
||||||
@ -2072,7 +2072,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
|||||||
goto done;
|
goto done;
|
||||||
msf->imsf_fmode = pmc->sfmode;
|
msf->imsf_fmode = pmc->sfmode;
|
||||||
psl = pmc->sflist;
|
psl = pmc->sflist;
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
if (!psl) {
|
if (!psl) {
|
||||||
len = 0;
|
len = 0;
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -2091,7 +2091,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
done:
|
done:
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2112,7 +2112,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
|||||||
if (!MULTICAST(addr))
|
if (!MULTICAST(addr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
err = -EADDRNOTAVAIL;
|
err = -EADDRNOTAVAIL;
|
||||||
|
|
||||||
@ -2125,7 +2125,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
|||||||
goto done;
|
goto done;
|
||||||
gsf->gf_fmode = pmc->sfmode;
|
gsf->gf_fmode = pmc->sfmode;
|
||||||
psl = pmc->sflist;
|
psl = pmc->sflist;
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
count = psl ? psl->sl_count : 0;
|
count = psl ? psl->sl_count : 0;
|
||||||
copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
|
copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
|
||||||
gsf->gf_numsrc = count;
|
gsf->gf_numsrc = count;
|
||||||
@ -2146,7 +2146,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
done:
|
done:
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ static int __init ic_open_devs(void)
|
|||||||
unsigned short oflags;
|
unsigned short oflags;
|
||||||
|
|
||||||
last = &ic_first_dev;
|
last = &ic_first_dev;
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
|
|
||||||
/* bring loopback device up first */
|
/* bring loopback device up first */
|
||||||
if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
|
if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
|
||||||
@ -215,7 +215,7 @@ static int __init ic_open_devs(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
|
if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
d->dev = dev;
|
d->dev = dev;
|
||||||
@ -232,7 +232,7 @@ static int __init ic_open_devs(void)
|
|||||||
dev->name, able, d->xid));
|
dev->name, able, d->xid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
*last = NULL;
|
*last = NULL;
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ static void __init ic_close_devs(void)
|
|||||||
struct ic_device *d, *next;
|
struct ic_device *d, *next;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
rtnl_shlock();
|
rtnl_lock();
|
||||||
next = ic_first_dev;
|
next = ic_first_dev;
|
||||||
while ((d = next)) {
|
while ((d = next)) {
|
||||||
next = d->next;
|
next = d->next;
|
||||||
@ -262,7 +262,7 @@ static void __init ic_close_devs(void)
|
|||||||
}
|
}
|
||||||
kfree(d);
|
kfree(d);
|
||||||
}
|
}
|
||||||
rtnl_shunlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user