linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info
       [not found] <CGME20200715074757epcas2p344b4e188af3221655c1697405b9e17f4@epcas2p3.samsung.com>
@ 2020-07-15  7:39 ` Kiwoong Kim
       [not found]   ` <CGME20200715074758epcas2p31bd668e519f59a47268bb086363b1826@epcas2p3.samsung.com>
                     ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Kiwoong Kim @ 2020-07-15  7:39 UTC (permalink / raw)
  To: linux-scsi, alim.akhtar, avri.altman, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee
  Cc: Kiwoong Kim

v5 -> v6
replace put_aligned with get_unaligned_be32 to set lba and sct
fix null pointer access symptom

v4 -> v5
Rebased on Stanley's patch (scsi: ufs: Fix and simplify ..
Change cmd history print order
rename config to SCSI_UFS_EXYNOS_DBG
feature functions in ufs-exynos-dbg.c by SCSI_UFS_EXYNOS_DBG

v3 -> v4
seperate respective implementations of the callbacks
change the location of compl_xfer_req related stuffs
fix null pointer access

v2 -> v3
fix build errors

v1 -> v2
change callbacks
allocate memory for ufs_s_dbg_mgr dynamically, not static way

Kiwoong Kim (3):
  ufs: introduce a callback to get info of command completion
  ufs: exynos: introduce command history
  ufs: exynos: implement dbg_register_dump

 drivers/scsi/ufs/Kconfig          |  14 +++
 drivers/scsi/ufs/Makefile         |   1 +
 drivers/scsi/ufs/ufs-exynos-dbg.c | 198 ++++++++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-exynos-if.h  |  17 ++++
 drivers/scsi/ufs/ufs-exynos.c     |  38 ++++++++
 drivers/scsi/ufs/ufs-exynos.h     |  35 +++++++
 drivers/scsi/ufs/ufshcd.c         |   1 +
 drivers/scsi/ufs/ufshcd.h         |   8 ++
 8 files changed, 312 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-exynos-dbg.c
 create mode 100644 drivers/scsi/ufs/ufs-exynos-if.h

-- 
2.7.4


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v6 1/3] ufs: introduce a callback to get info of command completion
       [not found]   ` <CGME20200715074758epcas2p31bd668e519f59a47268bb086363b1826@epcas2p3.samsung.com>
@ 2020-07-15  7:39     ` Kiwoong Kim
  0 siblings, 0 replies; 9+ messages in thread
From: Kiwoong Kim @ 2020-07-15  7:39 UTC (permalink / raw)
  To: linux-scsi, alim.akhtar, avri.altman, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee
  Cc: Kiwoong Kim

Some SoC specific might need command history for
various reasons, such as stacking command contexts
in system memory to check for debugging in the future
or scaling some DVFS knobs to boost IO throughput.

What you would do with the information could be
variant per SoC vendor.

Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
Acked-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Tested-by: Kiwoong Kim <kwmad.kim@samsung.com>
---
 drivers/scsi/ufs/ufshcd.c | 1 +
 drivers/scsi/ufs/ufshcd.h | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 292af12..092480a 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4884,6 +4884,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
 		lrbp = &hba->lrb[index];
 		lrbp->compl_time_stamp = ktime_get();
 		cmd = lrbp->cmd;
+		ufshcd_vops_compl_xfer_req(hba, index, (cmd) ? true : false);
 		if (cmd) {
 			ufshcd_add_command_trace(hba, index, "complete");
 			result = ufshcd_transfer_rsp_status(hba, lrbp);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c774012..e5353d6 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -294,6 +294,7 @@ struct ufs_hba_variant_ops {
 					struct ufs_pa_layer_attr *,
 					struct ufs_pa_layer_attr *);
 	void	(*setup_xfer_req)(struct ufs_hba *, int, bool);
+	void	(*compl_xfer_req)(struct ufs_hba *hba, int tag, bool is_scsi);
 	void	(*setup_task_mgmt)(struct ufs_hba *, int, u8);
 	void    (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme,
 					enum ufs_notify_change_status);
@@ -1070,6 +1071,13 @@ static inline void ufshcd_vops_setup_xfer_req(struct ufs_hba *hba, int tag,
 		return hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd);
 }
 
