Since this thread will call into the lport which will lock
a mutex it can't be in irq context. This patch switches
it from a timer to work thread.
Signed-off-by: Robert Love <[EMAIL PROTECTED]>
---
drivers/scsi/libfc/fc_exch.c | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 06e6236..0531c7c 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -86,7 +86,7 @@ struct fc_exch {
struct list_head ex_list; /* free or busy list linkage */
spinlock_t ex_lock; /* lock covering exchange state */
atomic_t ex_refcnt; /* reference counter */
- struct timer_list ex_timer; /* timer for upper level protocols */
+ struct delayed_work timeout_work; /* timer for upper level protocols */
struct fc_lport *lp; /* fc device instance */
u16 oxid; /* originator's exchange ID */
u16 rxid; /* responder's exchange ID */
@@ -310,7 +310,6 @@ static void fc_exch_release(struct fc_exch *ep)
if (ep->lp->tt.exch_put)
ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE);
- WARN_ON(timer_pending(&ep->ex_timer));
mempool_free(ep, mp->ep_pool);
}
}
@@ -332,7 +331,7 @@ static int fc_exch_done_locked(struct fc_exch *ep)
if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
ep->state |= FC_EX_DONE;
- if (del_timer(&ep->ex_timer))
+ if (cancel_delayed_work(&ep->timeout_work))
atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
rc = 0;
}
@@ -362,7 +361,8 @@ static inline void fc_exch_timer_set_locked(struct fc_exch
*ep,
if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
return;
- if (!mod_timer(&ep->ex_timer, jiffies + msecs_to_jiffies(timer_msec)))
+ if (schedule_delayed_work(&ep->timeout_work,
+ jiffies + msecs_to_jiffies(timer_msec)))
fc_exch_hold(ep); /* hold for timer */
}
@@ -435,9 +435,10 @@ EXPORT_SYMBOL(fc_seq_exch_abort);
* Exchange timeout - handle exchange timer expiration.
* The timer will have been cancelled before this is called.
*/
-static void fc_exch_timeout(unsigned long ep_arg)
+static void fc_exch_timeout(struct work_struct *work)
{
- struct fc_exch *ep = (struct fc_exch *)ep_arg;
+ struct fc_exch *ep = container_of(work, struct fc_exch,
+ timeout_work.work);
struct fc_seq *sp = &ep->seq;
void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
void *arg;
@@ -584,7 +585,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16
xid)
ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */
ep->rxid = FC_XID_UNKNOWN;
ep->class = mp->class;
- setup_timer(&ep->ex_timer, fc_exch_timeout, (unsigned long)ep);
+ INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
out:
return ep;
err:
@@ -1331,7 +1332,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct
fc_frame *fp)
FC_DBG("exch: BLS rctl %x - %s\n",
fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl));
- if (del_timer_sync(&ep->ex_timer))
+ if (cancel_delayed_work_sync(&ep->timeout_work))
fc_exch_release(ep); /* release from pending timer hold */
spin_lock_bh(&ep->ex_lock);
@@ -1509,7 +1510,7 @@ static void fc_exch_reset(struct fc_exch *ep)
* functions can also grab the lport lock which could cause
* a deadlock).
*/
- if (del_timer(&ep->ex_timer))
+ if (cancel_delayed_work(&ep->timeout_work))
atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
resp = ep->resp;
ep->resp = NULL;
@@ -1785,8 +1786,10 @@ static void fc_exch_els_rrq(struct fc_seq *sp, struct
fc_frame *fp)
ep->esb_stat &= ~ESB_ST_REC_QUAL;
atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */
}
- if ((ep->esb_stat & ESB_ST_COMPLETE) && (del_timer(&ep->ex_timer)))
- atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
+ if (ep->esb_stat & ESB_ST_COMPLETE) {
+ if (cancel_delayed_work(&ep->timeout_work))
+ atomic_dec(&ep->ex_refcnt); /* drop hold for timer
*/
+ }
spin_unlock_bh(&ep->ex_lock);
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel