[PATCH] uml: network driver locking and code cleanup

Add some missing locking to walks of the transports and opened lists.

Delete some dead code.

Comment the lack of some locking.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Jeff Dike 2007-02-10 01:44:04 -08:00 committed by Linus Torvalds
parent f979522052
commit c862fc32a3

View file

@ -502,7 +502,7 @@ static DEFINE_SPINLOCK(transports_lock);
static LIST_HEAD(transports); static LIST_HEAD(transports);
/* Filled in during early boot */ /* Filled in during early boot */
struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); static LIST_HEAD(eth_cmd_line);
static int check_transport(struct transport *transport, char *eth, int n, static int check_transport(struct transport *transport, char *eth, int n,
void **init_out, char **mac_out) void **init_out, char **mac_out)
@ -563,7 +563,9 @@ static int eth_setup_common(char *str, int index)
struct transport *transport; struct transport *transport;
void *init; void *init;
char *mac = NULL; char *mac = NULL;
int found = 0;
spin_lock(&transports_lock);
list_for_each(ele, &transports){ list_for_each(ele, &transports){
transport = list_entry(ele, struct transport, list); transport = list_entry(ele, struct transport, list);
if(!check_transport(transport, str, index, &init, &mac)) if(!check_transport(transport, str, index, &init, &mac))
@ -572,9 +574,12 @@ static int eth_setup_common(char *str, int index)
eth_configure(index, init, mac, transport); eth_configure(index, init, mac, transport);
kfree(init); kfree(init);
} }
return 1; found = 1;
break;
} }
return 0;
spin_unlock(&transports_lock);
return found;
} }
static int eth_setup(char *str) static int eth_setup(char *str)
@ -610,24 +615,6 @@ __uml_help(eth_setup,
" Configure a network device.\n\n" " Configure a network device.\n\n"
); );
#if 0
static int eth_init(void)
{
struct list_head *ele, *next;
struct eth_init *eth;
list_for_each_safe(ele, next, &eth_cmd_line){
eth = list_entry(ele, struct eth_init, list);
if(eth_setup_common(eth->init, eth->index))
list_del(&eth->list);
}
return(1);
}
__initcall(eth_init);
#endif
static int net_config(char *str, char **error_out) static int net_config(char *str, char **error_out)
{ {
int n, err; int n, err;
@ -729,6 +716,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* uml_net_init shouldn't be called twice on two CPUs at the same time */
struct notifier_block uml_inetaddr_notifier = { struct notifier_block uml_inetaddr_notifier = {
.notifier_call = uml_inetaddr_event, .notifier_call = uml_inetaddr_event,
}; };
@ -747,18 +735,21 @@ static int uml_net_init(void)
* didn't get a chance to run for them. This fakes it so that * didn't get a chance to run for them. This fakes it so that
* addresses which have already been set up get handled properly. * addresses which have already been set up get handled properly.
*/ */
spin_lock(&opened_lock);
list_for_each(ele, &opened){ list_for_each(ele, &opened){
lp = list_entry(ele, struct uml_net_private, list); lp = list_entry(ele, struct uml_net_private, list);
ip = lp->dev->ip_ptr; ip = lp->dev->ip_ptr;
if(ip == NULL) continue; if(ip == NULL)
continue;
in = ip->ifa_list; in = ip->ifa_list;
while(in != NULL){ while(in != NULL){
uml_inetaddr_event(NULL, NETDEV_UP, in); uml_inetaddr_event(NULL, NETDEV_UP, in);
in = in->ifa_next; in = in->ifa_next;
} }
} }
spin_unlock(&opened_lock);
return(0); return 0;
} }
__initcall(uml_net_init); __initcall(uml_net_init);
@ -768,13 +759,16 @@ static void close_devices(void)
struct list_head *ele; struct list_head *ele;
struct uml_net_private *lp; struct uml_net_private *lp;
spin_lock(&opened_lock);
list_for_each(ele, &opened){ list_for_each(ele, &opened){
lp = list_entry(ele, struct uml_net_private, list); lp = list_entry(ele, struct uml_net_private, list);
free_irq(lp->dev->irq, lp->dev); free_irq(lp->dev->irq, lp->dev);
if((lp->close != NULL) && (lp->fd >= 0)) if((lp->close != NULL) && (lp->fd >= 0))
(*lp->close)(lp->fd, &lp->user); (*lp->close)(lp->fd, &lp->user);
if(lp->remove != NULL) (*lp->remove)(&lp->user); if(lp->remove != NULL)
(*lp->remove)(&lp->user);
} }
spin_unlock(&opened_lock);
} }
__uml_exitcall(close_devices); __uml_exitcall(close_devices);