All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Nigel Kirkland" <nkirkland2304@gmail.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v6 5/8] lpfc: Rework I/O flush ordering when unloading driver
Date: Tue, 13 Oct 2026 00:12:51 +0000	[thread overview]
Message-ID: <sashiko-outbox-168784@kernel.org> (raw)
In-Reply-To: <20261013001648.62289-6-nkirkland2304@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] lpfc: lockless mutation of txcmplq in lpfc_els_abort causes list corruption
- [High] lpfc: Use-After-Free of lpfc_queue in destroy_workqueue during unload
- [High] scsi: lpfc: memory leak / infinite wait for IOCBs on txcmplq during unload
--

commit c519125dd5fca5410ebb69899d1a9f5ce0a92a82
Author: Nigel Kirkland <nkirkland2304@gmail.com>

lpfc: Rework I/O flush ordering when unloading driver

This commit modifies the handling of failed aborts during driver unload
to avoid concurrent threads acting on the same IOCB. It also delays
freeing the IOCB list until after the HBA is unset and flushes the
workqueue during PCI removal.

> diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
> --- a/drivers/scsi/lpfc/lpfc_init.c
> +++ b/drivers/scsi/lpfc/lpfc_init.c
[ ... ]
> @@ -14948,11 +14951,20 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev)
>  
>  	/* Perform scsi free before driver resource_unset since scsi
>  	 * buffers are released to their corresponding pools here.
> +	 * lpfc_sli4_hba_unset() issues aborts via lpfc_sli_hba_iocb_abort(),
> +	 * which allocates abort IOCBs from phba->lpfc_iocb_list; the pool
> +	 * must still exist, so lpfc_free_iocb_list() runs only after unset.
>  	 */
>  	lpfc_io_free(phba);
> -	lpfc_free_iocb_list(phba);
> -	lpfc_sli4_hba_unset(phba);
>  
> +	/* Flush the PHBA WQ - there could be a race with ELS IOs while lpfc
> +	 * is unloading.  This stops a race between completions, aborts and
> +	 * resource recovery.
> +	 */
> +	if (phba->wq)
> +		flush_workqueue(phba->wq);
> +

[Severity: High]
Could flushing the workqueue here lead to a use-after-free later during
unload?

If lpfc_sli4_hba_unset() issues hardware aborts, completions can still
trigger interrupts that queue new work to phba->wq. Later in the same unset
function, lpfc_sli4_queue_destroy() frees the lpfc_queue structures (which
contain the work_structs) without explicitly canceling the enqueued works.

When lpfc_unset_driver_resource_phase2() eventually calls
destroy_workqueue(phba->wq), it drains the queue and executes those newly
enqueued items on the freed lpfc_queue memory.

> +	lpfc_sli4_hba_unset(phba);
>  	lpfc_unset_driver_resource_phase2(phba);
>  	lpfc_sli4_driver_resource_unset(phba);

[ ... ]
> diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
> --- a/drivers/scsi/lpfc/lpfc_nportdisc.c
> +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
[ ... ]
> @@ -271,7 +272,13 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
>  		retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
>  		spin_unlock_irq(&phba->hbalock);
>  
> -		if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) {
> +		/* An abort that fails here is just cancelled when the driver is
> +		 * going offline.  However, if the abort failure is because the
> +		 * IOCB is already getting aborted, don't cancel.  Just let it
> +		 * complete.
> +		 */
> +		if (test_bit(FC_UNLOADING, &phba->pport->load_flag) &&
> +		    retval && retval != IOCB_ABORTING) {
>  			list_del_init(&iocb->list);

[Severity: High]
Does modifying the IOCB list here happen without the required locks?

The target iocb was found by traversing pring->txcmplq, but the lock
(phba->hbalock) was dropped immediately before this block. Calling
list_del_init(&iocb->list) alters the txcmplq list locklessly, which could
race with concurrent completion handlers or other abort routines traversing
the same list, resulting in list corruption.

[Severity: High]
Also, by intentionally bypassing cancellation for IOCB_ABORTING and leaving
the IOCB on txcmplq, is there a risk of leaking these IOCB structures?

Later in the unload path, lpfc_free_iocb_list() only frees items currently
on the free list (phba->lpfc_iocb_list). Any IOCB stranded on txcmplq would
not be returned to the free list and could be permanently leaked.
Additionally, if NVMe is enabled, could this cause functions like
lpfc_nvme_wait_for_io_drain() to loop infinitely while waiting for txcmplq
to be fully empty?

>  			list_add_tail(&iocb->list, &drv_cmpl_list);
>  		}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261013001648.62289-1-nkirkland2304@gmail.com?part=5

  reply	other threads:[~2026-10-13  0:12 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13  0:16 [PATCH v6 0/8] lpfc: Update lpfc to revision 15.0.0.1 Nigel Kirkland
2026-10-13  0:16 ` [PATCH v6 1/8] lpfc: Fix use-after-free in lpfc_cmpl_ct_cmd_vmid Nigel Kirkland
2026-10-13  0:03   ` sashiko-bot
2026-10-13  0:16 ` [PATCH v6 2/8] lpfc: Early return out of lpfc_els_abort when HBA_SETUP flag is not set Nigel Kirkland
2026-10-13  0:05   ` sashiko-bot
2026-10-13  0:16 ` [PATCH v6 3/8] lpfc: Fix kernel oops when unmapping scsi dma buffers for an aborted cmd Nigel Kirkland
2026-10-13  0:07   ` sashiko-bot
2026-10-13  0:16 ` [PATCH v6 4/8] lpfc: Check fc4_xpt_flags before decrementing ndlp kref on FDISC error Nigel Kirkland
2026-10-13  0:16 ` [PATCH v6 5/8] lpfc: Rework I/O flush ordering when unloading driver Nigel Kirkland
2026-10-13  0:12   ` sashiko-bot [this message]
2026-10-13  0:16 ` [PATCH v6 6/8] lpfc: Refactor calls on fc_disctmo to lpfc_set_disctmo in RSCN handler Nigel Kirkland
2026-10-13  0:16 ` [PATCH v6 7/8] lpfc: Update correct ndlp refcnt when rejecting an unsolicited PLOGI Nigel Kirkland
2026-10-13  0:13   ` sashiko-bot
2026-10-13  0:16 ` [PATCH v6 8/8] lpfc: Update lpfc version to 15.0.0.1 Nigel Kirkland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-168784@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=nkirkland2304@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.