[SCSI] lpfc 8.2.3 : Miscellaneous Small Fixes - part 1

Miscellaneous Small Fixes - part 1
- Fix typo kmzlloc -> kzalloc
- Fix discovery ndlp use after free panic
- Fix link event causing flood of 0108 messages
- Relieve some mbox congestion on link up with 100 vports
- Fix broken vport parameters
- Prevent lock recursion in logo_reglogin_issue
- Split uses of error variable in lpfc_pci_probe_one into retval and error
- Remove completion code related to dev_loss_tmo
- Remove unused LPFC_MAX_HBQ #define
- Don't compare pointers to 0 for sparse
- Make 2 functions static for sparse
- Fix default rpi cleanup code causing rogue ndlps to remain on the NPR list
- Remove annoying ELS messages when driver is unloaded
- Fix Cannot issue Register Fabric login problems on link up
- Remove LPFC_EVT_DEV_LOSS_DELAY
- Fix FC port swap test leads to device going offline
- Fix vport CT flags to only be set when accepted
- Add code to handle signals during vport_create
- Fix too many retries in FC-AL mode
- Pull lpfc_port_link_failure out of lpfc_linkdown_port

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
James Smart
2007-10-27 13:37:33 -04:00
committed by James Bottomley
parent 0b727fea7a
commit 98c9ea5c02
12 changed files with 372 additions and 148 deletions

View File

