This patch is based on fcoe-next commit:-

        commit 6dc1ce182ce0a3057e7bac6eb29b84a0ee65cdfd
        Author: Yi Zou <[email protected]>
        Date:   Mon Aug 3 10:42:36 2009 -0700
        fcoe: Add sysfs parameter to fcoe for minimum DDP read I/O size

Signed-off-by: Vasu Dev <[email protected]>
---

 drivers/scsi/libfc/fc_exch.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index b51db15..738926d 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -79,6 +79,7 @@ struct fc_exch_mgr {
        mempool_t       *ep_pool;       /* reserve ep's */
        u16             pool_max_index; /* max exch array index in exch pool */
        struct fc_exch_pool *pool;      /* per cpu exch pool */
+       struct completion exch_released;
 
        /*
         * currently exchange mgr stats are updated but not used.
@@ -86,6 +87,7 @@ struct fc_exch_mgr {
         * all together if not used XXX
         */
        struct {
+               atomic_t no_pending_exch;
                atomic_t no_free_exch;
                atomic_t no_free_exch_xid;
                atomic_t xid_not_found;
@@ -288,6 +290,8 @@ static void fc_exch_release(struct fc_exch *ep)
                        ep->destructor(&ep->seq, ep->arg);
                WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
                mempool_free(ep, mp->ep_pool);
+               if (atomic_dec_and_test(&mp->stats.no_pending_exch))
+                       complete(&mp->exch_released);
        }
 }
 
@@ -513,11 +517,20 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport 
*lport,
                atomic_inc(&mp->stats.no_free_exch);
                goto out;
        }
+       atomic_inc(&mp->stats.no_pending_exch);
        memset(ep, 0, sizeof(*ep));
 
        cpu = smp_processor_id();
        pool = per_cpu_ptr(mp->pool, cpu);
        spin_lock_bh(&pool->lock);
+
+       if (lport->state == LPORT_ST_DISABLED) {
+               printk(KERN_INFO "%s: alloc req while lport disabled\n",
+                       __func__);
+               dump_stack();
+               goto err;
+       }
+
        index = pool->next_index;
        /* allocate new exch from pool */
        while (fc_exch_ptr_get(pool, index)) {
@@ -559,6 +572,7 @@ err:
        spin_unlock_bh(&pool->lock);
        atomic_inc(&mp->stats.no_free_exch_xid);
        mempool_free(ep, mp->ep_pool);
+       atomic_dec(&mp->stats.no_pending_exch);
        return NULL;
 }
 
@@ -1803,6 +1817,11 @@ static void fc_exch_mgr_destroy(struct kref *kref)
 {
        struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
 
+       while (atomic_read(&mp->stats.no_pending_exch)) {
+               printk(KERN_INFO "%s: stats.no_pending_exch: %d\n",
+                       __func__, atomic_read(&mp->stats.no_pending_exch));
+               wait_for_completion_timeout(&mp->exch_released, 20 * HZ);
+       }
        mempool_destroy(mp->ep_pool);
        free_percpu(mp->pool);
        kfree(mp);
@@ -1884,6 +1903,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
         * so adjust that extra increment.
         */
        kref_put(&mp->kref, fc_exch_mgr_destroy);
+       init_completion(&mp->exch_released);
        return mp;
 
 free_mempool:

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to