[SCSI] fcoe: Ensure fcoe_recv_frame is always called in process context
authorNeil Horman <nhorman@tuxdriver.com>
Fri, 9 Mar 2012 22:49:48 +0000 (14:49 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 28 Mar 2012 08:02:26 +0000 (09:02 +0100)
commit5e70c4c43e559ea6a1bf1edc0eb7d284ea7f16b4
tree48cf08ae09bdf23e9a48a10821ca5223f25ab74f
parentb08c1856b4d4295040ec72f15427588087369220
[SCSI] fcoe: Ensure fcoe_recv_frame is always called in process context

commit 859b7b649ab58ee5cbfb761491317d5b315c1b0f introduced the ability to call
fcoe_recv_frame in softirq context.  While this is beneficial to performance,
its not safe to do, as it breaks the serialization of access to the lport
structure (i.e. when an fcoe interface is being torn down, theres no way to
serialize the teardown effort with the completion of receieve operations
occuring in softirq context.  As a result, lport (and other) data structures can
be read and modified in parallel leading to corruption.  Most notable is the
vport list, which is protected by a mutex, that will cause a panic if a softirq
receive while said mutex is locked.  Additionaly, the ema_list, discussed here:

http://lists.open-fcoe.org/pipermail/devel/2012-February/011947.html

Can be corrupted if a list traversal occurs in softirq context at the same time
as a list delete in process context.  And generally the lport state variables
will not be stable, and may lead to unpredictable results.

The most direct fix is to remove the bits from the above commit that allowed
fcoe_recv_frame to be called in softirq context.  We just force all frames to be
handled by the per-cpu rx threads.  This will allow the fcoe_if_destroy's use of
fcoe_percpu_clean to function properly, ensuring that no frames are being
received while the lport is being torn down.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Reviewed-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/fcoe/fcoe.c