+static inline void ufshcd_vops_compl_xfer_req(struct ufs_hba *hba,
+					      int tag, bool is_scsi)
+{
+	if (hba->vops && hba->vops->compl_xfer_req)
+		hba->vops->compl_xfer_req(hba, tag, is_scsi);
+}
+
 static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba,
 					int tag, u8 tm_function)
 {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v6 2/3] ufs: exynos: introduce command history
       [not found]   ` <CGME20200715074758epcas2p117bed09c65271199ac0008a5a1564570@epcas2p1.samsung.com>
@ 2020-07-15  7:39     ` Kiwoong Kim
  2020-07-19  6:01       ` Avri Altman
  0 siblings, 1 reply; 9+ messages in thread
From: Kiwoong Kim @ 2020-07-15  7:39 UTC (permalink / raw)
  To: linux-scsi, alim.akhtar, avri.altman, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee
  Cc: Kiwoong Kim

This includes functions to record contexts of incoming commands
in a circular queue. ufshcd.c has already some function
tracer calls to get command history but ftrace would be
gone when system dies before you get the information,
such as panic cases.

This patch also implements callbacks compl_xfer_req
to store IO contexts at completion times.

When you turn on CONFIG_SCSI_UFS_EXYNOS_CMD_LOG,
the driver collects the information from incoming commands
in the circular queue.

Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
Tested-by: Kiwoong Kim <kwmad.kim@samsung.com>
---
 drivers/scsi/ufs/Kconfig          |  14 +++
 drivers/scsi/ufs/Makefile         |   1 +
 drivers/scsi/ufs/ufs-exynos-dbg.c | 199 ++++++++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-exynos-if.h  |  17 ++++
 drivers/scsi/ufs/ufs-exynos.c     |  27 ++++++
 drivers/scsi/ufs/ufs-exynos.h     |  29 ++++++
 6 files changed, 287 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-exynos-dbg.c
 create mode 100644 drivers/scsi/ufs/ufs-exynos-if.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 8cd9026..c946d8f 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -172,3 +172,17 @@ config SCSI_UFS_EXYNOS
 
 	  Select this if you have UFS host controller on EXYNOS chipset.
 	  If unsure, say N.
+
+config SCSI_UFS_EXYNOS_DBG
+	bool "EXYNOS specific debug functions"
+	default n
+	depends on SCSI_UFS_EXYNOS
+	help
+	  This selects EXYNOS specific functions to get and even print
+	  some information to see what's happening at both command
+	  issue time completion time.
+	  The information may contain gerernal things as well as
+	  EXYNOS specific, such as vendor specific hardware contexts.
+
+	  Select this if you want to get and print the information.
+	  If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index f0c5b95..ee09961 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-d
 obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
 obj-$(CONFIG_SCSI_UFS_EXYNOS) += ufs-exynos.o
+obj-$(CONFIG_SCSI_UFS_EXYNOS_DBG) += ufs-exynos-dbg.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
 ufshcd-core-y				+= ufshcd.o ufs-sysfs.o
 ufshcd-core-$(CONFIG_SCSI_UFS_BSG)	+= ufs_bsg.o
diff --git a/drivers/scsi/ufs/ufs-exynos-dbg.c b/drivers/scsi/ufs/ufs-exynos-dbg.c
new file mode 100644
index 0000000..e1f1452
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-exynos-dbg.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UFS Exynos debugging functions
+ *
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ * Author: Kiwoong Kim <kwmad.kim@samsung.com>
+ *
+ */
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <asm-generic/unaligned.h>
+#include "ufshcd.h"
+#include "ufs-exynos-if.h"
+
+#define MAX_CMD_LOGS    32
+
+struct cmd_data {
+	unsigned int tag;
+	u32 sct;
+	u64 lba;
+	u64 start_time;
+	u64 end_time;
+	u64 outstanding_reqs;
+	int retries;
+	u8 op;
+};
+
+struct ufs_cmd_info {
+	u32 total;
+	u32 last;
+	struct cmd_data data[MAX_CMD_LOGS];
+	struct cmd_data *pdata[MAX_CMD_LOGS];
+};
+
+/*
+ * This structure points out several contexts on debugging
+ * per one host instant.
+ * Now command history exists in here but later handle may
+ * contains some mmio base addresses including vendor specific
+ * regions to get hardware contexts.
+ */
+struct ufs_s_dbg_mgr {
+	struct ufs_exynos_handle *handle;
+	int active;
+	u64 first_time;
+	u64 time;
+
+	/* cmd log */
+	struct ufs_cmd_info cmd_info;
+	struct cmd_data cmd_log;		/* temp buffer to put */
+	spinlock_t cmd_lock;
+};
+
+static void ufs_s_print_cmd_log(struct ufs_s_dbg_mgr *mgr, struct device *dev)
+{
+	struct ufs_cmd_info *cmd_info = &mgr->cmd_info;
+	struct cmd_data *data;
+	u32 i, idx;
+	u32 last;
+	u32 max = MAX_CMD_LOGS;
+	unsigned long flags;
+	u32 total;
+
+	spin_lock_irqsave(&mgr->cmd_lock, flags);
+	total = cmd_info->total;
+	if (cmd_info->total < max)
+		max = cmd_info->total;
+	last = (cmd_info->last + MAX_CMD_LOGS - 1) % MAX_CMD_LOGS;
+	spin_unlock_irqrestore(&mgr->cmd_lock, flags);
+
+	dev_err(dev, ":---------------------------------------------------\n");
+	dev_err(dev, ":\t\tSCSI CMD(%u)\n", total - 1);
+	dev_err(dev, ":---------------------------------------------------\n");
+	dev_err(dev, ":OP, TAG, LBA, SCT, RETRIES, STIME, ETIME, REQS\n\n");
+
+	idx = (last == max - 1) ? 0 : last + 1;
+	for (i = 0 ; i < max ; i++, data = &cmd_info->data[idx]) {
+		dev_err(dev, ": 0x%02x, %02d, 0x%08llx, 0x%04x, %d, %llu, %llu, 0x%llx",
+			data->op, data->tag, data->lba, data->sct, data->retries,
+			data->start_time, data->end_time, data->outstanding_reqs);
+		idx = (idx == max - 1) ? 0 : idx + 1;
+	}
+}
+
+static void ufs_s_put_cmd_log(struct ufs_s_dbg_mgr *mgr,
+			      struct cmd_data *cmd_data)
+{
+	struct ufs_cmd_info *cmd_info = &mgr->cmd_info;
+	unsigned long flags;
+	struct cmd_data *pdata;
+
+	spin_lock_irqsave(&mgr->cmd_lock, flags);
+	pdata = &cmd_info->data[cmd_info->last];
+	++cmd_info->total;
+	++cmd_info->last;
+	cmd_info->last = cmd_info->last % MAX_CMD_LOGS;
+	spin_unlock_irqrestore(&mgr->cmd_lock, flags);
+
+	pdata->op = cmd_data->op;
+	pdata->tag = cmd_data->tag;
+	pdata->lba = cmd_data->lba;
+	pdata->sct = cmd_data->sct;
+	pdata->retries = cmd_data->retries;
+	pdata->start_time = cmd_data->start_time;
+	pdata->end_time = 0;
+	pdata->outstanding_reqs = cmd_data->outstanding_reqs;
+	cmd_info->pdata[cmd_data->tag] = pdata;
+}
+
+/*
+ * EXTERNAL FUNCTIONS
+ *
+ * There are two classes that are to initialize data structures for debug
+ * and to define actual behavior.
+ */
+void exynos_ufs_dump_info(struct ufs_exynos_handle *handle, struct device *dev)
+{
+	struct ufs_s_dbg_mgr *mgr = (struct ufs_s_dbg_mgr *)handle->private;
+
+	if (mgr->active == 0)
+		goto out;
+
+	mgr->time = cpu_clock(raw_smp_processor_id());
+
+#ifdef CONFIG_SCSI_UFS_EXYNOS_CMD_LOG
+	ufs_s_print_cmd_log(mgr, dev);
+#endif
+
+	if (mgr->first_time == 0ULL)
+		mgr->first_time = mgr->time;
+out:
+	return;
+}
+
+void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
+			      struct ufs_hba *hba, int tag)
+{
+	struct ufs_s_dbg_mgr *mgr = (struct ufs_s_dbg_mgr *)handle->private;
+	struct scsi_cmnd *cmd = hba->lrb[tag].cmd;
+	int cpu = raw_smp_processor_id();
+	struct cmd_data *cmd_log = &mgr->cmd_log;	/* temp buffer to put */
+	u64 lba = 0;
+	u32 sct = 0;
+
+	if (mgr->active == 0)
+		return;
+
+	cmd_log->start_time = cpu_clock(cpu);
+	cmd_log->op = cmd->cmnd[0];
+	cmd_log->tag = tag;
+
+	/* This function runtime is protected by spinlock from outside */
+	cmd_log->outstanding_reqs = hba->outstanding_reqs;
+
+	/* Now assume using WRITE_10 and READ_10 */
+	put_unaligned(cpu_to_le32(*(u32 *)cmd->cmnd[2]), &lba);
+	put_unaligned(cpu_to_le16(*(u16 *)cmd->cmnd[7]), &sct);
+	if (cmd->cmnd[0] != UNMAP)
+		cmd_log->lba = lba;
+
+	cmd_log->sct = sct;
+	cmd_log->retries = cmd->allowed;
+
+	ufs_s_put_cmd_log(mgr, cmd_log);
+}
+
+void exynos_ufs_cmd_log_end(struct ufs_exynos_handle *handle,
+			    struct ufs_hba *hba, int tag)
+{
+	struct ufs_s_dbg_mgr *mgr = (struct ufs_s_dbg_mgr *)handle->private;
+	struct ufs_cmd_info *cmd_info = &mgr->cmd_info;
+	int cpu = raw_smp_processor_id();
+
+	if (mgr->active == 0)
+		return;
+
+	cmd_info->pdata[tag]->end_time = cpu_clock(cpu);
+}
+
+int exynos_ufs_init_dbg(struct ufs_exynos_handle *handle, struct device *dev)
+{
+	struct ufs_s_dbg_mgr *mgr;
+
+	mgr = devm_kzalloc(dev, sizeof(struct ufs_s_dbg_mgr), GFP_KERNEL);
+	if (!mgr)
+		return -ENOMEM;
+	handle->private = (void *)mgr;
+	mgr->handle = handle;
+	mgr->active = 1;
+
+	/* cmd log */
+	spin_lock_init(&mgr->cmd_lock);
+
+	return 0;
+}
+MODULE_AUTHOR("Kiwoong Kim <kwmad.kim@samsung.com>");
+MODULE_DESCRIPTION("Exynos UFS debug information");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
diff --git a/drivers/scsi/ufs/ufs-exynos-if.h b/drivers/scsi/ufs/ufs-exynos-if.h
new file mode 100644
index 0000000..c746f59
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-exynos-if.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * UFS Exynos debugging functions
+ *
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ * Author: Kiwoong Kim <kwmad.kim@samsung.com>
+ *
+ */
+#ifndef _UFS_EXYNOS_IF_H_
+#define _UFS_EXYNOS_IF_H_
+
+/* more members would be added in the future */
+struct ufs_exynos_handle {
+	void *private;
+};
+
+#endif /* _UFS_EXYNOS_IF_H_ */
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index 440f2af..53b9d6e 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -700,12 +700,26 @@ static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba,
 	return 0;
 }
 
+static void exynos_ufs_cmd_log(struct ufs_hba *hba, int tag, int start)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	struct ufs_exynos_handle *handle = &ufs->handle;
+
+	if (start == 1)
+		exynos_ufs_cmd_log_start(handle, hba, tag);
+	else if (start == 2)
+		exynos_ufs_cmd_log_end(handle, hba, tag);
+}
+
 static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba,
 						int tag, bool op)
 {
 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
 	u32 type;
 
+	if (op)
+		exynos_ufs_cmd_log(hba, tag, 1);
+
 	type =  hci_readl(ufs, HCI_UTRL_NEXUS_TYPE);
 
 	if (op)
@@ -714,6 +728,12 @@ static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba,
 		hci_writel(ufs, type & ~(1 << tag), HCI_UTRL_NEXUS_TYPE);
 }
 
+static void exynos_ufs_compl_xfer_req(struct ufs_hba *hba, int tag, bool op)
+{
+	if (op)
+		exynos_ufs_cmd_log(hba, tag, 0);
+}
+
 static void exynos_ufs_specify_nexus_t_tm_req(struct ufs_hba *hba,
 						int tag, u8 func)
 {
@@ -1008,6 +1028,12 @@ static int exynos_ufs_init(struct ufs_hba *hba)
 		goto out;
 	exynos_ufs_specify_phy_time_attr(ufs);
 	exynos_ufs_config_smu(ufs);
+
+	/* init dbg */
+	ret = exynos_ufs_init_dbg(&ufs->handle, dev);
+	if (ret)
+		return ret;
+	spin_lock_init(&ufs->dbg_lock);
 	return 0;
 
 phy_off:
@@ -1217,6 +1243,7 @@ static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.link_startup_notify		= exynos_ufs_link_startup_notify,
 	.pwr_change_notify		= exynos_ufs_pwr_change_notify,
 	.setup_xfer_req			= exynos_ufs_specify_nexus_t_xfer_req,
+	.compl_xfer_req			= exynos_ufs_compl_xfer_req,
 	.setup_task_mgmt		= exynos_ufs_specify_nexus_t_tm_req,
 	.hibern8_notify			= exynos_ufs_hibern8_notify,
 	.suspend			= exynos_ufs_suspend,
diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/scsi/ufs/ufs-exynos.h
index 76d6e39..b9cb517 100644
--- a/drivers/scsi/ufs/ufs-exynos.h
+++ b/drivers/scsi/ufs/ufs-exynos.h
@@ -8,6 +8,7 @@
 
 #ifndef _UFS_EXYNOS_H_
 #define _UFS_EXYNOS_H_
+#include "ufs-exynos-if.h"
 
 /*
  * UNIPRO registers
@@ -212,6 +213,10 @@ struct exynos_ufs {
 #define EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL	BIT(2)
 #define EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX	BIT(3)
 #define EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER	BIT(4)
+
+	struct ufs_exynos_handle handle;
+	spinlock_t dbg_lock;
+	int under_dump;
 };
 
 #define for_each_ufs_rx_lane(ufs, i) \
@@ -284,4 +289,28 @@ struct exynos_ufs_uic_attr exynos7_uic_attr = {
 	.rx_hs_g3_prep_sync_len_cap	= PREP_LEN(0xf),
 	.pa_dbg_option_suite		= 0x30103,
 };
+
+/* public function declarations */
+#ifdef CONFIG_SCSI_UFS_EXYNOS_DBG
+void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
+			      struct ufs_hba *hba, int tag);
+void exynos_ufs_cmd_log_end(struct ufs_exynos_handle *handle,
+			    struct ufs_hba *hba, int tag);
+int exynos_ufs_init_dbg(struct ufs_exynos_handle *handle, struct device *dev);
+#else
+void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
+			      struct ufs_hba *hba, int tag)
+{
+}
+
+void exynos_ufs_cmd_log_end(struct ufs_exynos_handle *handle,
+			    struct ufs_hba *hba, int tag)
+{
+}
+
+int exynos_ufs_init_dbg(struct ufs_exynos_handle *handle, struct device *dev)
+{
+	return 0;
+}
+#endif
 #endif /* _UFS_EXYNOS_H_ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v6 3/3] ufs: exynos: implement dbg_register_dump
       [not found]   ` <CGME20200715074759epcas2p2a2046f8fc8548601d644089c141ab7cd@epcas2p2.samsung.com>
