Fixes possible crash, caused by q2t_sess_work_fn() called on several CPUs at time. Reported by Gal Rosen <galr@storwize.com>

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1314 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2009-11-03 18:44:09 +00:00
parent cdbd65daeb
commit 02bdb07c7e
2 changed files with 12 additions and 8 deletions

View File

@@ -3173,9 +3173,10 @@ out_sched:
prm->cmd = cmd;
spin_lock_irqsave(&tgt->sess_work_lock, flags);
if (list_empty(&tgt->sess_works_list))
if (!tgt->sess_works_pending)
tgt->tm_to_unknown = 0;
list_add_tail(&prm->sess_works_list_entry, &tgt->sess_works_list);
tgt->sess_works_pending = 1;
spin_unlock_irqrestore(&tgt->sess_work_lock, flags);
schedule_work(&tgt->sess_work);
@@ -4855,18 +4856,18 @@ static void q2t_sess_work_fn(struct work_struct *work)
tgt->sess_works_list.next, typeof(*prm),
sess_works_list_entry);
/*
* This work can be scheduled on several CPUs at time, so we
* must delete the entry to eliminate double processing
*/
list_del(&prm->sess_works_list_entry);
spin_unlock_irq(&tgt->sess_work_lock);
rc = q2t_exec_sess_work(tgt, prm);
spin_lock_irq(&tgt->sess_work_lock);
/*
* Prm must be in the list on the exec time to sync with
* tm_to_unknown clearance
*/
list_del(&prm->sess_works_list_entry);
if (rc != 0) {
PRINT_CRIT_ERROR("%s", "Unable to complete sess work");
q2t_free_cmd(prm->cmd);
@@ -4878,8 +4879,10 @@ static void q2t_sess_work_fn(struct work_struct *work)
spin_lock_irq(&tgt->ha->hardware_lock);
spin_lock(&tgt->sess_work_lock);
if (list_empty(&tgt->sess_works_list))
if (list_empty(&tgt->sess_works_list)) {
tgt->sess_works_pending = 0;
tgt->tm_to_unknown = 0;
}
spin_unlock(&tgt->sess_work_lock);
spin_unlock_irq(&tgt->ha->hardware_lock);

View File

@@ -129,6 +129,7 @@ struct q2t_tgt {
unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addressing enabled */
unsigned int link_reinit_iocb_pending:1;
unsigned int tm_to_unknown:1; /* TM to unknown session was sent */
unsigned int sess_works_pending:1; /* there are sess_work entries */
/*
* Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex