Commit 6756ae4b authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

[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: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 253aa115
...@@ -1605,7 +1605,7 @@ static void rtl8139_thread (void *_data) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -262,7 +262,7 @@ static void __init ic_close_devs(void)
} }
kfree(d); kfree(d);
} }
rtnl_shunlock(); rtnl_unlock();
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment