Lee Duncan (1): scsi: fnic: Move fnic_fnic_flush_tx() to a work queue
Martin Wilck (1): scsi: fnic: Move flush_work initialization out of if block
drivers/scsi/fnic/fnic.h | 3 ++- drivers/scsi/fnic/fnic_fcs.c | 5 +++-- drivers/scsi/fnic/fnic_main.c | 1 + drivers/scsi/fnic/fnic_scsi.c | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-)
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/12450 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/T...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/12450 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/T...
From: Lee Duncan lduncan@suse.com
mainline inclusion from mainline-v6.8-rc5 commit 379a58caa19930e010b7efa1c1f3b9411d3d2ca3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9HL6L CVE: CVE-2024-26917
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Rather than call 'fnic_flush_tx()' from interrupt context we should be moving it onto a work queue to avoid any locking issues.
Fixes: 1a1975551943 ("scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock") Co-developed-by: Hannes Reinecke hare@suse.de Signed-off-by: Hannes Reinecke hare@suse.de Signed-off-by: Lee Duncan lduncan@suse.com Link: https://lore.kernel.org/r/ce5ffa5d0ff82c2b2e283b3b4bff23291d49b05c.170750078... Signed-off-by: Martin K. Petersen martin.petersen@oracle.com
Conflict: drivers/scsi/fnic/fnic.h Commit 554a14826020 ("scsi: fnic: Refactor and redefine fnic.h for multiqueue") in mainline add copy_wq_base in fnic. Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- drivers/scsi/fnic/fnic.h | 3 ++- drivers/scsi/fnic/fnic_fcs.c | 5 +++-- drivers/scsi/fnic/fnic_main.c | 1 + drivers/scsi/fnic/fnic_scsi.c | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 477513dc23b7..cd39822778f7 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -281,6 +281,7 @@ struct fnic {
struct work_struct link_work; struct work_struct frame_work; + struct work_struct flush_work; struct sk_buff_head frame_queue; struct sk_buff_head tx_queue;
@@ -336,7 +337,7 @@ void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); -void fnic_flush_tx(struct fnic *); +void fnic_flush_tx(struct work_struct *work); void fnic_eth_send(struct fcoe_ctlr *, struct sk_buff *skb); void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *); void fnic_update_mac(struct fc_lport *, u8 *new); diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index e3384afb7cbd..90e81c8c63b1 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -1184,7 +1184,7 @@ int fnic_send(struct fc_lport *lp, struct fc_frame *fp)
/** * fnic_flush_tx() - send queued frames. - * @fnic: fnic device + * @work: pointer to work element * * Send frames that were waiting to go out in FC or Ethernet mode. * Whenever changing modes we purge queued frames, so these frames should @@ -1192,8 +1192,9 @@ int fnic_send(struct fc_lport *lp, struct fc_frame *fp) * * Called without fnic_lock held. */ -void fnic_flush_tx(struct fnic *fnic) +void fnic_flush_tx(struct work_struct *work) { + struct fnic *fnic = container_of(work, struct fnic, flush_work); struct sk_buff *skb; struct fc_frame *fp;
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 4f7befb43d60..16c2cdacd0a6 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -776,6 +776,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&fnic->vlans_lock); INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); INIT_WORK(&fnic->event_work, fnic_handle_event); + INIT_WORK(&fnic->flush_work, fnic_flush_tx); skb_queue_head_init(&fnic->fip_frame_queue); INIT_LIST_HEAD(&fnic->evlist); INIT_LIST_HEAD(&fnic->vlans); diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index d1f7b84bbfe8..2b714a4bdb6a 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -695,7 +695,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
- fnic_flush_tx(fnic); + queue_work(fnic_event_queue, &fnic->flush_work);
reset_cmpl_handler_end: fnic_clear_state_flags(fnic, FNIC_FLAGS_FWRESET); @@ -751,7 +751,7 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic, } spin_unlock_irqrestore(&fnic->fnic_lock, flags);
- fnic_flush_tx(fnic); + queue_work(fnic_event_queue, &fnic->flush_work); queue_work(fnic_event_queue, &fnic->frame_work); } else { spin_unlock_irqrestore(&fnic->fnic_lock, flags);
From: Martin Wilck martin.wilck@suse.com
mainline inclusion from mainline-v6.12-rc3 commit f30e5f77d2f205ac14d09dec40fd4bb76712f13d category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRJ6 CVE: CVE-2024-50025
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
After commit 379a58caa199 ("scsi: fnic: Move fnic_fnic_flush_tx() to a work queue"), it can happen that a work item is sent to an uninitialized work queue. This may has the effect that the item being queued is never actually queued, and any further actions depending on it will not proceed.
The following warning is observed while the fnic driver is loaded:
kernel: WARNING: CPU: 11 PID: 0 at ../kernel/workqueue.c:1524 __queue_work+0x373/0x410 kernel: <IRQ> kernel: queue_work_on+0x3a/0x50 kernel: fnic_wq_copy_cmpl_handler+0x54a/0x730 [fnic 62fbff0c42e7fb825c60a55cde2fb91facb2ed24] kernel: fnic_isr_msix_wq_copy+0x2d/0x60 [fnic 62fbff0c42e7fb825c60a55cde2fb91facb2ed24] kernel: __handle_irq_event_percpu+0x36/0x1a0 kernel: handle_irq_event_percpu+0x30/0x70 kernel: handle_irq_event+0x34/0x60 kernel: handle_edge_irq+0x7e/0x1a0 kernel: __common_interrupt+0x3b/0xb0 kernel: common_interrupt+0x58/0xa0 kernel: </IRQ>
It has been observed that this may break the rediscovery of Fibre Channel devices after a temporary fabric failure.
This patch fixes it by moving the work queue initialization out of an if block in fnic_probe().
Signed-off-by: Martin Wilck mwilck@suse.com Fixes: 379a58caa199 ("scsi: fnic: Move fnic_fnic_flush_tx() to a work queue") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240930133014.71615-1-mwilck@suse.com Reviewed-by: Lee Duncan lduncan@suse.com Reviewed-by: Karan Tilak Kumar kartilak@cisco.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- drivers/scsi/fnic/fnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 16c2cdacd0a6..580ee456eab3 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -776,7 +776,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&fnic->vlans_lock); INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); INIT_WORK(&fnic->event_work, fnic_handle_event); - INIT_WORK(&fnic->flush_work, fnic_flush_tx); skb_queue_head_init(&fnic->fip_frame_queue); INIT_LIST_HEAD(&fnic->evlist); INIT_LIST_HEAD(&fnic->vlans); @@ -877,6 +876,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
INIT_WORK(&fnic->link_work, fnic_handle_link); INIT_WORK(&fnic->frame_work, fnic_handle_frame); + INIT_WORK(&fnic->flush_work, fnic_flush_tx); skb_queue_head_init(&fnic->frame_queue); skb_queue_head_init(&fnic->tx_queue);