From: Ranjan Kumar <ranjan.kumar@broadcom.com>
To: linux-scsi@vger.kernel.org, martin.petersen@oracle.com
Cc: rajsekhar.chundru@broadcom.com, sathya.prakash@broadcom.com,
sumit.saxena@broadcom.com, chandrakanth.patil@broadcom.com,
prayas.patel@broadcom.com,
Ranjan Kumar <ranjan.kumar@broadcom.com>
Subject: [PATCH v1 3/6] mpi3mr: Dump driver and dmesg logs into driver diag buffer
Date: Tue, 14 May 2024 19:58:55 +0530 [thread overview]
Message-ID: <20240514142858.51992-4-ranjan.kumar@broadcom.com> (raw)
In-Reply-To: <20240514142858.51992-1-ranjan.kumar@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 6845 bytes --]
This patch adds support for collecting the kernel messages based
on the driver buffer capture level set in the module parameter
and copy the pertinent information to the driver diagnostic buffer
posted to the controller. The buffer capture and copy will be
executed when the driver detected the controller in the fault state.
Signed-off-by: Sathya Prakash <sathya.prakash@broadcom.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
drivers/scsi/mpi3mr/mpi/mpi30_tool.h | 2 +
drivers/scsi/mpi3mr/mpi3mr.h | 5 ++
drivers/scsi/mpi3mr/mpi3mr_fw.c | 126 +++++++++++++++++++++++++++
3 files changed, 133 insertions(+)
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_tool.h b/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
index 495933856006..8b8b6ba00c7b 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
@@ -10,6 +10,8 @@
#define MPI3_DIAG_BUFFER_TYPE_DRIVER (0x10)
#define MPI3_DIAG_BUFFER_ACTION_RELEASE (0x01)
+#define MPI3_DRIVER_DIAG_BUFFER_HEADER_FLAGS_CIRCULAR_BUF_FORMAT_ASCII (0x00000000)
+
struct mpi3_diag_buffer_post_request {
__le16 host_tag;
u8 ioc_use_only02;
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index dc7e8f461826..b6030a665ec8 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -226,6 +226,10 @@ extern atomic64_t event_counter;
#define MPI3MR_WRITE_SAME_MAX_LEN_256_BLKS 256
#define MPI3MR_WRITE_SAME_MAX_LEN_2048_BLKS 2048
+struct mpi3mr_kmsg_dumper {
+ struct kmsg_dump_iter kdumper;
+};
+
/* Driver diag buffer levels */
enum mpi3mr_drv_db_level {
MRIOC_DRV_DB_DISABLED = 0,
@@ -1331,6 +1335,7 @@ struct mpi3mr_ioc {
void *drv_diag_buffer;
dma_addr_t drv_diag_buffer_dma;
u32 drv_diag_buffer_sz;
+ struct mpi3mr_kmsg_dumper dump;
};
/**
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 5937054b3cdb..35143d2b7fe4 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1200,6 +1200,128 @@ static void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_ioc *mrioc)
mpi3mr_free_ioctl_dma_memory(mrioc);
}
+/**
+ * mpi3mr_do_mini_dump - copy system logs associated with mrioc.
+ * @mrioc: Adapter instance reference
+ * @prev_offset: offset returned from previous operation
+ *
+ * Read system logs and search for pattern mpi3mr%d and copy the lines
+ * into driver diag buffer
+ *
+ * Return: next available location in driver diag buffer.
+ */
+static int mpi3mr_do_mini_dump(struct mpi3mr_ioc *mrioc)
+{
+ int n = 0, lines, pos_mini_dump = 0;
+ struct mpi3mr_kmsg_dumper dumper;
+ size_t len;
+ char buf[201];
+ char *mini_start = "<6> Minidump start\n";
+ char *mini_end = "<6> Minidump end\n";
+
+ struct mpi3_driver_buffer_header *drv_buff_header = NULL;
+
+ dumper = mrioc->dump;
+
+ kmsg_dump_rewind(&dumper.kdumper);
+ while (kmsg_dump_get_line(&dumper.kdumper, 1, NULL, 0, NULL))
+ n++;
+
+ lines = n;
+ kmsg_dump_rewind(&dumper.kdumper);
+
+ drv_buff_header = (struct mpi3_driver_buffer_header *)mrioc->drv_diag_buffer;
+ drv_buff_header->signature = 0x43495243;
+ drv_buff_header->logical_buffer_start = 0;
+ drv_buff_header->circular_buffer_size =
+ mrioc->drv_diag_buffer_sz - sizeof(struct mpi3_driver_buffer_header);
+ drv_buff_header->flags =
+ MPI3_DRIVER_DIAG_BUFFER_HEADER_FLAGS_CIRCULAR_BUF_FORMAT_ASCII;
+
+ if ((pos_mini_dump + strlen(mini_start)
+ < mrioc->drv_diag_buffer_sz)) {
+ sprintf((char *)mrioc->drv_diag_buffer + pos_mini_dump,
+ "%s\n", mini_start);
+ pos_mini_dump += strlen(mini_start);
+ } else {
+ ioc_info(mrioc, "driver diag buffer is full. minidump is not started\n");
+ goto out;
+ }
+
+ while (kmsg_dump_get_line(&dumper.kdumper, 1, buf, sizeof(buf), &len)) {
+ if (!lines--)
+ break;
+ if (strstr(buf, mrioc->name) &&
+ ((pos_mini_dump + len + strlen(mini_end))
+ < mrioc->drv_diag_buffer_sz)) {
+ sprintf((char *)mrioc->drv_diag_buffer
+ + pos_mini_dump, "%s", buf);
+ pos_mini_dump += len;
+ }
+ }
+
+ if ((pos_mini_dump + strlen(mini_end)
+ < mrioc->drv_diag_buffer_sz)) {
+ sprintf((char *)mrioc->drv_diag_buffer + pos_mini_dump,
+ "%s\n", mini_end);
+ pos_mini_dump += strlen(mini_end);
+ }
+
+out:
+ drv_buff_header->logical_buffer_end =
+ pos_mini_dump - sizeof(struct mpi3_driver_buffer_header);
+
+ ioc_info(mrioc, "driver diag buffer base_address(including 4K header) 0x%016llx, end_address 0x%016llx\n",
+ (unsigned long long)mrioc->drv_diag_buffer_dma,
+ (unsigned long long)mrioc->drv_diag_buffer_dma +
+ mrioc->drv_diag_buffer_sz);
+ ioc_info(mrioc, "logical_buffer end_address 0x%016llx, logical_buffer_end 0x%08x\n",
+ (unsigned long long)mrioc->drv_diag_buffer_dma +
+ drv_buff_header->logical_buffer_end,
+ drv_buff_header->logical_buffer_end);
+
+ return pos_mini_dump;
+}
+
+/**
+ * mpi3mr_do_dump - copy system logs into driver diag buffer.
+ * @mrioc: Adapter instance reference
+ *
+ * Return: Nothing.
+ */
+static void mpi3mr_do_dump(struct mpi3mr_ioc *mrioc)
+{
+ int offset = 0;
+ size_t dump_size;
+ struct mpi3_driver_buffer_header *drv_buff_header = NULL;
+
+ if (!mrioc->drv_diag_buffer)
+ return;
+
+ memset(mrioc->drv_diag_buffer, 0, mrioc->drv_diag_buffer_sz);
+
+ if (drv_db_level == MRIOC_DRV_DB_DISABLED)
+ return;
+
+ /* Copy controller specific logs */
+ offset += mpi3mr_do_mini_dump(mrioc);
+ if (drv_db_level != MRIOC_DRV_DB_FULL)
+ return;
+
+ kmsg_dump_rewind(&mrioc->dump.kdumper);
+ kmsg_dump_get_buffer(&mrioc->dump.kdumper, true,
+ mrioc->drv_diag_buffer + offset,
+ mrioc->drv_diag_buffer_sz - offset, &dump_size);
+
+ drv_buff_header = (struct mpi3_driver_buffer_header *)
+ mrioc->drv_diag_buffer;
+ drv_buff_header->logical_buffer_end += dump_size;
+ ioc_info(mrioc, "logical_buffer end_address(0x%016llx), logical_buffer_end(0x%08x)\n",
+ (unsigned long long)mrioc->drv_diag_buffer_dma +
+ drv_buff_header->logical_buffer_end,
+ drv_buff_header->logical_buffer_end);
+}
+
/**
* mpi3mr_clear_reset_history - clear reset history
* @mrioc: Adapter instance reference
@@ -2767,6 +2889,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
if (!mrioc->diagsave_timeout) {
mpi3mr_print_fault_info(mrioc);
ioc_warn(mrioc, "diag save in progress\n");
+ mpi3mr_do_dump(mrioc);
}
if ((mrioc->diagsave_timeout++) <= MPI3_SYSIF_DIAG_SAVE_TIMEOUT)
goto schedule_work;
@@ -5311,6 +5434,9 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
mpi3mr_ioc_disable_intr(mrioc);
if (snapdump) {
+ dprint_reset(mrioc,
+ "soft_reset_handler: saving snapdump\n");
+ mpi3mr_do_dump(mrioc);
mpi3mr_set_diagsave(mrioc);
retval = mpi3mr_issue_reset(mrioc,
MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
--
2.31.1
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]
next prev parent reply other threads:[~2024-05-14 14:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-14 14:28 [PATCH v1 0/6] mpi3mr: Host diag buffer support Ranjan Kumar
2024-05-14 14:28 ` [PATCH v1 1/6] mpi3mr: HDB allocation and posting for hardware and Firmware buffers Ranjan Kumar
2024-05-15 9:58 ` kernel test robot
2024-05-14 14:28 ` [PATCH v1 2/6] mpi3mr: Driver buffer allocation and posting Ranjan Kumar
2024-05-14 14:28 ` Ranjan Kumar [this message]
2024-05-15 11:00 ` [PATCH v1 3/6] mpi3mr: Dump driver and dmesg logs into driver diag buffer kernel test robot
2024-05-14 14:28 ` [PATCH v1 4/6] mpi3mr: Trigger support Ranjan Kumar
2024-05-15 12:03 ` kernel test robot
2024-05-14 14:28 ` [PATCH v1 5/6] mpi3mr: Ioctl support for HDB Ranjan Kumar
2024-05-14 14:28 ` [PATCH v1 6/6] mpi3mr: Update driver version to 8.9.1.0.50 Ranjan Kumar
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=20240514142858.51992-4-ranjan.kumar@broadcom.com \
--to=ranjan.kumar@broadcom.com \
--cc=chandrakanth.patil@broadcom.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=prayas.patel@broadcom.com \
--cc=rajsekhar.chundru@broadcom.com \
--cc=sathya.prakash@broadcom.com \
--cc=sumit.saxena@broadcom.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox