Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3163f725 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.2.5 : Fix buffer leaks



Fix buffer leaks:
- HBQ dma buffer leak at dma_pool_destroy when unloading driver
- Fix missing buffer free in slow ring buffer handling

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 7f5f3d0d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -495,6 +495,8 @@ struct lpfc_hba {
	wait_queue_head_t    *work_wait;
	struct task_struct   *worker_thread;

	uint32_t hbq_in_use;		/* HBQs in use flag */
	struct list_head hbqbuf_in_list;  /* in-fly hbq buffer list */
	uint32_t hbq_count;	        /* Count of configured HBQs */
	struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies  */

+13 −4
Original line number Diff line number Diff line
@@ -629,9 +629,8 @@ lpfc_linkdown(struct lpfc_hba *phba)
	LPFC_MBOXQ_t          *mb;
	int i;

	if (phba->link_state == LPFC_LINK_DOWN) {
	if (phba->link_state == LPFC_LINK_DOWN)
		return 0;
	}
	spin_lock_irq(&phba->hbalock);
	if (phba->link_state > LPFC_LINK_DOWN) {
		phba->link_state = LPFC_LINK_DOWN;
@@ -1122,7 +1121,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
	if (la->attType == AT_LINK_UP) {
		phba->fc_stat.LinkUp++;
		if (phba->link_flag & LS_LOOPBACK_MODE) {
			lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
					"1306 Link Up Event in loop back mode "
					"x%x received Data: x%x x%x x%x x%x\n",
					la->eventTag, phba->fc_eventTag,
@@ -1139,11 +1138,21 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
		lpfc_mbx_process_link_up(phba, la);
	} else {
		phba->fc_stat.LinkDown++;
		if (phba->link_flag & LS_LOOPBACK_MODE) {
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
				"1308 Link Down Event in loop back mode "
				"x%x received "
				"Data: x%x x%x x%x\n",
				la->eventTag, phba->fc_eventTag,
				phba->pport->port_state, vport->fc_flag);
		}
		else {
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
				"1305 Link Down Event x%x received "
				"Data: x%x x%x x%x\n",
				la->eventTag, phba->fc_eventTag,
				phba->pport->port_state, vport->fc_flag);
		}
		lpfc_mbx_issue_link_down(phba);
	}

+16 −1
Original line number Diff line number Diff line
/*******************************************************************
 * This file is part of the Emulex Linux Device Driver for         *
 * Fibre Channel Host Bus Adapters.                                *
 * Copyright (C) 2004-2007 Emulex.  All rights reserved.           *
 * Copyright (C) 2004-2008 Emulex.  All rights reserved.           *
 * EMULEX and SLI are trademarks of Emulex.                        *
 * www.emulex.com                                                  *
 *                                                                 *
@@ -1377,11 +1377,26 @@ typedef struct { /* FireFly BIU registers */
#define CMD_QUE_XRI64_CX	0xB3
#define CMD_IOCB_RCV_SEQ64_CX	0xB5
#define CMD_IOCB_RCV_ELS64_CX	0xB7
#define CMD_IOCB_RET_XRI64_CX	0xB9
#define CMD_IOCB_RCV_CONT64_CX	0xBB

#define CMD_GEN_REQUEST64_CR    0xC2
#define CMD_GEN_REQUEST64_CX    0xC3

/* Unhandled SLI-3 Commands */
#define CMD_IOCB_XMIT_MSEQ64_CR		0xB0
#define CMD_IOCB_XMIT_MSEQ64_CX		0xB1
#define CMD_IOCB_RCV_SEQ_LIST64_CX	0xC1
#define CMD_IOCB_RCV_ELS_LIST64_CX	0xCD
#define CMD_IOCB_CLOSE_EXTENDED_CN	0xB6
#define CMD_IOCB_ABORT_EXTENDED_CN	0xBA
#define CMD_IOCB_RET_HBQE64_CN		0xCA
#define CMD_IOCB_FCP_IBIDIR64_CR	0xAC
#define CMD_IOCB_FCP_IBIDIR64_CX	0xAD
#define CMD_IOCB_FCP_ITASKMGT64_CX	0xAF
#define CMD_IOCB_LOGENTRY_CN		0x94
#define CMD_IOCB_LOGENTRY_ASYNC_CN	0x96

#define CMD_MAX_IOCB_CMD        0xE6
#define CMD_IOCB_MASK           0xff

+2 −0
Original line number Diff line number Diff line
@@ -2087,6 +2087,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)

	memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size());

	INIT_LIST_HEAD(&phba->hbqbuf_in_list);

	/* Initialize the SLI Layer to run with lpfc HBAs. */
	lpfc_sli_setup(phba);
	lpfc_sli_queue_setup(phba);
+9 −0
Original line number Diff line number Diff line
@@ -264,18 +264,27 @@ void
lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
{
	struct hbq_dmabuf *hbq_entry;
	unsigned long flags;

	if (!mp)
		return;

	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
		/* Check whether HBQ is still in use */
		spin_lock_irqsave(&phba->hbalock, flags);
		if (!phba->hbq_in_use) {
			spin_unlock_irqrestore(&phba->hbalock, flags);
			return;
		}
		hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
		list_del(&hbq_entry->dbuf.list);
		if (hbq_entry->tag == -1) {
			(phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer)
				(phba, hbq_entry);
		} else {
			lpfc_sli_free_hbq(phba, hbq_entry);
		}
		spin_unlock_irqrestore(&phba->hbalock, flags);
	} else {
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
Loading