@ 2020-07-15  7:39     ` Kiwoong Kim
  2020-07-19  5:37       ` Avri Altman
  0 siblings, 1 reply; 9+ messages in thread
From: Kiwoong Kim @ 2020-07-15  7:39 UTC (permalink / raw)
  To: linux-scsi, alim.akhtar, avri.altman, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee
  Cc: Kiwoong Kim

At present, I just add command history print and
you can add various vendor regions.

I tried this with force error injection to verify
this:

[  421.876751] exynos-ufs 13100000.ufs: :---------------------------------------------------
[  421.876767] exynos-ufs 13100000.ufs: :\x09\x09SCSI CMD(19262)
[  421.876779] exynos-ufs 13100000.ufs: :---------------------------------------------------
[  421.876793] exynos-ufs 13100000.ufs: :OP, TAG, LBA, SCT, RETRIES, STIME, ETIME, REQS\x0a
...
[  421.876979] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1ae, 0x10000, 5, 415979836143, 0, 0x0
[  421.876991] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x00f7ddbc, 0x410000, 5, 416246257103, 0, 0x0
[  421.877004] exynos-ufs 13100000.ufs: : 0x2a, 01, 0x00130e62, 0x80000, 5, 416246296834, 0, 0x1
[  421.877017] exynos-ufs 13100000.ufs: : 0x2a, 02, 0x0085597f, 0x40000, 5, 416246309988, 0, 0x3
[  421.877030] exynos-ufs 13100000.ufs: : 0x2a, 03, 0x00855985, 0x240000, 5, 416246331373, 0, 0x7
...
[  421.877206] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1b9, 0x10000, 5, 417676828598, 0, 0x0
[  421.877217] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1ba, 0x10000, 5, 417677462136, 0, 0x0

Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
Tested-by: Kiwoong Kim <kwmad.kim@samsung.com>
---
 drivers/scsi/ufs/Kconfig          |  2 +-
 drivers/scsi/ufs/ufs-exynos-dbg.c | 11 +++++------
 drivers/scsi/ufs/ufs-exynos.c     | 13 ++++++++++++-
 drivers/scsi/ufs/ufs-exynos.h     | 10 ++++++++--
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index c946d8f..b906ff8 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -181,7 +181,7 @@ config SCSI_UFS_EXYNOS_DBG
 	  This selects EXYNOS specific functions to get and even print
 	  some information to see what's happening at both command
 	  issue time completion time.
