mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
Merge patch series "Update lpfc to revision 14.4.0.9"
Justin Tee <justintee8345@gmail.com> says: Update lpfc to revision 14.4.0.9 This patch set contains fixes related to handling of WQE commands, PCI function resets, firmware eratta events, ELS retries, a smatch use-after-free warning, and the creation of a new VMID information entry. The patches were cut against Martin's 6.16/scsi-queue tree. Link: https://lore.kernel.org/r/20250425194806.3585-1-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
commit
00159e436c
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
|
|
@ -291,6 +291,138 @@ lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
lpfc_vmid_info_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct Scsi_Host *shost = class_to_shost(dev);
|
||||
struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_vmid *vmp;
|
||||
int len = 0, i, j, k, cpu;
|
||||
char hxstr[LPFC_MAX_VMID_SIZE * 3] = {0};
|
||||
struct timespec64 curr_tm;
|
||||
struct lpfc_vmid_priority_range *vr;
|
||||
u64 *lta, rct_acc = 0, max_lta = 0;
|
||||
struct tm tm_val;
|
||||
|
||||
ktime_get_ts64(&curr_tm);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "Key 'vmid':\n");
|
||||
|
||||
/* if enabled continue, else return */
|
||||
if (lpfc_is_vmid_enabled(phba)) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"lpfc VMID Page: ON\n\n");
|
||||
} else {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"lpfc VMID Page: OFF\n\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
/* if using priority tagging */
|
||||
if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"VMID priority ranges:\n");
|
||||
vr = vport->vmid_priority.vmid_range;
|
||||
for (i = 0; i < vport->vmid_priority.num_descriptors; ++i) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"\t[x%x - x%x], qos: x%x\n",
|
||||
vr->low, vr->high, vr->qos);
|
||||
vr++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < phba->cfg_max_vmid; i++) {
|
||||
vmp = &vport->vmid[i];
|
||||
max_lta = 0;
|
||||
|
||||
/* only if the slot is used */
|
||||
if (!(vmp->flag & LPFC_VMID_SLOT_USED) ||
|
||||
!(vmp->flag & LPFC_VMID_REGISTERED))
|
||||
continue;
|
||||
|
||||
/* if using priority tagging */
|
||||
if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"VEM ID: %02x:%02x:%02x:%02x:"
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:"
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
vport->lpfc_vmid_host_uuid[0],
|
||||
vport->lpfc_vmid_host_uuid[1],
|
||||
vport->lpfc_vmid_host_uuid[2],
|
||||
vport->lpfc_vmid_host_uuid[3],
|
||||
vport->lpfc_vmid_host_uuid[4],
|
||||
vport->lpfc_vmid_host_uuid[5],
|
||||
vport->lpfc_vmid_host_uuid[6],
|
||||
vport->lpfc_vmid_host_uuid[7],
|
||||
vport->lpfc_vmid_host_uuid[8],
|
||||
vport->lpfc_vmid_host_uuid[9],
|
||||
vport->lpfc_vmid_host_uuid[10],
|
||||
vport->lpfc_vmid_host_uuid[11],
|
||||
vport->lpfc_vmid_host_uuid[12],
|
||||
vport->lpfc_vmid_host_uuid[13],
|
||||
vport->lpfc_vmid_host_uuid[14],
|
||||
vport->lpfc_vmid_host_uuid[15]);
|
||||
}
|
||||
|
||||
/* IO stats */
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"ID00 READs:%llx WRITEs:%llx\n",
|
||||
vmp->io_rd_cnt,
|
||||
vmp->io_wr_cnt);
|
||||
for (j = 0, k = 0; j < strlen(vmp->host_vmid); j++, k += 3)
|
||||
sprintf((char *)(hxstr + k), "%2x ", vmp->host_vmid[j]);
|
||||
/* UUIDs */
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "UUID:\n");
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", hxstr);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "String (%s)\n",
|
||||
vmp->host_vmid);
|
||||
|
||||
if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"CS_CTL VMID: 0x%x\n",
|
||||
vmp->un.cs_ctl_vmid);
|
||||
else
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"Application id: 0x%x\n",
|
||||
vmp->un.app_id);
|
||||
|
||||
/* calculate the last access time */
|
||||
for_each_possible_cpu(cpu) {
|
||||
lta = per_cpu_ptr(vmp->last_io_time, cpu);
|
||||
if (!lta)
|
||||
continue;
|
||||
|
||||
/* if last access time is less than timeout */
|
||||
if (time_after((unsigned long)*lta, jiffies))
|
||||
continue;
|
||||
|
||||
if (*lta > max_lta)
|
||||
max_lta = *lta;
|
||||
}
|
||||
|
||||
rct_acc = jiffies_to_msecs(jiffies - max_lta) / 1000;
|
||||
/* current time */
|
||||
time64_to_tm(ktime_get_real_seconds(),
|
||||
-(sys_tz.tz_minuteswest * 60) - rct_acc, &tm_val);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"Last Access Time :"
|
||||
"%ld-%d-%dT%02d:%02d:%02d\n\n",
|
||||
1900 + tm_val.tm_year, tm_val.tm_mon + 1,
|
||||
tm_val.tm_mday, tm_val.tm_hour,
|
||||
tm_val.tm_min, tm_val.tm_sec);
|
||||
|
||||
if (len >= PAGE_SIZE)
|
||||
return len;
|
||||
|
||||
memset(hxstr, 0, LPFC_MAX_VMID_SIZE * 3);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_drvr_version_show - Return the Emulex driver string with version number
|
||||
* @dev: class unused variable.
|
||||
|
|
@ -3011,6 +3143,7 @@ static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
|
|||
static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
|
||||
NULL);
|
||||
static DEVICE_ATTR(cmf_info, 0444, lpfc_cmf_info_show, NULL);
|
||||
static DEVICE_ATTR_RO(lpfc_vmid_info);
|
||||
|
||||
#define WWN_SZ 8
|
||||
/**
|
||||
|
|
@ -6117,6 +6250,7 @@ static struct attribute *lpfc_hba_attrs[] = {
|
|||
&dev_attr_lpfc_vmid_inactivity_timeout.attr,
|
||||
&dev_attr_lpfc_vmid_app_header.attr,
|
||||
&dev_attr_lpfc_vmid_priority_tagging.attr,
|
||||
&dev_attr_lpfc_vmid_info.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
struct lpfc_hba *phba;
|
||||
struct lpfc_work_evt *evtp;
|
||||
unsigned long iflags;
|
||||
bool nvme_reg = false;
|
||||
bool drop_initial_node_ref = false;
|
||||
|
||||
ndlp = ((struct lpfc_rport_data *)rport->dd_data)->pnode;
|
||||
if (!ndlp)
|
||||
|
|
@ -188,8 +188,13 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
spin_lock_irqsave(&ndlp->lock, iflags);
|
||||
ndlp->rport = NULL;
|
||||
|
||||
if (ndlp->fc4_xpt_flags & NVME_XPT_REGD)
|
||||
nvme_reg = true;
|
||||
/* Only 1 thread can drop the initial node reference.
|
||||
* If not registered for NVME and NLP_DROPPED flag is
|
||||
* clear, remove the initial reference.
|
||||
*/
|
||||
if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
|
||||
if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
drop_initial_node_ref = true;
|
||||
|
||||
/* The scsi_transport is done with the rport so lpfc cannot
|
||||
* call to unregister.
|
||||
|
|
@ -200,13 +205,16 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
/* If NLP_XPT_REGD was cleared in lpfc_nlp_unreg_node,
|
||||
* unregister calls were made to the scsi and nvme
|
||||
* transports and refcnt was already decremented. Clear
|
||||
* the NLP_XPT_REGD flag only if the NVME Rport is
|
||||
* the NLP_XPT_REGD flag only if the NVME nrport is
|
||||
* confirmed unregistered.
|
||||
*/
|
||||
if (!nvme_reg && ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
|
||||
ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
|
||||
if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
|
||||
if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD))
|
||||
ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
|
||||
spin_unlock_irqrestore(&ndlp->lock, iflags);
|
||||
lpfc_nlp_put(ndlp); /* may free ndlp */
|
||||
|
||||
/* Release scsi transport reference */
|
||||
lpfc_nlp_put(ndlp);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&ndlp->lock, iflags);
|
||||
}
|
||||
|
|
@ -214,14 +222,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
|||
spin_unlock_irqrestore(&ndlp->lock, iflags);
|
||||
}
|
||||
|
||||
/* Only 1 thread can drop the initial node reference. If
|
||||
* another thread has set NLP_DROPPED, this thread is done.
|
||||
*/
|
||||
if (nvme_reg || test_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
return;
|
||||
|
||||
set_bit(NLP_DROPPED, &ndlp->nlp_flag);
|
||||
lpfc_nlp_put(ndlp);
|
||||
if (drop_initial_node_ref)
|
||||
lpfc_nlp_put(ndlp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4695,9 +4697,7 @@ lpfc_nlp_unreg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
if (ndlp->fc4_xpt_flags & NVME_XPT_REGD) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
if (vport->phba->nvmet_support == 0) {
|
||||
/* Start devloss if target. */
|
||||
if (ndlp->nlp_type & NLP_NVME_TARGET)
|
||||
lpfc_nvme_unregister_port(vport, ndlp);
|
||||
lpfc_nvme_unregister_port(vport, ndlp);
|
||||
} else {
|
||||
/* NVMET has no upcall. */
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
|
@ -5053,7 +5053,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba,
|
|||
case CMD_GEN_REQUEST64_CR:
|
||||
if (iocb->ndlp == ndlp)
|
||||
return 1;
|
||||
fallthrough;
|
||||
break;
|
||||
case CMD_ELS_REQUEST64_CR:
|
||||
if (remote_id == ndlp->nlp_DID)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -1907,6 +1907,9 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
|
|||
uint32_t intr_mode;
|
||||
LPFC_MBOXQ_t *mboxq;
|
||||
|
||||
/* Notifying the transport that the targets are going offline. */
|
||||
lpfc_scsi_dev_block(phba);
|
||||
|
||||
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >=
|
||||
LPFC_SLI_INTF_IF_TYPE_2) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
|
|
@ -2508,7 +2508,10 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
"6031 RemotePort Registration failed "
|
||||
"err: %d, DID x%06x ref %u\n",
|
||||
ret, ndlp->nlp_DID, kref_read(&ndlp->kref));
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
/* Only release reference if one was taken for this request */
|
||||
if (!oldrport)
|
||||
lpfc_nlp_put(ndlp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -2614,7 +2617,8 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
* clear any rport state until the transport calls back.
|
||||
*/
|
||||
|
||||
if (ndlp->nlp_type & NLP_NVME_TARGET) {
|
||||
if ((ndlp->nlp_type & NLP_NVME_TARGET) ||
|
||||
(remoteport->port_role & FC_PORT_ROLE_NVME_TARGET)) {
|
||||
/* No concern about the role change on the nvme remoteport.
|
||||
* The transport will update it.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
|
|
@ -3926,12 +3926,19 @@ void lpfc_poll_eratt(struct timer_list *t)
|
|||
uint64_t sli_intr, cnt;
|
||||
|
||||
phba = from_timer(phba, t, eratt_poll);
|
||||
if (!test_bit(HBA_SETUP, &phba->hba_flag))
|
||||
return;
|
||||
|
||||
if (test_bit(FC_UNLOADING, &phba->pport->load_flag))
|
||||
return;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||
!test_bit(HBA_SETUP, &phba->hba_flag)) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"0663 HBA still initializing 0x%lx, restart "
|
||||
"timer\n",
|
||||
phba->hba_flag);
|
||||
goto restart_timer;
|
||||
}
|
||||
|
||||
/* Here we will also keep track of interrupts per sec of the hba */
|
||||
sli_intr = phba->sli.slistat.sli_intr;
|
||||
|
||||
|
|
@ -3950,13 +3957,16 @@ void lpfc_poll_eratt(struct timer_list *t)
|
|||
/* Check chip HA register for error event */
|
||||
eratt = lpfc_sli_check_eratt(phba);
|
||||
|
||||
if (eratt)
|
||||
if (eratt) {
|
||||
/* Tell the worker thread there is work to do */
|
||||
lpfc_worker_wake_up(phba);
|
||||
else
|
||||
/* Restart the timer for next eratt poll */
|
||||
mod_timer(&phba->eratt_poll,
|
||||
jiffies + secs_to_jiffies(phba->eratt_poll_interval));
|
||||
return;
|
||||
}
|
||||
|
||||
restart_timer:
|
||||
/* Restart the timer for next eratt poll */
|
||||
mod_timer(&phba->eratt_poll,
|
||||
jiffies + secs_to_jiffies(phba->eratt_poll_interval));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
#define LPFC_DRIVER_VERSION "14.4.0.8"
|
||||
#define LPFC_DRIVER_VERSION "14.4.0.9"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user