On 2/2/2012 12:30 PM, Neil Horman wrote:
On Thu, Feb 02, 2012 at 11:47:50AM -0800, Bhanu Prakash Gollapudi wrote:
On 2/2/2012 7:50 AM, Neil Horman wrote:
fc_port->ema_list is being accessed in multiple parallel contexts with no
locking around it leading to potential corruption.  Whats more the fc_find_ema
function was manually accessing ema_list.prev without checking for a list_empty
condition.  The ema_list could easily be emtpy if an transation came in to the
foce stack with an UNKNOWN xid prior to our adding a ema anchor to the list
(dev_add_pack gets called before said add occurs).

Fix it by adding an ema_lock to list accesses.  Make it an rcu lock so we don't
get Warnings when we try to tx a frame with a spinlock held

Signed-off-by: Neil Horman<nhor...@tuxdriver.com>
CC: kiran.pa...@intel.com
CC: bprak...@broadcom.com
CC: robert.w.l...@intel.com
---
  drivers/scsi/libfc/fc_exch.c |  102 +++++++++++++++++++++++++++++++-----------
  include/scsi/libfc.h         |    2 +
  2 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 630291f..9c63464 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -130,6 +130,7 @@ struct fc_exch_mgr_anchor {
        struct list_head ema_list;
        struct fc_exch_mgr *mp;
        bool (*match)(struct fc_frame *);
+       struct rcu_head rcu;
  };

  static void fc_exch_rrq(struct fc_exch *);
@@ -402,9 +403,10 @@ static void fc_exch_delete(struct fc_exch *ep)
  {
        struct fc_exch_pool *pool;
        u16 index;
+       unsigned long flags;

        pool = ep->pool;
-       spin_lock_bh(&pool->lock);
+       spin_lock_irqsave(&pool->lock, flags);

There is no contention between hard IRQs, so why do we need
spin_lock_irqsave()? spin_lock_bh() should be good enough as the
contention is only between softirq and process context.

Dang it, the pool_lock changes are pointless, they weren't meant to be in here,
just the ema_lock additions.  My git tree commits must be dirty, I'll repost
shortly.

If we can use spin_lock_bh(), second patch can be avoided.

Thats incorrect.  The second patch deals with managing the ex_lock,
not this new ema_lock, and it deals with dropping it prior to calling
fcoe_seq_send.  Specifically we have to drop it because transmitting a frame
with bottom halves disabled generates a warning.

You're hitting the following warning right?

static inline void _local_bh_enable_ip(unsigned long ip)
{
        WARN_ON_ONCE(in_irq() || irqs_disabled());

I think this is because of acquiring ex_lock using spin_lock_irqsave() (one of the changes done in this patch). If it was spin_lock_bh(), you should not have seen this. Isn't it?


_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to