-	  The information may contain gerernal things as well as
+	  The information may contain general things as well as
 	  EXYNOS specific, such as vendor specific hardware contexts.
 
 	  Select this if you want to get and print the information.
diff --git a/drivers/scsi/ufs/ufs-exynos-dbg.c b/drivers/scsi/ufs/ufs-exynos-dbg.c
index e1f1452..bd1f4be 100644
--- a/drivers/scsi/ufs/ufs-exynos-dbg.c
+++ b/drivers/scsi/ufs/ufs-exynos-dbg.c
@@ -74,6 +74,7 @@ static void ufs_s_print_cmd_log(struct ufs_s_dbg_mgr *mgr, struct device *dev)
 	dev_err(dev, ":OP, TAG, LBA, SCT, RETRIES, STIME, ETIME, REQS\n\n");
 
 	idx = (last == max - 1) ? 0 : last + 1;
+	data = &cmd_info->data[idx];
 	for (i = 0 ; i < max ; i++, data = &cmd_info->data[idx]) {
 		dev_err(dev, ": 0x%02x, %02d, 0x%08llx, 0x%04x, %d, %llu, %llu, 0x%llx",
 			data->op, data->tag, data->lba, data->sct, data->retries,
@@ -122,9 +123,7 @@ void exynos_ufs_dump_info(struct ufs_exynos_handle *handle, struct device *dev)
 
 	mgr->time = cpu_clock(raw_smp_processor_id());
 
-#ifdef CONFIG_SCSI_UFS_EXYNOS_CMD_LOG
 	ufs_s_print_cmd_log(mgr, dev);
-#endif
 
 	if (mgr->first_time == 0ULL)
 		mgr->first_time = mgr->time;
@@ -139,8 +138,8 @@ void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
 	struct scsi_cmnd *cmd = hba->lrb[tag].cmd;
 	int cpu = raw_smp_processor_id();
 	struct cmd_data *cmd_log = &mgr->cmd_log;	/* temp buffer to put */
-	u64 lba = 0;
-	u32 sct = 0;
+	u64 lba;
+	u32 sct;
 
 	if (mgr->active == 0)
 		return;
@@ -153,8 +152,8 @@ void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
 	cmd_log->outstanding_reqs = hba->outstanding_reqs;
 
 	/* Now assume using WRITE_10 and READ_10 */
-	put_unaligned(cpu_to_le32(*(u32 *)cmd->cmnd[2]), &lba);
-	put_unaligned(cpu_to_le16(*(u16 *)cmd->cmnd[7]), &sct);
+	lba = get_unaligned_be32(&cmd->cmnd[2]);
+	sct = get_unaligned_be32(&cmd->cmnd[7]);
 	if (cmd->cmnd[0] != UNMAP)
 		cmd_log->lba = lba;
 
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index 53b9d6e..be2e74f 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -1033,7 +1033,6 @@ static int exynos_ufs_init(struct ufs_hba *hba)
 	ret = exynos_ufs_init_dbg(&ufs->handle, dev);
 	if (ret)
 		return ret;
-	spin_lock_init(&ufs->dbg_lock);
 	return 0;
 
 phy_off:
@@ -1236,6 +1235,17 @@ static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 	return 0;
 }
 
+static void exynos_ufs_dbg_register_dump(struct ufs_hba *hba)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	if (!test_and_set_bit(EXYNOS_UFS_DBG_DUMP_CXT, &ufs->dbg_flag)) {
+		exynos_ufs_dump_info(&ufs->handle, hba->dev);
+		clear_bit(EXYNOS_UFS_DBG_DUMP_CXT, &ufs->dbg_flag);
+	}
+	return;
+}
+
 static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.name				= "exynos_ufs",
 	.init				= exynos_ufs_init,