@@ -107,7 +107,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
struct lpfc_nodelist * ndlp;
struct lpfc_vport *vport;
struct lpfc_hba *phba;
struct completion devloss_compl;
struct lpfc_work_evt *evtp;
rdata = rport->dd_data;
@@ -129,7 +128,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
"rport devlosscb: sid:x%x did:x%x flg:x%x",
ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
init_completion(&devloss_compl);
evtp = &ndlp->dev_loss_evt;
if (!list_empty(&evtp->evt_listp))
@@ -137,7 +135,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_lock_irq(&phba->hbalock);
evtp->evt_arg1 = ndlp;
evtp->evt_arg2 = &devloss_compl;
evtp->evt = LPFC_EVT_DEV_LOSS;
list_add_tail(&evtp->evt_listp, &phba->work_list);
if (phba->work_wait)
@@ -145,8 +142,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_unlock_irq(&phba->hbalock);
wait_for_completion(&devloss_compl);
return;
}
@@ -260,7 +255,6 @@ lpfc_work_list_done(struct lpfc_hba *phba)
{
struct lpfc_work_evt *evtp = NULL;
struct lpfc_nodelist *ndlp;
struct lpfc_vport *vport;
int free_evt;
spin_lock_irq(&phba->hbalock);
@@ -270,24 +264,6 @@ lpfc_work_list_done(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
free_evt = 1;
switch (evtp->evt) {
case LPFC_EVT_DEV_LOSS_DELAY:
free_evt = 0; /* evt is part of ndlp */
ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
vport = ndlp->vport;
if (!vport)
break;
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
"rport devlossdly:did:x%x flg:x%x",
ndlp->nlp_DID, ndlp->nlp_flag, 0);
if (!(vport->load_flag & FC_UNLOADING) &&
!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RM);
}
break;
case LPFC_EVT_ELS_RETRY:
ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
lpfc_els_retry_delay_handler(ndlp);
@@ -298,7 +274,6 @@ lpfc_work_list_done(struct lpfc_hba *phba)
lpfc_nlp_get(ndlp);
lpfc_dev_loss_tmo_handler(ndlp);
free_evt = 0;
complete((struct completion *)(evtp->evt_arg2));
lpfc_nlp_put(ndlp);
break;
case LPFC_EVT_ONLINE:
@@ -552,7 +527,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
continue;
if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN)
if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
((vport->port_type == LPFC_NPIV_PORT) &&
(ndlp->nlp_DID == NameServer_DID)))
lpfc_unreg_rpi(vport, ndlp);
/* Leave Fabric nodes alone on link down */
@@ -570,16 +547,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
}
static void
lpfc_linkdown_port(struct lpfc_vport *vport)
lpfc_port_link_failure(struct lpfc_vport *vport)
{
struct lpfc_nodelist *ndlp, *next_ndlp;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
"Link Down: state:x%x rtry:x%x flg:x%x",
vport->port_state, vport->fc_ns_retry, vport->fc_flag);
/* Cleanup any outstanding RSCN activity */
lpfc_els_flush_rscn(vport);
@@ -598,6 +568,21 @@ lpfc_linkdown_port(struct lpfc_vport *vport)
lpfc_can_disctmo(vport);
}
static void
lpfc_linkdown_port(struct lpfc_vport *vport)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
"Link Down: state:x%x rtry:x%x flg:x%x",
vport->port_state, vport->fc_ns_retry, vport->fc_flag);
lpfc_port_link_failure(vport);
}
int
lpfc_linkdown(struct lpfc_hba *phba)
{
@@ -851,8 +836,6 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
* LPFC_FLOGI while waiting for FLOGI cmpl
*/
if (vport->port_state != LPFC_FLOGI) {
vport->port_state = LPFC_FLOGI;
lpfc_set_disctmo(vport);
lpfc_initial_flogi(vport);
}
return;
@@ -1622,6 +1605,16 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
ndlp->nlp_type &= ~NLP_FC_NODE;
}
if ((old_state == NLP_STE_UNUSED_NODE) &&
(state != NLP_STE_UNUSED_NODE) &&
(ndlp->nlp_flag & NLP_DELAYED_RM)) {
/* We are using the ndlp after all, so reverse
* the delayed removal of it.
*/
ndlp->nlp_flag &= ~NLP_DELAYED_RM;
lpfc_nlp_get(ndlp);
}
if (list_empty(&ndlp->nlp_listp)) {
spin_lock_irq(shost->host_lock);
list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
@@ -1654,7 +1647,9 @@ void
lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
lpfc_nlp_put(ndlp);
if (!(ndlp->nlp_flag & NLP_DELAYED_RM))
lpfc_nlp_put(ndlp);
return;
}
/*
@@ -1975,11 +1970,6 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
if (!list_empty(&ndlp->dev_loss_evt.evt_listp))
list_del_init(&ndlp->dev_loss_evt.evt_listp);
if (!list_empty(&ndlp->dev_loss_evt.evt_listp)) {
list_del_init(&ndlp->dev_loss_evt.evt_listp);
complete((struct completion *)(ndlp->dev_loss_evt.evt_arg2));
}
lpfc_unreg_rpi(vport, ndlp);
return 0;
@@ -2418,7 +2408,6 @@ lpfc_disc_flush_list(struct lpfc_vport *vport)
if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
lpfc_free_tx(phba, ndlp);
lpfc_nlp_put(ndlp);
}
}
}
@@ -2516,8 +2505,6 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
}
}
if (vport->port_state != LPFC_FLOGI) {
vport->port_state = LPFC_FLOGI;
lpfc_set_disctmo(vport);
lpfc_initial_flogi(vport);
}
break;
@@ -2828,6 +2815,9 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return;
}
/* This routine releases all resources associated with a specifc NPort's ndlp
* and mempool_free's the nodelist.
*/
static void
lpfc_nlp_release(struct kref *kref)
{
@@ -2842,16 +2832,57 @@ lpfc_nlp_release(struct kref *kref)
mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool);
}
/* This routine bumps the reference count for a ndlp structure to ensure
* that one discovery thread won't free a ndlp while another discovery thread
* is using it.
*/
struct lpfc_nodelist *
lpfc_nlp_get(struct lpfc_nodelist *ndlp)
{
if (ndlp)
if (ndlp) {
lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
"node get: did:x%x flg:x%x refcnt:x%x",
ndlp->nlp_DID, ndlp->nlp_flag,
atomic_read(&ndlp->kref.refcount));
kref_get(&ndlp->kref);
}
return ndlp;
}
/* This routine decrements the reference count for a ndlp structure. If the
* count goes to 0, this indicates the the associated nodelist should be freed.
*/
int
lpfc_nlp_put(struct lpfc_nodelist *ndlp)
{
if (ndlp) {
lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
"node put: did:x%x flg:x%x refcnt:x%x",
ndlp->nlp_DID, ndlp->nlp_flag,
atomic_read(&ndlp->kref.refcount));
}
return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0;
}
/* This routine free's the specified nodelist if it is not in use
* by any other discovery thread. This routine returns 1 if the ndlp
* is not being used by anyone and has been freed. A return value of
* 0 indicates it is being used by another discovery thread and the
* refcount is left unchanged.
*/
int
lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
{
lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
"node not used: did:x%x flg:x%x refcnt:x%x",
ndlp->nlp_DID, ndlp->nlp_flag,
atomic_read(&ndlp->kref.refcount));
if (atomic_read(&ndlp->kref.refcount) == 1) {
lpfc_nlp_put(ndlp);
return 1;
}
return 0;
}