sunvnet: Use RCU to synchronize port usage with vnet_port_remove()
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Sat, 25 Oct 2014 19:12:20 +0000 (15:12 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 25 Oct 2014 20:20:15 +0000 (16:20 -0400)
commit2a968dd8f7d71ae85c4fe0ff190fbfb4212faf98
tree48144487f5fa0b19229ec8d4c50f471fc2745731
parent69088822abe7a09145fc86e1d5dd4996e29abc2d
sunvnet: Use RCU to synchronize port usage with vnet_port_remove()

A vnet_port_remove could be triggered as a result of an ldm-unbind
operation by the peer, module unload, or other changes to the
inter-vnet-link configuration.  When this is concurrent with
vnet_start_xmit(), there are several race sequences possible,
such as

thread 1                                    thread 2
vnet_start_xmit
-> tx_port_find
   spin_lock_irqsave(&vp->lock..)
   ret = __tx_port_find(..)
   spin_lock_irqrestore(&vp->lock..)
                                           vio_remove -> ..
                                               ->vnet_port_remove
                                           spin_lock_irqsave(&vp->lock..)
                                           cleanup
                                           spin_lock_irqrestore(&vp->lock..)
                                           kfree(port)
/* attempt to use ret will bomb */

This patch adds RCU locking for port access so that vnet_port_remove
will correctly clean up port-related state.

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Dwight Engen <dwight.engen@oracle.com>
Acked-by: Bob Picco <bob.picco@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sun/sunvnet.c