@@ -1248,6 +1258,7 @@ static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.hibern8_notify			= exynos_ufs_hibern8_notify,
 	.suspend			= exynos_ufs_suspend,
 	.resume				= exynos_ufs_resume,
+	.dbg_register_dump		= exynos_ufs_dbg_register_dump,
 };
 
 static int exynos_ufs_probe(struct platform_device *pdev)
diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/scsi/ufs/ufs-exynos.h
index b9cb517..cd752eb 100644
--- a/drivers/scsi/ufs/ufs-exynos.h
+++ b/drivers/scsi/ufs/ufs-exynos.h
@@ -215,8 +215,8 @@ struct exynos_ufs {
 #define EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER	BIT(4)
 
 	struct ufs_exynos_handle handle;
-	spinlock_t dbg_lock;
-	int under_dump;
+	unsigned long dbg_flag;
+#define EXYNOS_UFS_DBG_DUMP_CXT			BIT(0)
 };
 
 #define for_each_ufs_rx_lane(ufs, i) \
@@ -297,6 +297,7 @@ void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
 void exynos_ufs_cmd_log_end(struct ufs_exynos_handle *handle,
 			    struct ufs_hba *hba, int tag);
 int exynos_ufs_init_dbg(struct ufs_exynos_handle *handle, struct device *dev);
