diff options
author | Urs Thuermann <urs.thuermann@volkswagen.de> | 2008-02-07 18:04:45 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-07 18:04:45 -0800 |
commit | a2fea5f19f970b45e854c22cab25250a79613643 (patch) | |
tree | ed65426674c487102a98d5d28e6a8b5653525a4a /net/can/af_can.c | |
parent | 5423dd67bd0108a180784c6f307646622e804c9b (diff) | |
download | lwn-a2fea5f19f970b45e854c22cab25250a79613643.tar.gz lwn-a2fea5f19f970b45e854c22cab25250a79613643.zip |
[CAN]: Move proto_{,un}register() out of spin-locked region
The implementation of proto_register() has changed so that it can now
sleep. The call to proto_register() must be moved out of the
spin-locked region.
Signed-off-by: Urs Thuermann <urs.thuermann@volkswagen.de>
Signed-off-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/can/af_can.c')
-rw-r--r-- | net/can/af_can.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c index 1f51b8a18242..36b9f22ed83a 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -656,26 +656,26 @@ int can_proto_register(struct can_proto *cp) return -EINVAL; } + err = proto_register(cp->prot, 0); + if (err < 0) + return err; + spin_lock(&proto_tab_lock); if (proto_tab[proto]) { printk(KERN_ERR "can: protocol %d already registered\n", proto); err = -EBUSY; - goto errout; + } else { + proto_tab[proto] = cp; + + /* use generic ioctl function if not defined by module */ + if (!cp->ops->ioctl) + cp->ops->ioctl = can_ioctl; } + spin_unlock(&proto_tab_lock); - err = proto_register(cp->prot, 0); if (err < 0) - goto errout; - - proto_tab[proto] = cp; - - /* use generic ioctl function if the module doesn't bring its own */ - if (!cp->ops->ioctl) - cp->ops->ioctl = can_ioctl; - - errout: - spin_unlock(&proto_tab_lock); + proto_unregister(cp->prot); return err; } @@ -694,9 +694,10 @@ void can_proto_unregister(struct can_proto *cp) printk(KERN_ERR "BUG: can: protocol %d is not registered\n", proto); } - proto_unregister(cp->prot); proto_tab[proto] = NULL; spin_unlock(&proto_tab_lock); + + proto_unregister(cp->prot); } EXPORT_SYMBOL(can_proto_unregister); |