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