+void exynos_ufs_dump_info(struct ufs_exynos_handle *handle, struct device *dev);
 #else
 void exynos_ufs_cmd_log_start(struct ufs_exynos_handle *handle,
 			      struct ufs_hba *hba, int tag)
@@ -312,5 +313,10 @@ int exynos_ufs_init_dbg(struct ufs_exynos_handle *handle, struct device *dev)
 {
 	return 0;
 }
+
+void exynos_ufs_dump_info(struct ufs_exynos_handle *handle, struct device *dev)
+{
+	return;
+}
 #endif
 #endif /* _UFS_EXYNOS_H_ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* RE: [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info
  2020-07-15  7:39 ` [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info Kiwoong Kim
                     ` (2 preceding siblings ...)
       [not found]   ` <CGME20200715074759epcas2p2a2046f8fc8548601d644089c141ab7cd@epcas2p2.samsung.com>
@ 2020-07-15 18:25   ` Alim Akhtar
  2020-07-21  3:42   ` Martin K. Petersen
  4 siblings, 0 replies; 9+ messages in thread
From: Alim Akhtar @ 2020-07-15 18:25 UTC (permalink / raw)
  To: 'Kiwoong Kim',
	linux-scsi, avri.altman, jejb, martin.petersen, beanhuo,
	asutoshd, cang, bvanassche, grant.jung, sc.suh, hy50.seo,
	sh425.lee

Hi Kiwoong,

> -----Original Message-----
> From: Kiwoong Kim <kwmad.kim@samsung.com>
> Sent: 15 July 2020 13:10
> To: linux-scsi@vger.kernel.org; alim.akhtar@samsung.com;
> avri.altman@wdc.com; jejb@linux.ibm.com; martin.petersen@oracle.com;
> beanhuo@micron.com; asutoshd@codeaurora.org; cang@codeaurora.org;
> bvanassche@acm.org; grant.jung@samsung.com; sc.suh@samsung.com;
> hy50.seo@samsung.com; sh425.lee@samsung.com
> Cc: Kiwoong Kim <kwmad.kim@samsung.com>
> Subject: [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info
> 
> v5 -> v6
> replace put_aligned with get_unaligned_be32 to set lba and sct fix null pointer
> access symptom
> 
> v4 -> v5
> Rebased on Stanley's patch (scsi: ufs: Fix and simplify ..
> Change cmd history print order
> rename config to SCSI_UFS_EXYNOS_DBG
> feature functions in ufs-exynos-dbg.c by SCSI_UFS_EXYNOS_DBG
> 
> v3 -> v4
> seperate respective implementations of the callbacks change the location of
> compl_xfer_req related stuffs fix null pointer access
> 
> v2 -> v3
> fix build errors
> 
> v1 -> v2
> change callbacks
> allocate memory for ufs_s_dbg_mgr dynamically, not static way
> 
> Kiwoong Kim (3):
>   ufs: introduce a callback to get info of command completion
>   ufs: exynos: introduce command history
>   ufs: exynos: implement dbg_register_dump
> 
>  drivers/scsi/ufs/Kconfig          |  14 +++
>  drivers/scsi/ufs/Makefile         |   1 +
>  drivers/scsi/ufs/ufs-exynos-dbg.c | 198
> ++++++++++++++++++++++++++++++++++++++
>  drivers/scsi/ufs/ufs-exynos-if.h  |  17 ++++
>  drivers/scsi/ufs/ufs-exynos.c     |  38 ++++++++
>  drivers/scsi/ufs/ufs-exynos.h     |  35 +++++++
>  drivers/scsi/ufs/ufshcd.c         |   1 +
>  drivers/scsi/ufs/ufshcd.h         |   8 ++
>  8 files changed, 312 insertions(+)
>  create mode 100644 drivers/scsi/ufs/ufs-exynos-dbg.c  create mode 100644
> drivers/scsi/ufs/ufs-exynos-if.h
> 
This series looks good to me.
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
Thanks,
> --
> 2.7.4



^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v6 3/3] ufs: exynos: implement dbg_register_dump
  2020-07-15  7:39     ` [PATCH v6 3/3] ufs: exynos: implement dbg_register_dump Kiwoong Kim
@ 2020-07-19  5:37       ` Avri Altman
  0 siblings, 0 replies; 9+ messages in thread
From: Avri Altman @ 2020-07-19  5:37 UTC (permalink / raw)
  To: Kiwoong Kim, linux-scsi, alim.akhtar, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee



> 
> At present, I just add command history print and
> you can add various vendor regions.
> 
> I tried this with force error injection to verify
> this:
> 
> [  421.876751] exynos-ufs 13100000.ufs: :---------------------------------------------------
> [  421.876767] exynos-ufs 13100000.ufs: :\x09\x09SCSI CMD(19262)
> [  421.876779] exynos-ufs 13100000.ufs: :---------------------------------------------------
> [  421.876793] exynos-ufs 13100000.ufs: :OP, TAG, LBA, SCT, RETRIES, STIME,
> ETIME, REQS\x0a
> ...
> [  421.876979] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1ae, 0x10000, 5,
> 415979836143, 0, 0x0
> [  421.876991] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x00f7ddbc, 0x410000, 5,
> 416246257103, 0, 0x0
> [  421.877004] exynos-ufs 13100000.ufs: : 0x2a, 01, 0x00130e62, 0x80000, 5,
> 416246296834, 0, 0x1
> [  421.877017] exynos-ufs 13100000.ufs: : 0x2a, 02, 0x0085597f, 0x40000, 5,
> 416246309988, 0, 0x3
> [  421.877030] exynos-ufs 13100000.ufs: : 0x2a, 03, 0x00855985, 0x240000, 5,
> 416246331373, 0, 0x7
> ...
> [  421.877206] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1b9, 0x10000, 5,
> 417676828598, 0, 0x0
> [  421.877217] exynos-ufs 13100000.ufs: : 0x2a, 00, 0x0012f1ba, 0x10000, 5,
> 417677462136, 0, 0x0
> 
> Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
> Tested-by: Kiwoong Kim <kwmad.kim@samsung.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v6 2/3] ufs: exynos: introduce command history
  2020-07-15  7:39     ` [PATCH v6 2/3] ufs: exynos: introduce command history Kiwoong Kim
