Skip to content

Commit

Permalink
qla3xxx: bugfix: Move link state machine into a worker thread
Browse files Browse the repository at this point in the history
The link state machine requires access to some resources that
are shared with the iSCSI function on the chip.  (See iSCSI
driver at drivers/scsi/qla4xxx)  If the interface is being
up/downed at a rapid pace this driver may need to sleep
waiting to get access to the common resources. For this we
are moving the state machine to run as a work thread.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Ron Mercer authored and Jeff Garzik committed Nov 10, 2007
1 parent 32bee77 commit 3e23b7d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
27 changes: 13 additions & 14 deletions drivers/net/qla3xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1645,8 +1645,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev)
return 0;
}

static void ql_link_state_machine(struct ql3_adapter *qdev)
static void ql_link_state_machine_work(struct work_struct *work)
{
struct ql3_adapter *qdev =
container_of(work, struct ql3_adapter, link_state_work.work);

u32 curr_link_state;
unsigned long hw_flags;

Expand All @@ -1661,6 +1664,10 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
"state.\n", qdev->ndev->name);

spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);

/* Restart timer on 2 second interval. */
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\

return;
}

Expand Down Expand Up @@ -1705,6 +1712,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
break;
}
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);

/* Restart timer on 2 second interval. */
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
}

/*
Expand Down Expand Up @@ -3941,19 +3951,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev)
static void ql3xxx_timer(unsigned long ptr)
{
struct ql3_adapter *qdev = (struct ql3_adapter *)ptr;

if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) {
printk(KERN_DEBUG PFX
"%s: Reset in progress.\n",
qdev->ndev->name);
goto end;
}

ql_link_state_machine(qdev);

/* Restart timer on 2 second interval. */
end:
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0);
}

static int __devinit ql3xxx_probe(struct pci_dev *pdev,
Expand Down Expand Up @@ -4103,6 +4101,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
qdev->workqueue = create_singlethread_workqueue(ndev->name);
INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work);

init_timer(&qdev->adapter_timer);
qdev->adapter_timer.function = ql3xxx_timer;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/qla3xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,7 @@ struct ql3_adapter {
struct workqueue_struct *workqueue;
struct delayed_work reset_work;
struct delayed_work tx_timeout_work;
struct delayed_work link_state_work;
u32 max_frame_size;
u32 device_id;
u16 phyType;
Expand Down

0 comments on commit 3e23b7d

Please sign in to comment.