Commit a066f4c3 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

scsi: mpt3sas: Reuse diag buffer allocated at load time

The diag buffer which is allocated during driver load time or through sysfs
parameter is marked as driver allocated diag buffer.
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED bit will be set for this buffer.

This buffer won't be de-allocated even when application issues unregister
command, driver just clears the registered status bit. Same buffer will be
reused while re-registering the same diag buffer type by any application.
While re-registering the same diag buffer type application has to register
with the same size that the buffer was allocated during driver load
time. This buffer size can be read by the application by issuing diag
'query' command.

This always makes sure that the memory is available for applications for
collecting the firmware logs. Only thing is that this won't allow the
application to re-register the diag buffer with different size, but the
buffer size which is allocated during driver load time will be enough for
most of the cases for collecting the firmware logs.

Link: https://lore.kernel.org/r/1568379890-18347-8-git-send-email-sreekanth.reddy@broadcom.comSigned-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dd180e4e
...@@ -303,6 +303,7 @@ struct mpt3sas_nvme_cmd { ...@@ -303,6 +303,7 @@ struct mpt3sas_nvme_cmd {
#define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) #define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01)
#define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) #define MPT3_DIAG_BUFFER_IS_RELEASED (0x02)
#define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04)
#define MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED (0x08)
/* /*
* HP HBA branding * HP HBA branding
......
...@@ -1617,6 +1617,19 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, ...@@ -1617,6 +1617,19 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
__func__, buffer_type); __func__, buffer_type);
return -EINVAL; return -EINVAL;
} }
} else if (ioc->diag_buffer_status[buffer_type] &
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {
if (ioc->unique_id[buffer_type] != MPT3DIAGBUFFUNIQUEID ||
ioc->diag_buffer_sz[buffer_type] !=
diag_register->requested_buffer_size) {
ioc_err(ioc,
"%s: already a buffer is allocated for buffer_type(0x%02x) of size %d bytes, so please try registering again with same size\n",
__func__, buffer_type,
ioc->diag_buffer_sz[buffer_type]);
return -EINVAL;
}
} }
if (diag_register->requested_buffer_size % 4) { if (diag_register->requested_buffer_size % 4) {
...@@ -1641,7 +1654,8 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, ...@@ -1641,7 +1654,8 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
request_data = ioc->diag_buffer[buffer_type]; request_data = ioc->diag_buffer[buffer_type];
request_data_sz = diag_register->requested_buffer_size; request_data_sz = diag_register->requested_buffer_size;
ioc->unique_id[buffer_type] = diag_register->unique_id; ioc->unique_id[buffer_type] = diag_register->unique_id;
ioc->diag_buffer_status[buffer_type] = 0; ioc->diag_buffer_status[buffer_type] &=
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
memcpy(ioc->product_specific[buffer_type], memcpy(ioc->product_specific[buffer_type],
diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS); diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS);
ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags; ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
...@@ -1731,9 +1745,12 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, ...@@ -1731,9 +1745,12 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
out: out:
if (rc && request_data) if (rc && request_data) {
dma_free_coherent(&ioc->pdev->dev, request_data_sz, dma_free_coherent(&ioc->pdev->dev, request_data_sz,
request_data, request_data_dma); request_data, request_data_dma);
ioc->diag_buffer_status[buffer_type] &=
~MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
}
ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; ioc->ctl_cmds.status = MPT3_CMD_NOT_USED;
return rc; return rc;
...@@ -1817,9 +1834,14 @@ mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register) ...@@ -1817,9 +1834,14 @@ mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register)
"Cannot allocate trace buffer memory. Last memory tried = %d KB\n", "Cannot allocate trace buffer memory. Last memory tried = %d KB\n",
diag_register.requested_buffer_size>>10); diag_register.requested_buffer_size>>10);
else if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] else if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE]
& MPT3_DIAG_BUFFER_IS_REGISTERED) & MPT3_DIAG_BUFFER_IS_REGISTERED) {
ioc_err(ioc, "Trace buffer memory %d KB allocated\n", ioc_err(ioc, "Trace buffer memory %d KB allocated\n",
diag_register.requested_buffer_size>>10); diag_register.requested_buffer_size>>10);
if (ioc->hba_mpi_version_belonged != MPI2_VERSION)
ioc->diag_buffer_status[
MPI2_DIAG_BUF_TYPE_TRACE] |=
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
}
} }
if (bits_to_register & 2) { if (bits_to_register & 2) {
...@@ -1930,12 +1952,19 @@ _ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ...@@ -1930,12 +1952,19 @@ _ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
return -ENOMEM; return -ENOMEM;
} }
request_data_sz = ioc->diag_buffer_sz[buffer_type]; if (ioc->diag_buffer_status[buffer_type] &
request_data_dma = ioc->diag_buffer_dma[buffer_type]; MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) {
dma_free_coherent(&ioc->pdev->dev, request_data_sz, ioc->unique_id[buffer_type] = MPT3DIAGBUFFUNIQUEID;
request_data, request_data_dma); ioc->diag_buffer_status[buffer_type] &=
ioc->diag_buffer[buffer_type] = NULL; ~MPT3_DIAG_BUFFER_IS_REGISTERED;
ioc->diag_buffer_status[buffer_type] = 0; } else {
request_data_sz = ioc->diag_buffer_sz[buffer_type];
request_data_dma = ioc->diag_buffer_dma[buffer_type];
dma_free_coherent(&ioc->pdev->dev, request_data_sz,
request_data, request_data_dma);
ioc->diag_buffer[buffer_type] = NULL;
ioc->diag_buffer_status[buffer_type] = 0;
}
return 0; return 0;
} }
...@@ -1974,11 +2003,14 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ...@@ -1974,11 +2003,14 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
return -EPERM; return -EPERM;
} }
if ((ioc->diag_buffer_status[buffer_type] & if (!(ioc->diag_buffer_status[buffer_type] &
MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED)) {
ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n", if ((ioc->diag_buffer_status[buffer_type] &
__func__, buffer_type); MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
return -EINVAL; ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n",
__func__, buffer_type);
return -EINVAL;
}
} }
if (karg.unique_id) { if (karg.unique_id) {
...@@ -1996,13 +2028,17 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ...@@ -1996,13 +2028,17 @@ _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
return -ENOMEM; return -ENOMEM;
} }
if (ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_RELEASED) if ((ioc->diag_buffer_status[buffer_type] &
karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | MPT3_DIAG_BUFFER_IS_REGISTERED))
MPT3_APP_FLAGS_BUFFER_VALID); karg.application_flags |= MPT3_APP_FLAGS_BUFFER_VALID;
else
karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | if (!(ioc->diag_buffer_status[buffer_type] &
MPT3_APP_FLAGS_BUFFER_VALID | MPT3_DIAG_BUFFER_IS_RELEASED))
MPT3_APP_FLAGS_FW_BUFFER_ACCESS); karg.application_flags |= MPT3_APP_FLAGS_FW_BUFFER_ACCESS;
if (!(ioc->diag_buffer_status[buffer_type] &
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED))
karg.application_flags |= MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC;
for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++)
karg.product_specific[i] = karg.product_specific[i] =
...@@ -3303,6 +3339,16 @@ host_trace_buffer_enable_store(struct device *cdev, ...@@ -3303,6 +3339,16 @@ host_trace_buffer_enable_store(struct device *cdev,
(MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID); (MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID);
ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0; ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;
_ctl_diag_register_2(ioc, &diag_register); _ctl_diag_register_2(ioc, &diag_register);
if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] &
MPT3_DIAG_BUFFER_IS_REGISTERED) {
ioc_info(ioc,
"Trace buffer %d KB allocated through sysfs\n",
diag_register.requested_buffer_size>>10);
if (ioc->hba_mpi_version_belonged != MPI2_VERSION)
ioc->diag_buffer_status[
MPI2_DIAG_BUF_TYPE_TRACE] |=
MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
}
} else if (!strcmp(str, "release")) { } else if (!strcmp(str, "release")) {
/* exit out if host buffers are already released */ /* exit out if host buffers are already released */
if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE])
......
...@@ -318,6 +318,7 @@ struct mpt3_ioctl_btdh_mapping { ...@@ -318,6 +318,7 @@ struct mpt3_ioctl_btdh_mapping {
#define MPT3_APP_FLAGS_APP_OWNED (0x0001) #define MPT3_APP_FLAGS_APP_OWNED (0x0001)
#define MPT3_APP_FLAGS_BUFFER_VALID (0x0002) #define MPT3_APP_FLAGS_BUFFER_VALID (0x0002)
#define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) #define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004)
#define MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC (0x0008)
/* flags for mpt3_diag_read_buffer */ /* flags for mpt3_diag_read_buffer */
#define MPT3_FLAGS_REREGISTER (0x0001) #define MPT3_FLAGS_REREGISTER (0x0001)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment