diff options
author | James Smart <james.smart@emulex.com> | 2012-01-18 16:25:55 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:08:53 -0500 |
commit | b42c07c8ade6ae9d74f0fd01638760650b049cdd (patch) | |
tree | 159d7f9e6ae79ca765f158af0e08ce47b90a4bca /drivers/scsi | |
parent | 728599090a9bf3aefb1226cc063295886525cd0e (diff) |
[SCSI] lpfc 8.3.29: Remove GFP_KERNEL allocation while lock is held
Note: this is a replacement patch for the issue pointed out in
http://www.gossamer-threads.com/lists/linux/kernel/1477270
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 136 |
1 files changed, 57 insertions, 79 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e5d22b10ff2f..e0e4d8d18244 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -558,81 +558,6 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
558 | } | 558 | } |
559 | 559 | ||
560 | /** | 560 | /** |
561 | * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap. | ||
562 | * @phba: Pointer to HBA context object. | ||
563 | * @ndlp: nodelist pointer for this target. | ||
564 | * @xritag: xri used in this exchange. | ||
565 | * @rxid: Remote Exchange ID. | ||
566 | * @send_rrq: Flag used to determine if we should send rrq els cmd. | ||
567 | * | ||
568 | * This function is called with hbalock held. | ||
569 | * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an | ||
570 | * rrq struct and adds it to the active_rrq_list. | ||
571 | * | ||
572 | * returns 0 for rrq slot for this xri | ||
573 | * < 0 Were not able to get rrq mem or invalid parameter. | ||
574 | **/ | ||
575 | static int | ||
576 | __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
577 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | ||
578 | { | ||
579 | struct lpfc_node_rrq *rrq; | ||
580 | int empty; | ||
581 | uint32_t did = 0; | ||
582 | |||
583 | |||
584 | if (!ndlp) | ||
585 | return -EINVAL; | ||
586 | |||
587 | if (!phba->cfg_enable_rrq) | ||
588 | return -EINVAL; | ||
589 | |||
590 | if (phba->pport->load_flag & FC_UNLOADING) { | ||
591 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
592 | goto out; | ||
593 | } | ||
594 | did = ndlp->nlp_DID; | ||
595 | |||
596 | /* | ||
597 | * set the active bit even if there is no mem available. | ||
598 | */ | ||
599 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
600 | goto out; | ||
601 | |||
602 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | ||
603 | goto out; | ||
604 | |||
605 | if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap)) | ||
606 | goto out; | ||
607 | |||
608 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); | ||
609 | if (rrq) { | ||
610 | rrq->send_rrq = send_rrq; | ||
611 | rrq->xritag = xritag; | ||
612 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
613 | rrq->ndlp = ndlp; | ||
614 | rrq->nlp_DID = ndlp->nlp_DID; | ||
615 | rrq->vport = ndlp->vport; | ||
616 | rrq->rxid = rxid; | ||
617 | empty = list_empty(&phba->active_rrq_list); | ||
618 | rrq->send_rrq = send_rrq; | ||
619 | list_add_tail(&rrq->list, &phba->active_rrq_list); | ||
620 | if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { | ||
621 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
622 | if (empty) | ||
623 | lpfc_worker_wake_up(phba); | ||
624 | } | ||
625 | return 0; | ||
626 | } | ||
627 | out: | ||
628 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
629 | "2921 Can't set rrq active xri:0x%x rxid:0x%x" | ||
630 | " DID:0x%x Send:%d\n", | ||
631 | xritag, rxid, did, send_rrq); | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | 561 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. |
637 | * @phba: Pointer to HBA context object. | 562 | * @phba: Pointer to HBA context object. |
638 | * @xritag: xri used in this exchange. | 563 | * @xritag: xri used in this exchange. |
@@ -860,15 +785,68 @@ lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
860 | **/ | 785 | **/ |
861 | int | 786 | int |
862 | lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 787 | lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, |
863 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | 788 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) |
864 | { | 789 | { |
865 | int ret; | ||
866 | unsigned long iflags; | 790 | unsigned long iflags; |
791 | struct lpfc_node_rrq *rrq; | ||
792 | int empty; | ||
793 | |||
794 | if (!ndlp) | ||
795 | return -EINVAL; | ||
796 | |||
797 | if (!phba->cfg_enable_rrq) | ||
798 | return -EINVAL; | ||
867 | 799 | ||
868 | spin_lock_irqsave(&phba->hbalock, iflags); | 800 | spin_lock_irqsave(&phba->hbalock, iflags); |
869 | ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq); | 801 | if (phba->pport->load_flag & FC_UNLOADING) { |
802 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
803 | goto out; | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * set the active bit even if there is no mem available. | ||
808 | */ | ||
809 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
810 | goto out; | ||
811 | |||
812 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | ||
813 | goto out; | ||
814 | |||
815 | if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap)) | ||
816 | goto out; | ||
817 | |||
870 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 818 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
871 | return ret; | 819 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); |
820 | if (!rrq) { | ||
821 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
822 | "3155 Unable to allocate RRQ xri:0x%x rxid:0x%x" | ||
823 | " DID:0x%x Send:%d\n", | ||
824 | xritag, rxid, ndlp->nlp_DID, send_rrq); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | rrq->send_rrq = send_rrq; | ||
828 | rrq->xritag = xritag; | ||
829 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
830 | rrq->ndlp = ndlp; | ||
831 | rrq->nlp_DID = ndlp->nlp_DID; | ||
832 | rrq->vport = ndlp->vport; | ||
833 | rrq->rxid = rxid; | ||
834 | rrq->send_rrq = send_rrq; | ||
835 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
836 | empty = list_empty(&phba->active_rrq_list); | ||
837 | list_add_tail(&rrq->list, &phba->active_rrq_list); | ||
838 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
839 | if (empty) | ||
840 | lpfc_worker_wake_up(phba); | ||
841 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
842 | return 0; | ||
843 | out: | ||
844 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
845 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
846 | "2921 Can't set rrq active xri:0x%x rxid:0x%x" | ||
847 | " DID:0x%x Send:%d\n", | ||
848 | xritag, rxid, ndlp->nlp_DID, send_rrq); | ||
849 | return -EINVAL; | ||
872 | } | 850 | } |
873 | 851 | ||
874 | /** | 852 | /** |