scsi: mpt3sas: Register trace buffer based on NVDATA settings

Currently if user wishes to enable the host trace buffer during driver load
time, then user has to load the driver with module parameter
'diag_buffer_enable' set to one.

Alternatively now the user can enable host trace buffer by enabling the
following fields in manufacturing page11 in NVDATA (nvdata xml is used
while building HBA firmware image):

 * HostTraceBufferMaxSizeKB - Maximum trace buffer size in KB that host can
                              allocate,

 * HostTraceBufferMinSizeKB - Minimum trace buffer size in KB atleast host
                              should allocate,

 * HostTraceBufferDecrementSizeKB - size by which host can reduce from
                              buffer size and retry the buffer allocation
                              when buffer allocation failed with previous
                              calculated buffer size.

The driver will register the trace buffer automatically without any module
parameter during boot time when above fields are enabled in manufacturing
page11 in HBA firmware.

Driver follows the following algorithm for enabling the host trace buffer
during driver load time:

* If user has loaded the driver with module parameter 'diag_buffer_enable'
  set to one, then driver allocates 2MB buffer and registers this buffer
  with HBA firmware for capturing the firmware trace logs.

* Else driver reads manufacture page11 data and checks whether
  HostTraceBufferMaxSizeKB filed is zero or not?

  - If HostTraceBufferMaxSizeKB is non-zero then driver tries to allocate
    HostTraceBufferMaxSizeKB size of memory. If the buffer allocation is
    successful, then it will register this buffer with HBA firmware, else
    in a loop the driver will try again by reducing the current buffer size
    with HostTraceBufferDecrementSizeKB size until memory allocation is
    successful or buffer size falls below HostTraceBufferMinSizeKB. If the
    memory allocation is successful, then the buffer will be registered
    with the firmware. Else, if the buffer size falls below the
    HostTraceBufferMinSizeKB, then driver won't register trace buffer with
    HBA firmware.

  - If HostTraceBufferMaxSizeKB is zero, then driver won't register trace
    buffer with HBA firmware.

Link: https://lore.kernel.org/r/1568379890-18347-2-git-send-email-sreekanth.reddy@broadcom.com
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Sreekanth Reddy 2019-09-13 09:04:38 -04:00 committed by Martin K. Petersen
parent 5f9d423a72
commit d04a6edfed
3 changed files with 75 additions and 7 deletions

View File

@ -391,9 +391,12 @@ struct Mpi2ManufacturingPage11_t {
u8 Reserved6; /* 2Fh */
__le32 Reserved7[7]; /* 30h - 4Bh */
u8 NVMeAbortTO; /* 4Ch */
u8 Reserved8; /* 4Dh */
u16 Reserved9; /* 4Eh */
__le32 Reserved10[4]; /* 50h - 60h */
u8 NumPerDevEvents; /* 4Dh */
u8 HostTraceBufferDecrementSizeKB; /* 4Eh */
u8 HostTraceBufferFlags; /* 4Fh */
u16 HostTraceBufferMaxSizeKB; /* 50h */
u16 HostTraceBufferMinSizeKB; /* 52h */
__le32 Reserved10[2]; /* 54h - 5Bh */
};
/**

View File

@ -1669,6 +1669,10 @@ void
mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register)
{
struct mpt3_diag_register diag_register;
u32 ret_val;
u32 trace_buff_size = ioc->manu_pg11.HostTraceBufferMaxSizeKB<<10;
u32 min_trace_buff_size = 0;
u32 decr_trace_buff_size = 0;
memset(&diag_register, 0, sizeof(struct mpt3_diag_register));
@ -1677,10 +1681,61 @@ mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register)
ioc->diag_trigger_master.MasterData =
(MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET);
diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
/* register for 2MB buffers */
diag_register.requested_buffer_size = 2 * (1024 * 1024);
diag_register.unique_id = 0x7075900;
_ctl_diag_register_2(ioc, &diag_register);
if (trace_buff_size != 0) {
diag_register.requested_buffer_size = trace_buff_size;
min_trace_buff_size =
ioc->manu_pg11.HostTraceBufferMinSizeKB<<10;
decr_trace_buff_size =
ioc->manu_pg11.HostTraceBufferDecrementSizeKB<<10;
if (min_trace_buff_size > trace_buff_size) {
/* The buff size is not set correctly */
ioc_err(ioc,
"Min Trace Buff size (%d KB) greater than Max Trace Buff size (%d KB)\n",
min_trace_buff_size>>10,
trace_buff_size>>10);
ioc_err(ioc,
"Using zero Min Trace Buff Size\n");
min_trace_buff_size = 0;
}
if (decr_trace_buff_size == 0) {
/*
* retry the min size if decrement
* is not available.
*/
decr_trace_buff_size =
trace_buff_size - min_trace_buff_size;
}
} else {
/* register for 2MB buffers */
diag_register.requested_buffer_size = 2 * (1024 * 1024);
}
do {
ret_val = _ctl_diag_register_2(ioc, &diag_register);
if (ret_val == -ENOMEM && min_trace_buff_size &&
(trace_buff_size - decr_trace_buff_size) >=
min_trace_buff_size) {
/* adjust the buffer size */
trace_buff_size -= decr_trace_buff_size;
diag_register.requested_buffer_size =
trace_buff_size;
} else
break;
} while (true);
if (ret_val == -ENOMEM)
ioc_err(ioc,
"Cannot allocate trace buffer memory. Last memory tried = %d KB\n",
diag_register.requested_buffer_size>>10);
else if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE]
& MPT3_DIAG_BUFFER_IS_REGISTERED)
ioc_err(ioc, "Trace buffer memory %d KB allocated\n",
diag_register.requested_buffer_size>>10);
}
if (bits_to_register & 2) {
@ -3130,7 +3185,15 @@ host_trace_buffer_enable_store(struct device *cdev,
memset(&diag_register, 0, sizeof(struct mpt3_diag_register));
ioc_info(ioc, "posting host trace buffers\n");
diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
diag_register.requested_buffer_size = (1024 * 1024);
if (ioc->manu_pg11.HostTraceBufferMaxSizeKB != 0 &&
ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0) {
/* post the same buffer allocated previously */
diag_register.requested_buffer_size =
ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE];
} else
diag_register.requested_buffer_size = (1024 * 1024);
diag_register.unique_id = 0x7075900;
ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0;
_ctl_diag_register_2(ioc, &diag_register);

View File

@ -10193,6 +10193,8 @@ scsih_scan_start(struct Scsi_Host *shost)
int rc;
if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
mpt3sas_enable_diag_buffer(ioc, diag_buffer_enable);
else if (ioc->manu_pg11.HostTraceBufferMaxSizeKB != 0)
mpt3sas_enable_diag_buffer(ioc, 1);
if (disable_discovery > 0)
return;