]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/libfc-improve-fc_lport-c-locki.diff
Added missing Xen Kernel Patches which were not commited because
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / libfc-improve-fc_lport-c-locki.diff
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/libfc-improve-fc_lport-c-locki.diff b/src/patches/suse-2.6.27.31/patches.drivers/libfc-improve-fc_lport-c-locki.diff
new file mode 100644 (file)
index 0000000..89f885d
--- /dev/null
@@ -0,0 +1,114 @@
+From: Robert Love <robert.w.love@intel.com>
+Subject: [FcOE] Improve fc_lport.c locking comment block
+References: bnc #459142
+
+Signed-off-by: Robert Love <robert.w.love@intel.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+---
+
+ drivers/scsi/libfc/fc_lport.c |   76 ++++++++++++++++++++++++------------------
+ 1 file changed, 45 insertions(+), 31 deletions(-)
+
+
+--- a/drivers/scsi/libfc/fc_lport.c
++++ b/drivers/scsi/libfc/fc_lport.c
+@@ -18,34 +18,51 @@
+  */
+ /*
+- * General locking notes:
++ * PORT LOCKING NOTES
+  *
+- * The lport and rport blocks both have mutexes that are used to protect
+- * the port objects states. The main motivation for this protection is that
+- * we don't want to be preparing a request/response in one context while
+- * another thread "resets" the port in question. For example, if the lport
+- * block is sending a SCR request to the directory server we don't want
+- * the lport to be reset before we fill out the frame header's port_id. The
+- * problem is that a reset would cause the lport's port_id to reset to 0.
+- * If we don't protect the lport we'd spew incorrect frames.
+- *
+- * At the time of this writing there are two primary mutexes, one for the
+- * lport and one for the rport. Since the lport uses the rport and makes
+- * calls into that block the rport should never make calls that would cause
+- * the lport's mutex to be locked. In other words, the lport's mutex is
+- * considered the outer lock and the rport's lock is considered the inner
+- * lock. The bottom line is that you can hold a lport's mutex and then
+- * hold the rport's mutex, but not the other way around.
+- *
+- * The only complication to this rule is the callbacks from the rport to
+- * the lport's rport_callback function. When rports become READY they make
+- * a callback to the lport so that it can track them. In the case of the
+- * directory server that callback might cause the lport to change its
+- * state, implying that the lport mutex would need to be held. This problem
+- * was solved by serializing the rport notifications to the lport and the
+- * callback is made without holding the rport's lock.
++ * These comments only apply to the 'port code' which consists of the lport,
++ * disc and rport blocks.
+  *
+- * lport locking notes:
++ * MOTIVATION
++ *
++ * The lport, disc and rport blocks all have mutexes that are used to protect
++ * those objects. The main motivation for these locks is to prevent from
++ * having an lport reset just before we send a frame. In that scenario the
++ * lport's FID would get set to zero and then we'd send a frame with an
++ * invalid SID. We also need to ensure that states don't change unexpectedly
++ * while processing another state.
++ *
++ * HEIRARCHY
++ *
++ * The following heirarchy defines the locking rules. A greater lock
++ * may be held before acquiring a lesser lock, but a lesser lock should never
++ * be held while attempting to acquire a greater lock. Here is the heirarchy-
++ *
++ * lport > disc, lport > rport, disc > rport
++ *
++ * CALLBACKS
++ *
++ * The callbacks cause complications with this scheme. There is a callback
++ * from the rport (to either lport or disc) and a callback from disc
++ * (to the lport).
++ *
++ * As rports exit the rport state machine a callback is made to the owner of
++ * the rport to notify success or failure. Since the callback is likely to
++ * cause the lport or disc to grab its lock we cannot hold the rport lock
++ * while making the callback. To ensure that the rport is not free'd while
++ * processing the callback the rport callbacks are serialized through a
++ * single-threaded workqueue. An rport would never be free'd while in a
++ * callback handler becuase no other rport work in this queue can be executed
++ * at the same time.
++ *
++ * When discovery succeeds or fails a callback is made to the lport as
++ * notification. Currently, succesful discovery causes the lport to take no
++ * action. A failure will cause the lport to reset. There is likely a circular
++ * locking problem with this implementation.
++ */
++
++/*
++ * LPORT LOCKING
+  *
+  * The critical sections protected by the lport's mutex are quite broad and
+  * may be improved upon in the future. The lport code and its locking doesn't
+@@ -54,9 +71,9 @@
+  *
+  * The strategy is to lock whenever processing a request or response. Note
+  * that every _enter_* function corresponds to a state change. They generally
+- * change the lports state and then sends a request out on the wire. We lock
++ * change the lports state and then send a request out on the wire. We lock
+  * before calling any of these functions to protect that state change. This
+- * means that the entry points into the lport block to manage the locks while
++ * means that the entry points into the lport block manage the locks while
+  * the state machine can transition between states (i.e. _enter_* functions)
+  * while always staying protected.
+  *
+@@ -68,9 +85,6 @@
+  * Retries also have to consider the locking. The retries occur from a work
+  * context and the work function will lock the lport and then retry the state
+  * (i.e. _enter_* function).
+- *
+- * The implication to all of this is that each lport can only process one
+- * state at a time.
+  */
+ #include <linux/timer.h>