lpfc 8.3.44: Fix kernel panics from corrupted ndlp list.
Subsystems (2)
PATCH 4/7 lpfc 8.3.44: Fix kernel panics from corrupted ndlp list.
Fix kernel panics from corrupted ndlp list.
Signed-off-by James Smart <[email protected]>
---
lpfc.h | 2 + lpfc_crtn.h | 1 lpfc_disc.h | 2 - lpfc_els.c | 80 +++++++++++++++++++++++++++++++++++++++------------------ lpfc_hbadisc.c | 21 ++++++++++++-- lpfc_init.c | 3 ++ lpfc_mem.c | 22 +++++++++++++++ lpfc_sli.c | 11 +++++-- 8 files changed, 110 insertions(+), 32 deletions(-)
drivers/scsi/lpfc/lpfc_crtn.h +1 -0
@@ -242,6 +242,7 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpvoid lpfc_sli4_clear_fcf_rr_bmask (struct lpfc_hba *);int lpfc_mem_alloc (struct lpfc_hba *,int align); +int lpfc_mem_alloc_active_rrq_pool_s4 (struct lpfc_hba *);void lpfc_mem_free (struct lpfc_hba *);void lpfc_mem_free_all (struct lpfc_hba *);void lpfc_stop_vport_timers (struct lpfc_vport *);
drivers/scsi/lpfc/lpfc_disc.h +1 -1
@@ -116,7 +116,7 @@ struct lpfc_nodelist {atomic_t cmd_pending;uint32_t cmd_qdepth;unsigned long last_change_time; -struct lpfc_node_rrqs active_rrqs; +unsigned long *active_rrqs_xri_bitmap;struct lpfc_scsicmd_bkt *lat_data;/* Latency data */ };struct lpfc_node_rrq {
drivers/scsi/lpfc/lpfc_els.c +55 -25
142 lines not on this page · raw message
drivers/scsi/lpfc/lpfc.h +2 -0
@@ -730,6 +730,7 @@ struct lpfc_hba {uint32_t cfg_request_firmware_upgrade;uint32_t cfg_iocb_cnt;uint32_t cfg_suppress_link_up; +uint32_t cfg_rrq_xri_bitmap_sz;#define LPFC_INITIALIZE_LINK 0/* do normal init_link mbox */ #define LPFC_DELAY_INIT_LINK 1/* layered driver hold off */ #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2/* wait, manual intervention */
@@ -835,6 +836,7 @@ struct lpfc_hba {mempool_t *mbox_mem_pool;mempool_t *nlp_mem_pool;mempool_t *rrq_pool; +mempool_t *active_rrq_pool;struct fc_host_statistics link_stats;enum intr_type_t intr_type;
drivers/scsi/lpfc/lpfc_hbadisc.c +18 -3
@@ -4186,6 +4186,7 @@ lpfc_enable_node(struct lpfc_vport *vporstruct lpfc_hba *phba = vport->phba;uint32_t did;unsigned long flags; +unsigned long *active_rrqs_xri_bitmap =NULL ;if (!ndlp)return NULL ;
@@ -4214,12 +4215,17 @@ lpfc_enable_node(struct lpfc_vport *vpor/* Keep the original DID */ did = ndlp->nlp_DID; +if (phba->sli_rev ==LPFC_SLI_REV4 ) + active_rrqs_xri_bitmap = ndlp->active_rrqs_xri_bitmap;/* re-initialize ndlp except of ndlp linked list pointer */ memset ((((char *)ndlp) +sizeof (struct list_head )),0 ,sizeof (struct lpfc_nodelist ) -sizeof (struct list_head ));lpfc_initialize_node (vport, ndlp, did); +if (phba->sli_rev ==LPFC_SLI_REV4 ) + ndlp->active_rrqs_xri_bitmap = active_rrqs_xri_bitmap; +spin_unlock_irqrestore (&phba->ndlp_lock, flags);if (vport->phba->sli_rev ==LPFC_SLI_REV4 ) ndlp->nlp_rpi =lpfc_sli4_alloc_rpi (vport->phba);
@@ -4805,9 +4811,10 @@ __lpfc_findnode_did(struct lpfc_vport *v ((uint32_t) ndlp->nlp_rpi & 0xff));lpfc_printf_vlog (vport,KERN_INFO ,LOG_NODE ,"0929 FIND node DID " -"Data: x%p x%x x%x x%x\n" , +"Data: x%p x%x x%x x%x %p\n" , ndlp, ndlp->nlp_DID, - ndlp->nlp_flag, data1); + ndlp->nlp_flag, data1, + ndlp->active_rrqs_xri_bitmap);return ndlp; } }
@@ -5624,8 +5631,13 @@ lpfc_nlp_init(struct lpfc_vport *vport,lpfc_initialize_node (vport, ndlp, did);INIT_LIST_HEAD (&ndlp->nlp_listp); -if (vport->phba->sli_rev ==LPFC_SLI_REV4 ) +if (vport->phba->sli_rev ==LPFC_SLI_REV4 ) { ndlp->nlp_rpi =lpfc_sli4_alloc_rpi (vport->phba); + ndlp->active_rrqs_xri_bitmap = +mempool_alloc (vport->phba->active_rrq_pool, +GFP_KERNEL ); + } + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
@@ -5670,6 +5682,9 @@ lpfc_nlp_release(struct kref *kref)/* free ndlp memory for final ndlp release */ if (NLP_CHK_FREE_REQ (ndlp)) {kfree (ndlp->lat_data); +if (phba->sli_rev ==LPFC_SLI_REV4 ) +mempool_free (ndlp->active_rrqs_xri_bitmap, + ndlp->phba->active_rrq_pool);mempool_free (ndlp, ndlp->phba->nlp_mem_pool); } }
drivers/scsi/lpfc/lpfc_init.c +3 -0
@@ -5061,6 +5061,9 @@ lpfc_sli4_driver_resource_setup(struct l rc =lpfc_sli4_read_config (phba);if (unlikely (rc)) goto out_free_bsmbx; + rc =lpfc_mem_alloc_active_rrq_pool_s4 (phba); +if (unlikely (rc)) + goto out_free_bsmbx;/* IF Type 0 ports get initialized now. */ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
drivers/scsi/lpfc/lpfc_mem.c +22 -0
@@ -38,10 +38,28 @@#include "lpfc_scsi.h" #include "lpfc.h" #include "lpfc_crtn.h" +#include "lpfc_logmsg.h" #define LPFC_MBUF_POOL_SIZE 64/* max elements in MBUF safety pool */ #define LPFC_MEM_POOL_SIZE 64/* max elem in non-DMA safety pool */ +int +lpfc_mem_alloc_active_rrq_pool_s4 (struct lpfc_hba *phba) { +size_t bytes; +int max_xri = phba->sli4_hba.max_cfg_param.max_xri; + +if (max_xri <=0 ) +return -ENOMEM ; + bytes = ((BITS_PER_LONG -1 + max_xri) /BITS_PER_LONG ) * +sizeof (unsigned long ); + phba->cfg_rrq_xri_bitmap_sz = bytes; + phba->active_rrq_pool =mempool_create_kmalloc_pool (LPFC_MEM_POOL_SIZE , + bytes); +if (!phba->active_rrq_pool) +return -ENOMEM ; +else +return 0 ; +}/** * lpfc_mem_alloc - create and allocate all PCI and memory pools
@@ -209,6 +227,10 @@ lpfc_mem_free(struct lpfc_hba *phba)/* Free NLP memory pool */ mempool_destroy (phba->nlp_mem_pool); phba->nlp_mem_pool =NULL ; +if (phba->sli_rev ==LPFC_SLI_REV4 && phba->active_rrq_pool) { +mempool_destroy (phba->active_rrq_pool); + phba->active_rrq_pool =NULL ; + }/* Free mbox memory pool */ mempool_destroy (phba->mbox_mem_pool);
drivers/scsi/lpfc/lpfc_sli.c +8 -3
@@ -635,7 +635,7 @@ lpfc_clr_rrq_active(struct lpfc_hba *phbif (!ndlp) goto out; -if (test_and_clear_bit (xritag, ndlp->active_rrqs.xri_bitmap)) { +if (test_and_clear_bit (xritag, ndlp->active_rrqs_xri_bitmap)) { rrq->send_rrq =0 ; rrq->xritag =0 ; rrq->rrq_stop_time =0 ;
@@ -813,7 +813,9 @@ lpfc_test_rrq_active(struct lpfc_hba *ph {if (!ndlp)return 0 ; -if (test_bit (xritag, ndlp->active_rrqs.xri_bitmap)) +if (!ndlp->active_rrqs_xri_bitmap) +return 0 ; +if (test_bit (xritag, ndlp->active_rrqs_xri_bitmap))return 1 ;else return 0 ;
@@ -863,7 +865,10 @@ lpfc_set_rrq_active(struct lpfc_hba *phbif (ndlp->vport && (ndlp->vport->load_flag &FC_UNLOADING )) goto out; -if (test_and_set_bit (xritag, ndlp->active_rrqs.xri_bitmap)) +if (!ndlp->active_rrqs_xri_bitmap) + goto out; + +if (test_and_set_bit (xritag, ndlp->active_rrqs_xri_bitmap)) goto out;spin_unlock_irqrestore (&phba->hbalock, iflags);