@ 2020-07-19  6:01       ` Avri Altman
  0 siblings, 0 replies; 9+ messages in thread
From: Avri Altman @ 2020-07-19  6:01 UTC (permalink / raw)
  To: Kiwoong Kim, linux-scsi, alim.akhtar, jejb, martin.petersen,
	beanhuo, asutoshd, cang, bvanassche, grant.jung, sc.suh,
	hy50.seo, sh425.lee

 
> 
> This includes functions to record contexts of incoming commands
> in a circular queue. ufshcd.c has already some function
> tracer calls to get command history but ftrace would be
> gone when system dies before you get the information,
> such as panic cases.
> 
> This patch also implements callbacks compl_xfer_req
> to store IO contexts at completion times.
> 
> When you turn on CONFIG_SCSI_UFS_EXYNOS_CMD_LOG,
> the driver collects the information from incoming commands
> in the circular queue.
> 
> Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
> Tested-by: Kiwoong Kim <kwmad.kim@samsung.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info
  2020-07-15  7:39 ` [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info Kiwoong Kim
                     ` (3 preceding siblings ...)
  2020-07-15 18:25   ` [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info Alim Akhtar
@ 2020-07-21  3:42   ` Martin K. Petersen
  2020-08-08 11:16     ` Greg KH
  4 siblings, 1 reply; 9+ messages in thread
From: Martin K. Petersen @ 2020-07-21  3:42 UTC (permalink / raw)
  To: hy50.seo, asutoshd, bvanassche, alim.akhtar, grant.jung,
	linux-scsi, sc.suh, beanhuo, jejb, sh425.lee, avri.altman,
	Kiwoong Kim, cang
  Cc: Martin K . Petersen

On Wed, 15 Jul 2020 16:39:54 +0900, Kiwoong Kim wrote:

> v5 -> v6
> replace put_aligned with get_unaligned_be32 to set lba and sct
> fix null pointer access symptom
> 
> v4 -> v5
> Rebased on Stanley's patch (scsi: ufs: Fix and simplify ..
> Change cmd history print order
> rename config to SCSI_UFS_EXYNOS_DBG
> feature functions in ufs-exynos-dbg.c by SCSI_UFS_EXYNOS_DBG
> 
> [...]

Applied to 5.9/scsi-queue, thanks!

[1/3] scsi: ufs: Introduce callback to capture command completion information
      https://git.kernel.org/mkp/scsi/c/679d4ca6c93f
[2/3] scsi: ufs: exynos: Introduce command history
      https://git.kernel.org/mkp/scsi/c/c3b5e96ef515
[3/3] scsi: ufs: exynos: Implement dbg_register_dump
      https://git.kernel.org/mkp/scsi/c/957ee40d413b

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info
  2020-07-21  3:42   ` Martin K. Petersen
@ 2020-08-08 11:16     ` Greg KH
  0 siblings, 0 replies; 9+ messages in thread
From: Greg KH @ 2020-08-08 11:16 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: hy50.seo, asutoshd, bvanassche, alim.akhtar, grant.jung,
	linux-scsi, sc.suh, beanhuo, jejb, sh425.lee, avri.altman,
	Kiwoong Kim, cang

On Mon, Jul 20, 2020 at 11:42:07PM -0400, Martin K. Petersen wrote:
> On Wed, 15 Jul 2020 16:39:54 +0900, Kiwoong Kim wrote:
> 
> > v5 -> v6
> > replace put_aligned with get_unaligned_be32 to set lba and sct
> > fix null pointer access symptom
> > 
> > v4 -> v5
> > Rebased on Stanley's patch (scsi: ufs: Fix and simplify ..
> > Change cmd history print order
> > rename config to SCSI_UFS_EXYNOS_DBG
> > feature functions in ufs-exynos-dbg.c by SCSI_UFS_EXYNOS_DBG
> > 
> > [...]
> 
> Applied to 5.9/scsi-queue, thanks!
> 
> [1/3] scsi: ufs: Introduce callback to capture command completion information
>       https://git.kernel.org/mkp/scsi/c/679d4ca6c93f
> [2/3] scsi: ufs: exynos: Introduce command history
>       https://git.kernel.org/mkp/scsi/c/c3b5e96ef515
> [3/3] scsi: ufs: exynos: Implement dbg_register_dump
>       https://git.kernel.org/mkp/scsi/c/957ee40d413b

These links no longer work, did the patches get dropped from your tree
or rebased or something else?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-08-08 11:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20200715074757epcas2p344b4e188af3221655c1697405b9e17f4@epcas2p3.samsung.com>
2020-07-15  7:39 ` [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info Kiwoong Kim
     [not found]   ` <CGME20200715074758epcas2p31bd668e519f59a47268bb086363b1826@epcas2p3.samsung.com>
2020-07-15  7:39     ` [PATCH v6 1/3] ufs: introduce a callback to get info of command completion Kiwoong Kim
     [not found]   ` <CGME20200715074758epcas2p117bed09c65271199ac0008a5a1564570@epcas2p1.samsung.com>
2020-07-15  7:39     ` [PATCH v6 2/3] ufs: exynos: introduce command history Kiwoong Kim
2020-07-19  6:01       ` Avri Altman
     [not found]   ` <CGME20200715074759epcas2p2a2046f8fc8548601d644089c141ab7cd@epcas2p2.samsung.com>
2020-07-15  7:39     ` [PATCH v6 3/3] ufs: exynos: implement dbg_register_dump Kiwoong Kim
2020-07-19  5:37       ` Avri Altman
2020-07-15 18:25   ` [PATCH v6 0/3] ufs: exynos: introduce the way to get cmd info Alim Akhtar
2020-07-21  3:42   ` Martin K. Petersen
2020-08-08 11:16     ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).