blob: 54675b0555c0fe16825c6272ecbf277267d392b2 [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eric Biggers <ebiggers@google.com>
Date: Sat, 22 Aug 2020 10:47:33 -0700
Subject: NOUPSTREAM: ANDROID: scsi: SCSI related vendor hooks
Add a 'fill_prdt' Android vendor hook so that UFS platform drivers can
initialize variant-specific PRDT fields.
This is needed for FMP support.
[CPNOTE: 03/06/21] Lee: Vendor related code - maintain forever
Squash:
NOUPSTREAM: ANDROID: scsi: ufs: add a hook to prepare command
NOUPSTREAM: ANDROID: scsi: ufs: add a hook to add sysfs entries
NOUPSTREAM: ANDROID: scsi: ufs: add hooks to monitor stats of UFS traffic
NOUPSTREAM: ANDROID: scsi: ufs: add hooks to track ufs commands
Bug: 166139333
Bug: 162257402
Bug: 181359082
Bug: 158050260
Bug: 172874931
Bug: 172305874
Bug: 176940922
Change-Id: Icd07b5e475555ef3eaa0ae9e18a1ae9a4b981679
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
drivers/android/vendor_hooks.c | 9 ++++++
drivers/scsi/ufs/ufs-sysfs.c | 14 ++++++---
drivers/scsi/ufs/ufs-sysfs.h | 2 +-
drivers/scsi/ufs/ufshcd.c | 27 +++++++++++++++--
include/trace/hooks/ufshcd.h | 54 ++++++++++++++++++++++++++++++++++
5 files changed, 99 insertions(+), 7 deletions(-)
create mode 100644 include/trace/hooks/ufshcd.h
diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c
--- a/drivers/android/vendor_hooks.c
+++ b/drivers/android/vendor_hooks.c
@@ -26,6 +26,7 @@
#include <trace/hooks/mm.h>
#include <trace/hooks/preemptirq.h>
#include <trace/hooks/ftrace_dump.h>
+#include <trace/hooks/ufshcd.h>
#include <trace/hooks/cgroup.h>
#include <trace/hooks/sys.h>
#include <trace/hooks/iommu.h>
@@ -126,8 +127,16 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_oops_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_size_check);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_format_check);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_dump_buffer);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_fill_prdt);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_prepare_command);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_update_sysfs);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_command);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_compl_command);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_set_task);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_syscall_prctl_finished);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_uic_command);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_tm_command);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_check_int_errors);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_attach);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_setup_dma_ops);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ptype_head);
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -9,6 +9,8 @@
#include "ufs.h"
#include "ufs-sysfs.h"
+#include <trace/hooks/ufshcd.h>
+
static const char *ufshcd_uic_link_state_to_string(
enum uic_link_state state)
{
@@ -1250,15 +1252,19 @@ const struct attribute_group ufs_sysfs_lun_attributes_group = {
.attrs = ufs_sysfs_lun_attributes,
};
-void ufs_sysfs_add_nodes(struct device *dev)
+void ufs_sysfs_add_nodes(struct ufs_hba *hba)
{
int ret;
- ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups);
- if (ret)
- dev_err(dev,
+ ret = sysfs_create_groups(&hba->dev->kobj, ufs_sysfs_groups);
+ if (ret) {
+ dev_err(hba->dev,
"%s: sysfs groups creation failed (err = %d)\n",
__func__, ret);
+ return;
+ }
+
+ trace_android_vh_ufs_update_sysfs(hba);
}
void ufs_sysfs_remove_nodes(struct device *dev)
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h
--- a/drivers/scsi/ufs/ufs-sysfs.h
+++ b/drivers/scsi/ufs/ufs-sysfs.h
@@ -9,7 +9,7 @@
#include "ufshcd.h"
-void ufs_sysfs_add_nodes(struct device *dev);
+void ufs_sysfs_add_nodes(struct ufs_hba *hba);
void ufs_sysfs_remove_nodes(struct device *dev);
extern const struct attribute_group ufs_sysfs_unit_descriptor_group;
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -31,6 +31,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ufs.h>
+#undef CREATE_TRACE_POINTS
+#include <trace/hooks/ufshcd.h>
+
#define UFSHCD_ENABLE_INTRS (UTP_TRANSFER_REQ_COMPL |\
UTP_TASK_REQ_COMPL |\
UFSHCD_ERROR_MASK)
@@ -328,6 +331,8 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
{
struct utp_task_req_desc *descp = &hba->utmrdl_base_addr[tag];
+ trace_android_vh_ufs_send_tm_command(hba, tag, (int)str_t);
+
if (!trace_ufshcd_upiu_enabled())
return;
@@ -349,6 +354,8 @@ static void ufshcd_add_uic_command_trace(struct ufs_hba *hba,
{
u32 cmd;
+ trace_android_vh_ufs_send_uic_command(hba, ucmd, (int)str_t);
+
if (!trace_ufshcd_uic_command_enabled())
return;
@@ -2099,6 +2106,7 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
lrbp->issue_time_stamp = ktime_get();
lrbp->compl_time_stamp = ktime_set(0, 0);
+ trace_android_vh_ufs_send_command(hba, lrbp);
ufshcd_add_command_trace(hba, task_tag, UFS_CMD_SEND);
ufshcd_clk_scaling_start_busy(hba);
if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
@@ -2363,6 +2371,7 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
struct scsi_cmnd *cmd;
int sg_segments;
int i;
+ int err;
cmd = lrbp->cmd;
sg_segments = scsi_dma_map(cmd);
@@ -2401,7 +2410,9 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
lrbp->utr_descriptor_ptr->prd_table_length = 0;
}
- return 0;
+ err = 0;
+ trace_android_vh_ufs_fill_prdt(hba, lrbp, sg_segments, &err);
+ return err;
}
/**
@@ -2766,6 +2777,14 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
ufshcd_prepare_lrbp_crypto(scsi_cmd_to_rq(cmd), lrbp);
+ trace_android_vh_ufs_prepare_command(hba, scsi_cmd_to_rq(cmd), lrbp,
+ &err);
+ if (err) {
+ lrbp->cmd = NULL;
+ ufshcd_release(hba);
+ goto out;
+ }
+
lrbp->req_abort_skip = false;
ufshpb_prep(hba, lrbp);
@@ -5276,6 +5295,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
lrbp->compl_time_stamp = ktime_get();
cmd = lrbp->cmd;
if (cmd) {
+ trace_android_vh_ufs_compl_command(hba, lrbp);
if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
ufshcd_update_monitor(hba, lrbp);
ufshcd_add_command_trace(hba, index, UFS_CMD_COMP);
@@ -5292,6 +5312,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
if (hba->dev_cmd.complete) {
+ trace_android_vh_ufs_compl_command(hba, lrbp);
ufshcd_add_command_trace(hba, index,
UFS_DEV_COMP);
complete(hba->dev_cmd.complete);
@@ -6406,6 +6427,8 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
queue_eh_work = true;
}
+ trace_android_vh_ufs_check_int_errors(hba, queue_eh_work);
+
if (queue_eh_work) {
/*
* update the transfer error masks to sticky bits, let's do this
@@ -9674,7 +9697,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
ufshcd_set_ufs_dev_active(hba);
async_schedule(ufshcd_async_scan, hba);
- ufs_sysfs_add_nodes(hba->dev);
+ ufs_sysfs_add_nodes(hba);
device_enable_async_suspend(dev);
return 0;
diff --git a/include/trace/hooks/ufshcd.h b/include/trace/hooks/ufshcd.h
new file mode 100644
--- /dev/null
+++ b/include/trace/hooks/ufshcd.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ufshcd
+#define TRACE_INCLUDE_PATH trace/hooks
+#if !defined(_TRACE_HOOK_UFSHCD_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_HOOK_UFSHCD_H
+#include <linux/tracepoint.h>
+#include <trace/hooks/vendor_hooks.h>
+/*
+ * Following tracepoints are not exported in tracefs and provide a
+ * mechanism for vendor modules to hook and extend functionality
+ */
+struct ufs_hba;
+struct request;
+struct ufshcd_lrb;
+
+DECLARE_HOOK(android_vh_ufs_fill_prdt,
+ TP_PROTO(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
+ unsigned int segments, int *err),
+ TP_ARGS(hba, lrbp, segments, err));
+
+DECLARE_HOOK(android_vh_ufs_prepare_command,
+ TP_PROTO(struct ufs_hba *hba, struct request *rq,
+ struct ufshcd_lrb *lrbp, int *err),
+ TP_ARGS(hba, rq, lrbp, err));
+
+DECLARE_HOOK(android_vh_ufs_update_sysfs,
+ TP_PROTO(struct ufs_hba *hba),
+ TP_ARGS(hba));
+
+DECLARE_HOOK(android_vh_ufs_send_command,
+ TP_PROTO(struct ufs_hba *hba, struct ufshcd_lrb *lrbp),
+ TP_ARGS(hba, lrbp));
+
+DECLARE_HOOK(android_vh_ufs_compl_command,
+ TP_PROTO(struct ufs_hba *hba, struct ufshcd_lrb *lrbp),
+ TP_ARGS(hba, lrbp));
+
+struct uic_command;
+DECLARE_HOOK(android_vh_ufs_send_uic_command,
+ TP_PROTO(struct ufs_hba *hba, struct uic_command *ucmd, int str_t),
+ TP_ARGS(hba, ucmd, str_t));
+
+DECLARE_HOOK(android_vh_ufs_send_tm_command,
+ TP_PROTO(struct ufs_hba *hba, int tag, int str_t),
+ TP_ARGS(hba, tag, str_t));
+
+DECLARE_HOOK(android_vh_ufs_check_int_errors,
+ TP_PROTO(struct ufs_hba *hba, bool queue_eh_work),
+ TP_ARGS(hba, queue_eh_work));
+
+#endif /* _TRACE_HOOK_UFSHCD_H */
+/* This part must be outside protection */
+#include <trace/define_trace.h>