| 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> |